亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go 中是否有關于什么類型是接口類型的官方說法?

Go 中是否有關于什么類型是接口類型的官方說法?

Go
素胚勾勒不出你 2023-07-17 14:16:44
這是一個 Go 語法問題,看起來是一個愚蠢的問題,但我一直在檢查Go 語言規范,找到一些官方單詞或定義來定義什么類型是 xxx 類型,比如說,什么類型是接口類型?例如,我看到這樣的詞:接口類型的方法集就是它的接口?;蛘咔度胱侄伪仨氈付轭愋兔Q T 或指向非接口類型名稱 *T 的指針,并且 T 本身可能不是指針類型。或者考慮一個具有兩種方法的結構類型T ...type T struct {? a int}....像結構類型這樣的類型文字struct {...},那么Ain?type A struct {...}和Bin呢type B interface{...}?是A結構體類型還是B接口類型?是的,從上面的結構類型示例中T,我可以看出,其給定類型是結構類型或接口類型的已定義類型(通過“類型”聲明)也是結構或接口類型。A結構類型也是如此,B接口類型也是如此。但這條規則的官方定義在哪里?對于定義的類型,我只能找到以下與類型類別相關的內容:類型定義創建一個新的、不同的類型,其具有與給定類型相同的基礎類型和操作,并將標識符綁定到它。所以我的理解是,定義的類型是與給定類型不同的新類型,但它們屬于同一類型類別,例如接口類型或結構類型。盡管如此,仍然沒有這樣的定義。
查看完整描述

2 回答

?
慕少森

TA貢獻2019條經驗 獲得超9個贊

太長了;

如果其基礎類型T接口類型,則類型的種類是接口。

如果其基礎類型是結構體類型,則該類型是結構體。T


規范:結構類型和規范:接口類型準確指定了結構和接口類型:

StructType? ? = "struct" "{" { FieldDecl ";" } "}" .

FieldDecl? ? ?= (IdentifierList Type | EmbeddedField) [ Tag ] .

EmbeddedField = [ "*" ] TypeName .

Tag? ? ? ? ? ?= string_lit .


InterfaceType? ? ? = "interface" "{" { MethodSpec ";" } "}" .

MethodSpec? ? ? ? ?= MethodName Signature | InterfaceTypeName .

MethodName? ? ? ? ?= identifier .

InterfaceTypeName? = TypeName .

例如,這些是結構類型:


struct { A int }

struct {}

struct { _ int }

這些是接口類型:


interface { String() string }

interface {}

我們可以使用類型聲明來創建新類型,例如:

type?Point?struct?{?X,?Y?int?}

上面的類型定義創建了一個新的、不同的類型,其具有與給定類型相同的基礎類型和操作,并將標識符綁定到它。底層類型的定義是遞歸的:

每個類型T都有一個基礎類型:如果T是預聲明的布爾、數字或字符串類型之一,或者類型文字,則相應的基礎類型是T其本身。否則,的基礎類型是其類型聲明T中引用的類型的基礎類型。T

當我們談論任意類型(結構體或接口)時,我們談論的是它們的類型。

鑒于此,基本上你的問題相當于:

“什么時候是任意類型的接口或結構體?”

這個問題的答案不在規范中,但我們可以這樣定義它:

如果類型的基礎類型T接口類型,則該類型的種類是接口。

相似地:

如果類型的基礎類型T結構體類型,則該類型的類型是結構體。

例如:

type?Point?struct?{?X,?Y?int?}
type?PP?Point

struct { X, Y int }是kind?struct的類型嗎?是的,因為由于它是類型文字,所以它的基礎類型就是它本身,并且根據定義它是結構類型。

Point一個結構體嗎?由于 的基礎類型Point是它在其類型聲明中引用的類型的基礎類型,即類型文字(見上文),因此它是 struct 類型(其種類是struct)。

PP一個結構體嗎?由于它的基礎類型是它在類型聲明中引用的類型的基礎類型(即Point),其基礎類型是結構體類型文字,是的,它也是結構體類型。

我們所說的這種就是reflect.Kind用類型來表示的。有reflect.Interfacereflect.Struct常量(類型為reflect.Kind)來表示結構接口類型。并且reflect.Type類型描述符有一個Type.Kind()方法來訪問這種類型。

這是檢查某個值的類型(種類)是否為結構的方法,例如:

func isStruct(i interface{}) bool {

? ? return reflect.TypeOf(i).Kind() == reflect.Struct

}

測試它(在Go Playground上嘗試一下):


fmt.Println(isStruct(Point{}))? ? // true

fmt.Println(isStruct(PP{}))? ? ? ?// true

fmt.Println(isStruct(struct{}{})) // true

fmt.Println(isStruct("text"))? ? ?// false

檢查接口類型有點復雜,因為將接口值傳遞給期望的函數interface{}不會按原樣傳遞接口值,而是“存儲”在其中的具體值,并作為值傳遞interface{}。我們必須傳遞一個指向接口的指針(否則這在 Go 中很少有意義),訪問元素類型并檢查其類型。

查看完整回答
反對 回復 2023-07-17
?
弒天下

TA貢獻1818條經驗 獲得超8個贊

接口類型是由關鍵字引入的類型interface,或者是由定義的類型的名稱(當然還要加上該接口的實際要求)。type name interface

任何類型,無論是否是接口類型,如果具有適當的命名方法集,都可以實現接口類型。也就是說,struct類型可能足以與某些接口類型一起使用。即使是非struct類型也可能就足夠了:

type?foo?int
func?(receiver_arg?foo)?method1()?{?...?}

類型名稱foo現在實現任何需要指定方法的接口method1(當然前提是它實現了其余的任何所需方法)。

...定義的類型[通過type關鍵字]是具有給定類型的新的、不同的類型,但它們屬于同一類型類別...

是的,就是這樣。使用reflect,你會發現它們有相同的Kind。kind這個詞并不像這樣出現在規范中,但它非常有用,這里的鏈接枚舉了 Go 中的所有基本類型。


查看完整回答
反對 回復 2023-07-17
  • 2 回答
  • 0 關注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號