2 回答

TA貢獻(xiàn)2019條經(jīng)驗(yàn) 獲得超9個(gè)贊
太長(zhǎng)了;
如果其基礎(chǔ)類型
T
是接口類型,則類型的種類是接口。如果其基礎(chǔ)類型是結(jié)構(gòu)體類型,則該類型是結(jié)構(gòu)體。
T
規(guī)范:結(jié)構(gòu)類型和規(guī)范:接口類型準(zhǔn)確指定了結(jié)構(gòu)和接口類型:
StructType? ? = "struct" "{" { FieldDecl ";" } "}" .
FieldDecl? ? ?= (IdentifierList Type | EmbeddedField) [ Tag ] .
EmbeddedField = [ "*" ] TypeName .
Tag? ? ? ? ? ?= string_lit .
InterfaceType? ? ? = "interface" "{" { MethodSpec ";" } "}" .
MethodSpec? ? ? ? ?= MethodName Signature | InterfaceTypeName .
MethodName? ? ? ? ?= identifier .
InterfaceTypeName? = TypeName .
例如,這些是結(jié)構(gòu)類型:
struct { A int }
struct {}
struct { _ int }
這些是接口類型:
interface { String() string }
interface {}
我們可以使用類型聲明來(lái)創(chuàng)建新類型,例如:
type?Point?struct?{?X,?Y?int?}
上面的類型定義創(chuàng)建了一個(gè)新的、不同的類型,其具有與給定類型相同的基礎(chǔ)類型和操作,并將標(biāo)識(shí)符綁定到它。底層類型的定義是遞歸的:
每個(gè)類型
T
都有一個(gè)基礎(chǔ)類型:如果T
是預(yù)聲明的布爾、數(shù)字或字符串類型之一,或者類型文字,則相應(yīng)的基礎(chǔ)類型是T
其本身。否則,的基礎(chǔ)類型是其類型聲明T
中引用的類型的基礎(chǔ)類型。T
當(dāng)我們談?wù)撊我忸愋停ńY(jié)構(gòu)體或接口)時(shí),我們談?wù)摰氖撬鼈兊?em>類型。
鑒于此,基本上你的問(wèn)題相當(dāng)于:
“什么時(shí)候是任意類型的接口或結(jié)構(gòu)體?”
這個(gè)問(wèn)題的答案不在規(guī)范中,但我們可以這樣定義它:
如果類型的基礎(chǔ)類型
T
是接口類型,則該類型的種類是接口。
相似地:
如果類型的基礎(chǔ)類型
T
是結(jié)構(gòu)體類型,則該類型的類型是結(jié)構(gòu)體。
例如:
type?Point?struct?{?X,?Y?int?} type?PP?Point
struct { X, Y int }
是kind?struct的類型嗎?是的,因?yàn)橛捎谒穷愋臀淖?,所以它的基礎(chǔ)類型就是它本身,并且根據(jù)定義它是結(jié)構(gòu)類型。
是Point
一個(gè)結(jié)構(gòu)體嗎?由于 的基礎(chǔ)類型Point
是它在其類型聲明中引用的類型的基礎(chǔ)類型,即類型文字(見(jiàn)上文),因此它是 struct 類型(其種類是struct)。
是PP
一個(gè)結(jié)構(gòu)體嗎?由于它的基礎(chǔ)類型是它在類型聲明中引用的類型的基礎(chǔ)類型(即Point
),其基礎(chǔ)類型是結(jié)構(gòu)體類型文字,是的,它也是結(jié)構(gòu)體類型。
我們所說(shuō)的這種就是reflect.Kind
用類型來(lái)表示的。有reflect.Interface
和reflect.Struct
常量(類型為reflect.Kind
)來(lái)表示結(jié)構(gòu)和接口類型。并且reflect.Type
類型描述符有一個(gè)Type.Kind()
方法來(lái)訪問(wèn)這種類型。
這是檢查某個(gè)值的類型(種類)是否為結(jié)構(gòu)的方法,例如:
func isStruct(i interface{}) bool {
? ? return reflect.TypeOf(i).Kind() == reflect.Struct
}
測(cè)試它(在Go Playground上嘗試一下):
fmt.Println(isStruct(Point{}))? ? // true
fmt.Println(isStruct(PP{}))? ? ? ?// true
fmt.Println(isStruct(struct{}{})) // true
fmt.Println(isStruct("text"))? ? ?// false
檢查接口類型有點(diǎn)復(fù)雜,因?yàn)閷⒔涌谥祩鬟f給期望的函數(shù)interface{}
不會(huì)按原樣傳遞接口值,而是“存儲(chǔ)”在其中的具體值,并作為值傳遞interface{}
。我們必須傳遞一個(gè)指向接口的指針(否則這在 Go 中很少有意義),訪問(wèn)元素類型并檢查其類型。

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超8個(gè)贊
接口類型是由關(guān)鍵字引入的類型interface
,或者是由定義的類型的名稱(當(dāng)然還要加上該接口的實(shí)際要求)。type name interface
任何類型,無(wú)論是否是接口類型,如果具有適當(dāng)?shù)拿椒?,?em>可以實(shí)現(xiàn)接口類型。也就是說(shuō),struct
類型可能足以與某些接口類型一起使用。即使是非struct
類型也可能就足夠了:
type?foo?int func?(receiver_arg?foo)?method1()?{?...?}
類型名稱foo
現(xiàn)在實(shí)現(xiàn)任何需要指定方法的接口method1
(當(dāng)然前提是它實(shí)現(xiàn)了其余的任何所需方法)。
...定義的類型[通過(guò)
type
關(guān)鍵字]是具有給定類型的新的、不同的類型,但它們屬于同一類型類別...
是的,就是這樣。使用reflect
,你會(huì)發(fā)現(xiàn)它們有相同的Kind
。kind這個(gè)詞并不像這樣出現(xiàn)在規(guī)范中,但它非常有用,這里的鏈接枚舉了 Go 中的所有基本類型。
- 2 回答
- 0 關(guān)注
- 125 瀏覽
添加回答
舉報(bào)