Why does golang allow named slice type assignment without explicit type conversion?

huangapple go评论85阅读模式
英文:

Why does golang allow named slice type assignment without explicit type conversion?

问题

我以为Go语言不允许在没有显式类型转换的情况下将命名类型赋值给实际类型。

但是如果我将[]byte赋值给json.RawMessage,它为什么可以编译通过而没有错误呢?

var a json.RawMessage // 类型 RawMessage []byte
var b []byte

a = b

var x time.Duration // 类型 Duration int64
var y int64

x = y // 错误:无法将类型为int64的y赋值给time.Duration

链接:https://play.golang.org/p/oD5LwJl7an

英文:

I thought go didn't allow any named type to actual type assignment without explicit type conversion.

But how does it compile without an error if I assign []byte to json.RawMessage?

var a json.RawMessage // type RawMessage []byte
var b []byte

a = b

var x time.Duration // type Duration int64
var y int64

x = y // ERROR: cannot use y (type int64) as type time.Duration in assignment

https://play.golang.org/p/oD5LwJl7an

答案1

得分: 6

int64是一个命名类型,[]byte是一个无名类型。

命名类型通过(可能带限定符的)类型名称来指定;无名类型使用类型字面值来指定,它从现有类型组合成一个新类型 - golang spec

另外

如果两个命名类型的类型名称源自相同的TypeSpec,则它们是相同的。命名类型和无名类型始终不同。如果对应的类型字面值相同,那么两个无名类型是相同的,也就是说,它们具有相同的字面结构,并且相应的组件具有相同的类型 - golang spec

因此

type MyByteArray []byte
type MyInt int

var a MyByteArray
var b []byte
a = b // 合法,因为数组是无名的 - 它们对应的类型字面值是相同的

var x MyInt
var y int
x = y // 非法,因为int是命名类型 - 它们不是源自相同的类型规范

另请参阅 https://stackoverflow.com/questions/19334542/why-can-i-type-alias-functions-and-use-them-without-casting

英文:

int64 is a named type, []byte is an unamed type.

> Named types are specified by a (possibly qualified) type name; unnamed types are specified using a type literal, which composes a new type from existing types - golang spec

Also

> Two named types are identical if their type names originate in the same TypeSpec. A named and an unnamed type are always different. Two unnamed types are identical if the corresponding type literals are identical, that is, if they have the same literal structure and corresponding components have identical types. - golang spec

Therefore

type MyByteArray []byte
type MyInt int

var a MyByteArray
var b []byte
a = b // legal because array is unnamed - their corresponding type literals are identical

var x MyInt
var y int
x = y // illegal because int is named - they don't originate in the same type spec

Also see https://stackoverflow.com/questions/19334542/why-can-i-type-alias-functions-and-use-them-without-casting

huangapple
  • 本文由 发表于 2016年4月12日 01:29:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/36555352.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定