How can i use []T
as []interface{}
?
I want to be able to do the following
s := []rune{'a', 'b', 'c'}
fmt.Println(s...)
How can i use []T
as []interface{}
?
I want to be able to do the following
s := []rune{'a', 'b', 'c'}
fmt.Println(s...)
You cannot. You have to convert:
rs := []rune{'a', 'b', 'c'}
vs := make([]interface{}, len(rs)
for i, r := range rs {
vs[i] = r
}
fmt.Println(vs...)
Why?
If T
can be assigned to interface{}
, then why []T
can’t be assigned to []interface{}
?
I’m working on an example now
The issue is that the memory layout of a []rune
is completely different than that of []interface{}
. A []rune
contains a pointer to an array of 4-byte rune
s positioned back-to-back in memory. An interface{}
“behind the scenes” is really:
type emptyInterface struct {
*_type
unsafe.Pointer
}
so a slice of []interface{}
is a slice of 16-byte (on a 64-bit system, 8-byte on a 32-bit system) structs back-to-back in memory. You cannot just cast a []rune
to an []interface{}
because the memory layout is completely different.
If i can assign T
to interface{}
then why I can’t assign []T
to []interface{}
Because in order to assign a rune
to an interface{}
, the Go runtime allocates a pointer to a rune and then stores that pointer in the interface{}
as well as the rune
type information. The memory layout is completely different. The runtime handles the magic that converts concrete types to interfaces but the runtime does not convert concrete types like slices from one type to another.
still unclear. i can assign a T to interface{}. Then i can’t have a slice of them.
This is inherently a complicated subject. Yes, pun intended.
It has to do with covariance
and invariance
and this same issue has caused many lost hours of productivity for new players in Java, C# and just about every other OOesque language that includeds generics.
Now, I know Go does not have generics, yet. But it is the same issue at hand.
you can assert
any interface{}
reference to a type because **every type is an interface{}
is covariant because every SomeType
is an interface{}
and every type
is an interface{}
[]interface{}
can not be asserted to a []SomeType
because []interface{}
is a separate type and completely unrelated to []AnyOtherType
.
I know this is a link to a question about Java, but it shows two things, one that this is a reaccuring confusing issue since 2004 in the Java world. When Java got generics.
Two it explains the idea of covariant
and invariant
very well and gives you a place to start to do more research on a complex set theory idea for yourself.
Now imagine how confusing it is going to get with Go if they have the same limitations that Java, C#, Scala, etc have with their generic implementations.
i still don’t understand.
It was stated in the official Go F.A.Q.:
https://golang.org/doc/faq#convert_slice_of_interface
if that is not clear, then you can do a research on internal memory representation for slices and interfaces.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.