Reputation: 78065
Two closely related question:
Why doesn't Go Specification allow you to convert []T1
to []T2
if T2
has the underlying type of T1
?
What are the negative consequences of doing the conversion using the unsafe
package?
Example:
package main
import (
"fmt"
"unsafe"
)
type T1 struct {
Val int
}
// T2 has the underlying type of T1
type T2 T1
func main() {
a := []T1{T1{12}}
// cannot convert a (type []T1) to type []T2
//b := ([]T2)(a)
// But with some unsafe we can do it.
// So, why doesn't Go allow it? And what unforeseen consequence might it have?
b := *(*[]T2)(unsafe.Pointer(&a))
b[0].Val = 42
fmt.Println(a[0].Val) // 42
}
Playground: http://play.golang.org/p/x2tBRKuRF1
Example of usage:
If T1 implements a certain interface, say json.Marshaler
, and you want to JSON encode the type in a different way, you create a new type T2 T1
with its own implementation of json.Marshaler
.
It works fine when marshaling single values, but when you get a []T1 slice you would have to either copy it to a []T2 slice or create a new type ST1 []T1
with its own MarshalJSON()
method. It would be nice to do a simple conversion instead instead of having to turn to unsafe
as it might result in runtime errors instead of compile time.
Upvotes: 1
Views: 145
Reputation: 166845
The Go Programming Language Specification
A non-constant value x can be converted to type T if x's type and T have identical underlying types.
For example,
package main
import (
"fmt"
)
type T1 struct {
Val int
}
type T2 T1
type ST1 []T1
type ST2 ST1
func main() {
a := ST1{T1{42}}
fmt.Println(a) // 42
// convert a (type ST1) to type []ST2
b := ST2(a)
fmt.Println(b) // 42
}
Output:
[{42}]
[{42}]
Upvotes: 1