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.Interface
和reflect.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 中很少有意义),访问元素类型并检查其类型。
TA贡献1818条经验 获得超7个赞
接口类型是由关键字引入的类型interface
,或者是由定义的类型的名称(当然还要加上该接口的实际要求)。type name interface
任何类型,无论是否是接口类型,如果具有适当的命名方法集,都可以实现接口类型。也就是说,struct
类型可能足以与某些接口类型一起使用。即使是非struct
类型也可能就足够了:
type foo int func (receiver_arg foo) method1() { ... }
类型名称foo
现在实现任何需要指定方法的接口method1
(当然前提是它实现了其余的任何所需方法)。
...定义的类型[通过
type
关键字]是具有给定类型的新的、不同的类型,但它们属于同一类型类别...
是的,就是这样。使用reflect
,你会发现它们有相同的Kind
。kind这个词并不像这样出现在规范中,但它非常有用,这里的链接枚举了 Go 中的所有基本类型。
- 2 回答
- 0 关注
- 75 浏览
添加回答
举报