Why are errors nillable in Go? [closed] - go

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
An error in Go can be nil. The following compiles:
var err error
err = nil
err = errors.New("hello")
Yet errors are values, and value types are not nullable in Go.
Looking at error, it is an ordinary interface:
type error interface {
Error() string
}
implemented by this struct:
type errorString struct {
s string
}
No pointers here. There is a method that takes a pointer receiver,
func (e *errorString) Error() string {
return e.s
}
Yet that doesn't explain why error behaves as a pointer rather than a value.
errors.New() does return a pointer,
func New(text string) error {
return &errorString{text}
}
which makes my third code line above more puzzling -- we are assigning the result of New to a value variable.
How does this work?

I think you may be conflating some concepts. Yes, "errors are values", in that they are not exceptions that can be thrown, but rather they are just regular values returned from a function like any other return value. The Go quality "errors are values" has nothing to do with value vs reference semantics.
The built-in type error is an interface, and all interface values are nilable, so error is nilable.

Related

can you use a primitive or inbuild data types as a method in golang [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
i wanna know if we are able to use inbuild data types as a method for a func in golang, cause whenever I use it as such, it shows an error
You can define methods on built-in types by first wrapping them with your own types, like this:
type MyInteger int
func (my MyInteger) Tell() {
fmt.Println("I'm MyInteger with value", my)
}
func main() {
var my MyInteger = 42
my.Tell()
}
You can try this on the Go Playground, it will print:
I'm MyInteger with value 42
This can be useful if you want to make a built-in type implement an interface. For example, here's how MyInteger would implement the fmt.Stringer interface:
type MyInteger int
func (my MyInteger) String() string {
return "MyInteger " + strconv.Itoa(int(my))
}
func main() {
var my MyInteger = 42
fmt.Println(my)
}

How to idiomatically check that an interface is one of two types in Go [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Assume that I have a function that accepts a very broad interface, which could wrap(?) or describe many different types such as int64, float64, string, as well as other interfaces. However, this particular function only wants to interact with floats and ints, and will return an error for any other underlying concrete type.
What is an idiomatic way to do this in Go?
Should I use a switch statement and do nothing in the cases where it is int or float64 and return an error in the default case? This seems strange to me because those cases would just be empty.
e.g.
type BoardInterface interface{
doThing()
}
type customInt int
type customFloat float64
func (i customInt) doThing() {}
func (f customFloat) doThing() {}
// Other methods for different types here...
func getThing(i BoardInterface) error {
// i could be string, int, float, customInterface1, customInterface2...
// but we want to assert that it is int or float.
switch t := i.(type) {
case customInt:
// Do nothing here?
case customFloat:
// Do nothing here?
default:
return fmt.Errorf("Got %v want float or int", t)
}
// Do something with i here now that we know
// it is a float or int.
i.doThing()
return nil
}
Ideally your BoardInterface should incorporate all the behavior you want to use i for, and that way you can just "interact" with i via the methods listed in BoardInterface. That way it should not matter what concrete type is wrapped in i. If the compiler allowed to pass a value, you have guarantee it implements BoardInterface.
If for some reason that is not feasible (or not possible), your proposed solution is fine. You may simplify it by listing all allowed types in a simple case, and no need to declare t, you may use i just as well like this:
switch i.(type) {
case customInt, customFloat:
default:
return fmt.Errorf("Got %T want customInt or customFloat", i)
}
(Note I used %T in the error message, as that is more informative in this case.)

Provide potentional nil variable to function in GOLANG [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I want to call a function with a int variable that can have a value or can be nil. In the main function i'm doing this call.
doDomething(10) // does not work?
doDomething(nil) // works
func doSomething(parent_id *int) {
fmt.Print(parent_id)
}
I'm getting the following error:
cannot use a (type int) as type *int in argument to doSomething
I use the *int pointer, therefore the nil works but not if it is a value. Then I'm getting the type mismatch.
doSomething expects a *intparameter. 10 is of type int, so this is he source of the error.
This is a valid usage:
i := 10
doDomething(&i)
This is how doSomething should look like:
func doSomething(parent_id *int) {
if parent_id == nil{
//nil
fmt.Println("nil")
return
}
//valid int
fmt.Printf("%d", *parent_id)
}

Multiple receivers on a single method [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Is it possible to have multiple receivers on a single function? In other words, a single function can belong to two or more structs?
Say I have
type Struct1 struct {
foo.Client
}
func CreateClient() struct1 {
return struct1{
ClientID: cId,
// ...
}
}
func (s *Struct1) MyFunc( // ... ) {}
But I also want to be able to associate MyFunc with another struct (different package):
type Struct2 struct {
lgr log.logger
}
func NewStruct2 (l *log.logger) (*Struct2, err) {
return &Struct2{mylog: *l}, nil
}
So what I want to actually have is:
func (s1 *Struct1, s2 *Struct2) MyFunc( // ... ) {}
"Is it possible to have multiple receivers on a single function?" -- It is not possible.
https://golang.org/ref/spec#Method_declarations
The receiver is specified via an extra parameter section preceding the
method name. That parameter section must declare a single non-variadic
parameter, the receiver.

How to parse slice inside json in golang? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I am trying to unmarshal json data. The slice inside is deliberately without quotes, because this is what I am getting from https (added manually \ before ")
data:="{\"queryEndTime\" : \"2017-11-15T14:39:00Z\", \"message\" : [{\"spamScore\":67,\"phishScore\":0}]}"
into Message struct:
type Message struct {
QueryEndTime string `json:"queryEndTime"`
Message []string `json:"message"`
}
but I am getting correct QueryEndTime and empty Message. I tried to change Message type but it always stays empty
var message Message
json.Unmarshal([]byte(data), &message)
fmt.Printf("QueryEndTime: %s\nMessage: %s\n", message.QueryEndTime, message.Message)
QueryEndTime: 2017-11-15T14:39:00Z
Message: []
See it in go playground https://play.golang.org/p/on0_cSKb0c.
package main
import (
"encoding/json"
"fmt"
)
type Message struct {
QueryEndTime string `json:"queryEndTime"`
// you need to use a struct can use anon struct
Message []struct {
SpamScore int `json:"spamScore"`
PhishScore int `json:"phishScore"`
} `json:"message"`
}
func main() {
var message Message
// You can use backticks to for your example JSON, so that you don't have to escape anything.
data := `{
"queryEndTime" : "2017-11-15T14:39:00Z",
"message" : [
{"spamScore":67, "phishScore":0}
]
}`
// please check for errors
err := json.Unmarshal([]byte(data), &message)
if err != nil {
fmt.Println(err)
}
// +v prints structs very nicely
fmt.Printf("%+v\n", message)
}
https://play.golang.org/p/Mu3WZCej3L
Have fun!

Resources