2 回答

TA貢獻1864條經驗 獲得超2個贊
我相信這里最初作者的邏輯是命名類型的命名是有原因的 - 它代表不同的東西,而不僅僅是底層類型。
我想我在 golang-nuts 的某個地方讀過它,但不記得確切的討論。
考慮以下示例:
type Email string
您將其命名為 Email,因為您需要表示電子郵件實體,而 'string' 只是它的簡化表示,足夠一開始。但稍后,您可能希望將 Email 更改為更復雜的內容,例如:
type Email struct {
Address string
Name string
Surname string
}
假設它是一個字符串,這將破壞所有與 Email 一起使用的代碼。

TA貢獻1829條經驗 獲得超9個贊
這是因為 Go 沒有類繼承。它使用結構組合代替。命名類型不會從它們的底層類型繼承屬性(這就是為什么它不被稱為“基本類型”)。
因此,當您specialString使用預定義類型的基礎類型聲明命名類型時string,您的新類型與基礎類型完全不同。這是因為 Go 假設您希望為新類型分配不同的行為,并且在運行時之前不會檢查其基礎類型。這就是 Go 既是靜態語言又是動態語言的原因。
當你打印
fmt.Println(reflect.TypeOf(ss)) // specialString
你得到specialString,不是string。如果你看一下Println()定義如下:
func Println(a ...interface{}) (n int, err error) {
return Fprintln(os.Stdout, a...)
}
這意味著您可以打印任何預先聲明的類型(int、float64、string),因為它們都實現了至少零個方法,這使得它們已經符合空接口并作為“可打印”傳遞,但不是您的命名類型specialString,它仍然未知在編譯期間去。我們可以通過打印 our interface{}against的類型來檢查specialString。
type specialString string
type anything interface{}
s := string("cheese")
ss := specialString("special cheese")
at := anything("any cheese")
fmt.Println(reflect.TypeOf(ss)) // specialString
fmt.Println(reflect.TypeOf(s)) // string
fmt.Println(reflect.TypeOf(at)) // Wow, this is also string!
你可以看到它specialString一直在調皮它的身份?,F在,看看它在運行時傳遞給函數時的效果
func printAnything(i interface{}) {
fmt.Println(i)
}
fmt.Println(ss.(interface{})) // Compile error! ss isn't interface{} but
printAnything(ss) // prints "special cheese" alright
ss就interface{}功能而言已經過得去。到那時,Go 已經創建了ss一個interface{}.
- 2 回答
- 0 關注
- 216 瀏覽
添加回答
舉報