Nil slice vs empty slice and nil value comparison - go

I have read some text regarding nil slice vs empty slice. I believe I have some basic understanding of the differences between them.
Summary of my understanding: var instance []Type is nil slice and instance == nil returns true; while instance:=[]Type{} is empty slice and instance != nil
However this particular instance still puzzles me.
Please look at the link below for code. My question is the last 2 cases.
https://play.golang.org/p/udyHoOlSeP
Suppose I want to compare two slices, renamed type and interface matching and all. The instance where a receiver can be nil, even though it's not defined as copy by value; while the argument is copied by value, seems to
be non-nil as long as the argument is not untyped.
In the last 2 cases, receiver has been identified as nil while argument is being processed by := so it becomes an empty slice. (But the other == nil also reports false...) How can I fix this to satisfy the following requirement?
nilslice.Equals(nilslice) // -> true
Further, I tried to define another interface comparing to pointers of interface but failed. Compiler complains that
cannot use p (type *AnotherNullable) as type *PointerComparable in argument to AnotherNullable(nil).Equals:
*PointerComparable is pointer to interface, not interface
https://play.golang.org/p/wYO1GKcBds
How can I fix that?
EDIT: Thanks to #zippoxer for all the insights. I learned a lot. I hope new readers too, please don't forget to check out #zippoxer's comment in the answer too!

First, you don't need a pointer to an interface. An interface is already a pointer.
See Go: What's the meaning of interface{}?
Just change the Equals method to accept a PointerComparable instead of a *PointerComparable. Equals will accept an interface instead of a pointer to an interface, but you can still pass a pointer to a slice/whatever to it.
See https://play.golang.org/p/e_Gtq2oAFA
Second, the receiver Nullable isn't an interface, while the argument you pass to Equals is an interface. That would explain why the Nullable receiver stays nil and the Comparable argument isn't nil although it's underlying slice is. The thing is, the Comparable argument is an interface that points to something, so whatever it points to, it won't be nil.
This code explains the problem:
var a interface{}
fmt.Println(a == nil) // true, the interface doesn't point to anything
var someNilSlice []int
fmt.Println(someNilSlice == nil) // true, just some nil slice
a = someNilSlice
fmt.Println(a == nil) // false, now the interface does point to something

Related

Get inteface's dynamic value when there is a pointer to integer as dinamic type

I'm struggling trying to figure out how to "extract" an integer value from a interface that holds a value whose dynamic type is pointer to integer.
You may follow this ready-to-run example in order to fully get the picture of what is problem and my intention.
TD;DR:
For some reason the reflection on a first call to reflect.ValueOf(value) over an interface whose dynamic type is pointer to integer, it returns a value whose Kind() results in reflect.Ptr, when i extract again the "inner" value using reflect.ValueOf(value).Elem() i get another value whose Kind() results in reflect.Struct. I don't even code any struct, but they appears by their own "magically". So golang may not panic but i don't understand what is happening, probably i lack of some information. I would be very thankful with anyone that explaint me what is going on.
This may work for this case, but it doesn't enlight me. I would expect to have an integer value "behind" the pointer. I don't need to access for modification, i only need to get it.
It's struct because when you call ToCompliantValue inside the function, you're not passing it the value itself, you're passing a reflect.Value value, and reflect.Value is a struct. You have to handle it directly instead of trying to use recursion:
v := reflect.ValueOf(value)
fmt.Printf("Value is %+v\n", v)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch v.Kind() {
// ...
Working example: https://play.golang.org/p/ndRjXJfj5xV

What's happening behind the scenes of Go's `nil` type?

I recently read on a popular programming forum that Go supports a handful of "typelesss" values — notably, nil, Go's null value/bottom type. I have fairly limited experience with Go, and one of the statements made on this forum caught me off guard — namely, that it's illegal to write x := nil in Go.
Sure enough, a toy Go program with that line doesn't compile and the compiler error clearly points out that the comment from the forum checks out: declaration and assignment of a variable to nil is disallowed. This seems like a bit of an odd limitation, but things get stranger.
It's a common idiom in Go to return partial errors by returning a tuple from a function. Something like this:
func might_error() (int, error) {
return 1, nil
}
func main() int {
x, err := might_error()
if err != nil {
panic("err was not nil!")
}
return x
}
This has at least two inconsistencies as far as I can tell:
First, even though nil is typeless on paper, it takes on the error type (by way of it implementing the Error interface combined with Go's duck typing) for the purposes of conforming to might_error's return type signature.
Second, it seems like nil is being used for that previously-illegal declaraiton-and-assignment in main, and in a situation where (at least in comparable languages) might_error could be treated as a constexpr.
Weirder still, replacing x, err := might_error() with x, err := 1, nil still errors out with use of untyped nil!
My current line of thinking is that the Error interface is injected into a specific instance of nil in cases where a function's type signature requires it, meaning that it stops being an untyped nil and becomes a typed nil for the lifetime of that specific nil instance, but I'm not at all sure that this is correct since it seems like a strange design choice by nature of it not being clearly generalizeable.
What motivated these design choices? Why have nil be untyped instead of having it be a proper null type, except when it's convenient, at which point it becomes a typed value implementing an Error interface (to the best of my understanding)?
This is a complete non-problem in the sense that in practice there can be confusion if a nil value is stored in an interface variable making that variable non-nil. This is https://golang.org/doc/faq#nil_error and everyone is bitten a few times by this problem until you learn that interface values containing a nil variable are no longer nil themself. It's a bit like with var s = []*int{nil, nil, nil} where s contains only nils but is non-nil itself.
Technically (from a language design point) you could introduce several "nils", e.g. nil for pointers, null for interfaces, noop for functions and vac for channels. (Exaggerating a bit). With this you could have:
type T whatever
func (t *T) Error() string // make *T implement error
var err error // interface variable of type error
print(err == null) // true, null is Zero-Value of interface types
print(err == nil) // COMPILER ERROR, cannot compare interface to nil (which is for pointers only
var t *T = nil // a nil pointer to T
err = t // store nil *T in err
print(err == null) // false err is no longer null, contains t
You could even remove the compiler error:
err = t // store nil *T in err
print(err == null) // false, err contains t
print(err == nil) // "deep" comparison yielding true
err = &T{} // store non-nil *T in err
print(err == null) // still false
print(err == nil) // false, value inside err is no longer nil
You also could define a default type for nil, e.g. *[]chan*func()string so that you can write x := nil like you can do with f := 3.141 where the default type of the untyped constant 3.141 is float64. But such a default type for nil would be arbitrary and not helpful at all (as my example shows; *[]chan*func()string is uncommon).
If I remember correctly there was a longer discussion about this topic on the golang-nuts mailng list where the rationals about this design was discussed. It boiled down to something like: "The actual real-life problems with having nil multiple meanings and not being a constant are tiny (basically just variants of an error type containing nil not being nil). The 'solution' to this one tiny problem would complicate the language (e.g. by introducing a null literal for the zero value of interface types) considerably. It probably is simpler to teach people that interface values containing a nil are no longer nil themself than introducing typed nils or nulls for interface types."
In more than 10 years of programming in Go I literally never had to think about a nil literal being typed or untyped or constant or whatever. The article you probably are referring to is constructing pure academic, but actually non-problem in practice issue out of a tiny design decision about having just one nil literal for all zero values for pointer, slice, map, channel and function types.
Addendum
First, even though nil is typeless on paper, it takes on the error type (by way of it implementing the Error interface combined with Go's duck typing) for the purposes of conforming to might_error's return type signature.
This is a completely wrong description of what happens.
If you write
func f() (r int) { return 7 }
then 7 is assigned to r of type int and f returns. This works because 7 can be assigned to int.
In
func might_error() (int, error) { return 1, nil }
the same happens, the second return variable of type error (an interface type) is set to nil because nil can be assigned to any interface type like you can assign nil to any pointer type or any function type.
This has nothing to do with "implementing the Error interface combined with Go's duck typing". Absolutely not. nil doesn't implement the error interface at all. Any interface value can be nil like can be any function value or slice value or channel value. Setting a chan to nil basically "clears" the channel variable, it doesn't mean that nil somehow "implements the channel interface". You seem to conflate the zero value of several types and how to set them by assigning nil with implementing interfaces. All this has basically nothing to do with nil being typed or not. The nil literal in source code os overloaded and often can be thought of as just representing the zero value of a type.
Your example doesn't compile (because main needs to return nothing), and when you go into picky and nitty areas of a language, all your examples should actually work. 😀
My current line of thinking is that the Error interface is injected into a specific instance of nil in cases where a function's type signature requires it ...
That's not quite right. The Go specification tells us how this works:
There are three ways to return values from a function with a result type:
The return value or values may be explicitly listed in the "return" statement. Each expression must be single-valued and assignable to the corresponding element of the function's result type. [example snipped]
This is the method you use in your example program (which I cleaned up a bit to compile and run in the Go Playground). The expression:
return 1, nil
means:
unnamed_return_variable_1 = 1
unnamed_return_variable_2 = nil
where the two unnamed return variables don't actually have these names (they're un-named, after all) but do have types, courtesy of the declaration of the function. So
return 1, nil
is not at all like:
x, err := 1, nil
but rather more like:
var x int; var err error; x, err = 1, nil
which, as you can see, is also quite valid.
What motivated these design choices?
For that, you'd have to ask the designers.
ThinkGoodly mentions in a comment that:
The untyped 0 does not cause this angst.
The untyped constant 0 has a default type, though:
An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required, for instance, in a short variable declaration such as i := 0 where there is no explicit type. The default type of an untyped constant is bool, rune, int, float64, complex128 or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant.
The predeclared identifier nil has no type, not even a default type. It just has a series of special rules that allow it to be used in various places.
The non-language-canon way to think about this
While this isn't how it's defined (it's defined by the Go specification), this is how I recommend thinking about the issue:
The predeclared identifier1 nil is untyped.
There are typed nil values. Anything sufficiently pointer-like can be nil, or can be non-nil. For instance, any *int variable can be pointer-to-int-nil, as an uninitialized one is. This nil is not the nil "keyword" (predeclared identifier, see footnote); it's a completely different "nil", just like Bruce (Banner) is a completely different person from Bruce (Wayne).
Interface values are two part: a type, and a value of that type. The type can be nil! This is yet another kind of nil, different from nil (the untyped "keyword") and nil (some particular nil of some particular pointer-y type). If the type is nil, the value can also be nil. If both are nil, the interface value compares equal to the <nil,nil> pair that the untyped "keyword" nil turns into when needed for comparison against an interface value. If either one is non-nil, the comparison says these are not equal. The hardware implementation is that the two parts of the interface are both zero: if either part is nonzero, the thing as a whole is nonzero, and hence "not nil".
The conversion from nil-the-"keyword" (predeclared identifier) to an appropriate hardware style zero value occurs when there's enough information supplied by context. Assignment to some variable—even an unnamed one—supplies context. Assignment to some positional argument supplies context. Trying to use a short declaration fails to supply context, hence the error.
1Go in general favors predeclared identifiers to keywords, so that false and true and so on are not actually keywords. This keeps nil out of the keyword set as well. Nonetheless, some things—such as the boolean constants false and true, or the magical behavior of the predeclared identifier iota, are only accessible by not covering up the predeclared identifier and then using it. That is, if you name something iota, you can't get the iota style functionality until that name goes out of scope. The way these things behave is often handled via keywords in other languages. If you tend to think in, say, C++ or Java, you might want to keep reminding yourself that these aren't keywords, even though they smell like them.

What is the difference between reflect.ValueOf() and Value.Elem() in go?

I started learning golang a couple of days ago and found reflect.Valueof() and Value.Elem() quite confusing. What is the difference between this two function/methods and how to use them correctly?
Both function/methods return a Value, and according to the go doc
ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value.
Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil.
I found this code from a post on stackoverflow but still don't understand when to use .Elem()
func SetField(obj interface{}, name string, value interface{}) error {
// won't work if I remove .Elem()
structValue := reflect.ValueOf(obj).Elem()
structFieldValue := structValue.FieldByName(name)
if !structFieldValue.IsValid() {
return fmt.Errorf("No such field: %s in obj", name)
}
if !structFieldValue.CanSet() {
return fmt.Errorf("Cannot set %s field value", name)
}
structFieldType := structFieldValue.Type()
// won't work either if I add .Elem() to the end
val := reflect.ValueOf(value)
if structFieldType != val.Type() {
return fmt.Errorf("Provided value %v type %v didn't match obj field type %v",val,val.Type(),structFieldType)
}
structFieldValue.Set(val)
return nil
}
reflect.ValueOf() is a function, think of it as the entry point to reflection. When you have a "non-reflection" value, such as a string or int, you can use reflect.ValueOf() to get a reflect.Value descriptor of it.
Value.Elem() is a method of reflect.Value. So you can only use this if you already have a reflect.Value. You may use Value.Elem() to get the value (reflect.Value) pointed by the value wrapped by the original reflect.Value. Note that you may also use reflect.Indirect() for this. There's another "use case" for Value.Elem(), but it's more "advanced", we return to it at the end of the answer.
To "leave" reflection, you may use the general Value.Interface() method, which returns you the wrapped value as an interface{}.
For example:
var i int = 3
var p *int = &i
fmt.Println(p, i)
v := reflect.ValueOf(p)
fmt.Println(v.Interface()) // This is the p pointer
v2 := v.Elem()
fmt.Println(v2.Interface()) // This is i's value: 3
This will output (try it on the Go Playground):
0x414020 3
0x414020
3
For a great introduction to Go's reflection, read The Go Blog: The Laws of Reflection. Although if you're just starting with Go, I'd focus on other things and leave reflection for a later adventure.
Another use case for Value.Elem()
This is kind of an advanced topic, so don't freak out if you don't understand it. You don't need to.
We saw how Value.Elem() can be used to "navigate" when a pointer is wrapped in the reflect.Value. Doc of Value.Elem() says:
Elem returns the value that the interface v contains or that the pointer v points to.
So if reflect.Value wraps an interface value, Value.Elem() may also be used to get the concrete value wrapped in that interface value.
Interfaces in Go is its own topic, for the internals, you may read Go Data Structures: Interfaces by Russ Cox. Again, not necessarily a topic for Go starters.
Basically whatever value you pass to reflect.ValueOf(), if it's not already an interface value, it will be wrapped in an interface{} implicitly. If the passed value is already an interface value, then the concrete value stored in it will be passed as a interface{}. This second "use case" surfaces if you pass a pointer to interface (which is otherwise very rare in Go!).
So if you pass a pointer to interface, this pointer will be wrapped in an interface{} value. You may use Value.Elem() to get the pointed value, which will be an interface value (not a concrete value), and using Value.Elem() again on this will give you the concrete value.
This example illustrates it:
var r io.Reader = os.Stdin // os.Stdin is of type *os.File which implements io.Reader
v := reflect.ValueOf(r) // r is interface wrapping *os.File value
fmt.Println(v.Type()) // *os.File
v2 := reflect.ValueOf(&r) // pointer passed, will be wrapped in interface{}
fmt.Println(v2.Type()) // *io.Reader
fmt.Println(v2.Elem().Type()) // navigate to pointed: io.Reader (interface type)
fmt.Println(v2.Elem().Elem().Type()) // 2nd Elem(): get concrete value in interface: *os.File
Try it on the Go Playground.

When does reflect.IsValid return false?

I am curious about IsValid function, because during my use of this function, it never returned false. So when does it return a negative result?
As the doc reflect.IsValid() says:
It returns false if v is the zero Value. [...]
Most functions and methods never return an invalid value. If one does, its documentation states the conditions explicitly.
Value.IsValid() is supposed to report whether the reflect.Value itself is valid, not the value it wraps (if any).
All the examples below print false. You can try them on the Go Playground.
The simplest example is calling IsValid() on the zero value of reflect.Value (which is a struct):
fmt.Println(reflect.Value{}.IsValid())
The 2nd simplest example is when passing nil to reflect.ValueOf():
fmt.Println(reflect.ValueOf(nil).IsValid())
Another example: start with a pointer being nil, in this case there is no "pointed" value, a nil pointer points to nowhere. Attempting to get the reflect.Value of the pointed value using Value.Elem() results in a zero reflect.Value whose IsValid() method will return false:
var i *int
v := reflect.ValueOf(i)
v2 := v.Elem()
fmt.Println(v2.IsValid())
Or in one line:
fmt.Println(reflect.ValueOf((*int)(nil)).Elem().IsValid())
Same thing if you call Value.Indirect() on the above reflect.Value():
fmt.Println(reflect.Indirect(v).IsValid())
Or attempting to get a non-existing struct field by name using Value.FieldByName():
s := struct{}{}
fmt.Println(reflect.ValueOf(s).FieldByName("").IsValid())
Or attempting to get a non-existing method by name using Value.MethodByName():
fmt.Println(reflect.ValueOf(s).MethodByName("").IsValid())
Or attempting to get a value from a map by a non-existing key using Value.MapIndex():
m := map[int]int{}
fmt.Println(reflect.ValueOf(m).MapIndex(reflect.ValueOf(3)).IsValid())
The list goes on...

Pointer to an interface in Go

I'm currently reading the source code of the https://github.com/codegangsta/inject go package to understand how does this package works.
I have some questions concerning the file https://github.com/codegangsta/inject/blob/master/inject.go file thats use some element of the Go language I don't understand and don't find precise explanations in the documentation.
// InterfaceOf dereferences a pointer to an Interface type.
// It panics if value is not an pointer to an interface.
func InterfaceOf(value interface{}) reflect.Type {
t := reflect.TypeOf(value)
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Interface {
panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)")
}
return t
}
My first question is concerning the for loop. Why does it uses a for loop with a test expression ?
The second relates to the message in the panic function. "A pointer to an interface" is mentioned with the (*MyInterface)(nil). I only encounter a similar construction in the go documentation concerning 'compile time checking structure' when you check that a type implements a structure :
var _ SomeType = (*SomeInterface)(nil)
I did not find any informations about a statement with (*Interface)(nil) and pointer to interface.
How should we interpret this statement ? What is the relation with a pointer to interface and where could I find informations about pointer to interface ?
To summarize both answers:
The for loop
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
t.Elem() is the reflection equivalent to *t, so what this loop does it dereferencing t as long as it holds another pointer value. At the end of the loop, t will hold the value that the last pointer pointed to, not a pointer anymore.
The message
Called [...] with a value that is not a pointer to an interface. (*MyInterface)(nil)
The expression (*MyInterface)(nil) is just an (poorly phrased) example of what is expected as parameter.
The syntax is that of a conversion. A conversion will attempt to convert a value (in this case nil) to a given type (*MyInterface) in this case. So,
(*MyInterface)(nil)
will give you a zero value of a *MyInterface whose interface type would be MyInterface (play):
x := (*MyInterface)(nil)
InterfaceOf(x) // MyInterface
Of course, this value does not point somewhere meaningful.
Compile time checking of interface implementation
To avoid confusion, the construct you showed
var _ SomeType = (*SomeInterface)(nil)
is probably not what you wanted. I guess you wanted this:
var _ SomeInterface = (*SomeType)(nil)
This construct enables compile time checking of interface implementation for certain types.
So in case you're writing a library of some sort and you want to satisfy an interface without
using it, you can use this to make sure that your struct implements the interface.
Why this works
First of all, var _ someType is a variable that is going to be checked by the compiler but
will not be in the compiled program and is not accessible due to the Blank Identifier _:
The blank identifier may be used like any other identifier in a declaration, but it does not introduce a binding and thus is not declared.
This enables you do declare an arbitrary number of these constructs without interfering with the
rest of the program.
You can declare a zero value of a pointer of any type by writing:
(*T)(nil)
Check this example on play.
Next, assignability says that x is assignable to T if T is an interface and x implements T.
So to summarize:
T _ = (*x)(nil)
enforces that x implements T as everything else would be an error.
The for loop is used to continually dereference the type until it is no longer a pointer. This will handle case where the type acquired an extra indirection(s).
e.g. play.golang.org/p/vR2gKNJChE
As for the (*MyInterface)(nil), pointers to interfaces always1 an error Go code. I assume the author is just describing what he means by pointer to interface with a code snippet since they are so rare.
If you're still intrigued by the forbidden type Russ Cox has some info how exactly all this works under the hood: research.swtch.com/interfaces. You'll have a hard time finding info on the use of pointers to an interface because [1].
(1) OK not really always, but honestly don't do it unless you're a Go pro. In which case don't tell anyone about it.
That for loop is identical to while loop in other languages
The second thing is just a syntax for conversions:
(*Point)(p) // p is converted to *Point
Because how this library works you just have to pass the pointer to interface, for loop then dereferences it (if we pass something like (***MyInterface)(nil)) and then if statement checks if the ty[e pointed to is an interface.

Resources