This question already has answers here:
What exactly does .(data_type) method called/do?
(2 answers)
Is this casting in golang?
(1 answer)
Closed 2 years ago.
I am studying a sample Go application that stores data in mongodb. The code at this line (https://github.com/zeebo/gostbook/blob/master/context.go#L36) seems to access a user ID stored in a gorilla session:
if uid, ok := sess.Values["user"].(bson.ObjectId); ok {
...
}
Would someone please explain to me the syntax here? I understand that sess.Values["user"] gets a value from the session, but what is the part that follows? Why is the expression after the dot in parentheses? Is this a function invocation?
sess.Values["user"] is an interface{}, and what is between parenthesis is called a type assertion. It checks that the value of sess.Values["user"] is of type bson.ObjectId. If it is, then ok will be true. Otherwise, it will be false.
For instance:
var i interface{}
i = int(42)
a, ok := i.(int)
// a == 42 and ok == true
b, ok := i.(string)
// b == "" (default value) and ok == false
Related
This question already has answers here:
Hiding nil values, understanding why Go fails here
(3 answers)
Closed 2 years ago.
My code is simply:
func Test_DecodeLBPolicy(t *testing.T) {
policy := decodeLBPolicy("lb:RING_HASH")
require.Equal(t, api.RING_HASH, policy.Type)
require.Equal(t, nil, decodeLBPolicy(""))
}
problem occurs at last line, the output is as below:
Error: Not equal:
expected: <nil>(<nil>)
actual : *api.LBPolicy(nil)
then I tried to replace expected "nil" to "*api.LBPolicy(nil)" it wont compile
but when I change the require to require.Equal(t, true, decodeLBPolicy("") == nil) it passed.
In go, an interface of value nil isn't equal to nil. This is because it has type information associated to it, whereas the nil keyword has no such type. (It also has type nil).
This explains theses lines
expected: <nil>(<nil>)
actual : *api.LBPolicy(nil)
You have a parameter of type *api.LBPolicy and of value nil. But you wanted a type niland value nil.
How to fix is a bit tricky, you could make sure that decodeLBPolicy really return nil and not a interface of value nil. Or compare to a interface of the good type and with the value nil. Or use the == trick as you showed
More details in this post: https://glucn.medium.com/golang-an-interface-holding-a-nil-value-is-not-nil-bb151f472cc7
This question already has answers here:
Is this casting in golang?
(1 answer)
What is the meaning of "dot parenthesis" syntax? [duplicate]
(1 answer)
Closed 4 years ago.
I recently started looking for functional go examples and I found this function:
mapper := func (i interface{}) interface{} {
return strings.ToUpper(i.(string))
}
Map(mapper, New(“milu”, “rantanplan”))
//[“MILU”, “RANTANPLAN”]
Now in this function, as you can see the return value of mapper is:
strings.ToUpper(i.(string)).
But, what does this i.(string) syntax mean? I tried searching, but didn't find anything particularly useful.
i.(string) casts (or attempts at least) i (type interface{}) to type string. I say attempts because say i is an int instead, this will panic. If that doesn't sound great to you, then you could change the syntax to
x, ok := i.(string)
In this case if i is not a string, then ok will be false and the code won't panic.
i.(string) means converting i(interface{} type) to string type.
This question already has answers here:
What is this "err.(*exec.ExitError)" thing in Go code? [duplicate]
(2 answers)
Closed 7 years ago.
I am reading this code and I don't quite understand what line #2 does:
resp := route.Handler(req)
_, nilresponse := resp.(NilResponse)
if !nilresponse {
type NilResponse struct {
}
Thank you
This isn't an empty function name. This is a type-assertion. It is testing that resp is a NilResponse. If it is, then nilResponse will be true, otherwise it will be false. This code throws away the resulting type-asserted value by using _.
See Type Assertions.
If line two is _, nilresponse := resp.(NilResponse) then it's not a function call at all. It's a type assertion. The code is saying "the interface value represented by resp is of type NilResponse.
EDIT; your assignment is kind of odd though because the first return value would be the NilResponse object and the second (if specified) is a flag to indicate whether or not it worked (or maybe an error, can't remember if it's a bool or error). So typically it would be something like; nilResponse, ok := or nilResponse, err :=
This question already has answers here:
How to check if a map contains a key in Go?
(11 answers)
Closed 7 years ago.
The following code yields true. So I'm wondering for map[string]string in Golang, is there a way to differentiate empty string and nothing?
package main
import "fmt"
func main() {
m := make(map[string]string)
m["abc"] = ""
fmt.Println(m["a"] == m["abc"]) //true
}
If by "nothing" you mean that the element is not in the map you can use the ok idiom:
val, ok := myMap["value"] // ok is true if value was in the map
You can find more information in Effective Go.
This question already has answers here:
What exactly does .(data_type) method called/do?
(2 answers)
What is the meaning of "dot parenthesis" syntax? [duplicate]
(1 answer)
What is err.(*os.PathError) in Go?
(2 answers)
Explain Type Assertions in Go
(3 answers)
Closed 10 months ago.
For instance, in this answer:
https://stackoverflow.com/a/10385867/20654
...
if exiterr, ok := err.(*exec.ExitError); ok {
...
What is that err.(*exec.ExitError) called? How does it work?
It's type assertion. I can't explain it better than the spec.
It's a type assertion. That if statement is checking if err is also a *exec.ExitError. The ok let's you know whether it was or wasn't. Finally, exiterr is err, but "converted" to *exec.ExitError. This only works with interface types.
You can also omit the ok if you're 100000 percent sure of the underlying type. But, if you omit ok and it turns out you were wrong, then you'll get a panic.
// find out at runtime if this is true by checking second value
exitErr, isExitError := err.(*exec.ExitError)
// will panic if err is not *exec.ExitError
exitErr := err.(*exec.ExitError)
The ok isn't part of the syntax, by the way. It's just a boolean and you can name it whatever you want.