考虑以下代码:
package main
import "fmt"
type specialString string
func printString(s string) {
fmt.Println(s)
}
// unlike, say, C++, this is not legal GO, because it redeclares printString
//func printString(s specialString) {
// fmt.Println("Special: " + s)
//}
func main() {
ss := specialString("cheese")
// ... so then why shouldn't this be allowed?
printString(ss)
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:为什么定义语言以便不允许调用printString(ss)in main()?(我不是在寻找指向Golang规则的答案;我已经读过它们了,我发现specialString和string都有相同的"底层类型",两种类型都是'命名' - 如果你考虑的话要命名的泛型类型'string',Golang显然也是这样 - 因此它们不能根据规则分配.)
但为什么这样的规则呢?通过将内置类型视为"命名"类型并阻止您将命名类型传递给接受相同底层内置类型的所有标准库函数,可以解决哪些问题?有人知道语言设计师在这里想到了什么吗?
从我的角度来看,它似乎在代码中创建了许多无意义的类型转换,并且不鼓励在实际上有意义的情况下使用强类型.
我相信这里的初始作者的逻辑是命名类型是出于某种原因而命名的 - 它代表了不同的东西,而不仅仅是基础类型.
我想我已经在golang-nuts中的某个地方读过它,但不记得确切的讨论.
请考虑以下示例:
type Email string
Run Code Online (Sandbox Code Playgroud)
你将它命名为Email,因为你需要代表电子邮件实体,而'string'只是它的简化表示,一开始就足够了.但是稍后,您可能希望将电子邮件更改为更复杂的内容,例如:
type Email struct {
Address string
Name string
Surname string
}
Run Code Online (Sandbox Code Playgroud)
这将破坏所有与电子邮件一起工作的代码,假设它是一个字符串.