Go自定义类型赋值疑惑:切片可隐式转换?基本类型却不行?
Go自定义类型赋值规则解惑:切片 vs 基本类型的差异
嘿,这个问题问得特别精准,刚好触及了Go类型系统里容易搞混的细节——咱们分两个例子拆解,把道理说透:
一、为什么切片自定义类型Coartl能直接和[][]rune赋值?
先看你的第一个例子:type Coartl [][]rune是定义了一个命名自定义类型,它的「底层类型」是[][]rune(也就是Go用来存储这个类型值的实际底层结构)。
Go的赋值规则里有这么一条:如果赋值的两边,一方是命名类型,另一方是与它底层类型完全相同的非命名类型,那么可以直接隐式赋值。
这里的art变量类型是[][]rune,这是一个非命名类型(它是复合类型的字面量形式,没有被type关键字赋予过独立名称);而Coartl是命名类型,两者底层类型完全一致,所以coartl = art这种隐式赋值是合法的。
包括你代码里PushFront方法里的*ptr = append([][]rune{str}, (*ptr)...),append返回的是[][]rune(非命名类型),赋值给*ptr(Coartl命名类型),也是同样的规则在生效。
二、为什么基本类型的自定义类型Int不能直接和int赋值?
再看第二个例子:type Int int是命名自定义类型,而int本身是Go内置的命名类型(Go把所有基本类型都定义成了命名类型)。
这时候赋值的两边都是命名类型,哪怕它们的底层类型完全相同,Go也不允许隐式赋值——必须用显式转换:var j Int = Int(i)才能通过编译。
核心规则总结
把上面的差异提炼成两条清晰的规则:
- 「命名类型 ↔ 同底层非命名类型」:允许隐式赋值/转换
- 「命名类型 ↔ 同底层命名类型」:必须显式转换
内容的提问来源于stack exchange,提问作者srilakshmikanthanp
相关产品推荐
相关产品推荐

