我是接口的新手,并尝试通过github执行 SOAP 请求
我不明白什么意思
Msg interface{}
在这段代码中:
type Envelope struct { Body `xml:"soap:"` } type Body struct { Msg interface{} }
我观察到相同的语法
fmt.Println
但不明白正在取得什么
interface{}
接口是两件事: 它是一组方法, 但它也是一种类型 该interface{}类型的空接口是没有方法的接口。 由于没有implements关键字,所有类型至少实现零个方法,并且自动满足接口,所有类型都满足空接口。 这意味着,如果您编写一个将interface{}值作为参数的函数,则可以为该函数提供任何值。
接口是两件事:
该interface{}类型的空接口是没有方法的接口。
由于没有implements关键字,所有类型至少实现零个方法,并且自动满足接口,所有类型都满足空接口。 这意味着,如果您编写一个将interface{}值作为参数的函数,则可以为该函数提供任何值。
(这就是Msg你的问题所代表的:任何价值)
Msg
func DoSomething(v interface{}) { // ... }
这是令人困惑的地方: 在DoSomething函数内部,什么是v类型? 初学者地鼠被引导相信“v是任何类型”,但这是错误的。 v不属于任何类型;它是interface{}类型. 当将值传递给DoSomething函数时,Go 运行时将执行类型转换(如有必要),并将值转换为interface{}值。 所有值在运行时都只有一种类型,而v的一种静态类型是interface{}. 接口值由两个数据字构成: 一个词用于指向值的基础类型的方法表, 另一个词用于指向该值所持有的实际数据。
这是令人困惑的地方:
在DoSomething函数内部,什么是v类型?
DoSomething
v
初学者地鼠被引导相信“v是任何类型”,但这是错误的。 v不属于任何类型;它是interface{}类型.
当将值传递给DoSomething函数时,Go 运行时将执行类型转换(如有必要),并将值转换为interface{}值。 所有值在运行时都只有一种类型,而v的一种静态类型是interface{}.
接口值由两个数据字构成:
附录:这是 Russ 关于接口结构的非常完整的文章:
type Stringer interface { String() string }
接口值表示为一个两字对,给出一个指向存储在接口中的类型信息的指针和一个指向相关数据的指针。 将 b 分配给 Stringer 类型的接口值会设置接口值的两个字。
接口值中的第一个词指向我所说的接口表或 itable(发音为 i-table;在运行时源中,C 实现名称是 Itab)。 itable 以一些关于所涉及类型的元数据开始,然后成为一个函数指针列表。 请注意, itable 对应于接口类型,而不是动态类型。 就我们的示例而言,Stringer持有类型 Binary的 itable列出了用于满足 Stringer 的方法,这只是String: Binary 的其他方法 ( Get) 没有出现在itable. 接口值中的第二个字指向实际数据,在本例中为b. 赋值var s Stringer = b创建一个副本b而不是指向副本的b原因与var c uint64 = b创建副本相同:如果b以后发生更改,s并且c应该具有原始值,而不是新值。 存储在接口中的值可能是任意大的,但只有一个字专门用于保存接口结构中的值,因此赋值会在堆上分配一块内存并将指针记录在一个字槽中。
接口值中的第一个词指向我所说的接口表或 itable(发音为 i-table;在运行时源中,C 实现名称是 Itab)。 itable 以一些关于所涉及类型的元数据开始,然后成为一个函数指针列表。 请注意, itable 对应于接口类型,而不是动态类型。 就我们的示例而言,Stringer持有类型 Binary的 itable列出了用于满足 Stringer 的方法,这只是String: Binary 的其他方法 ( Get) 没有出现在itable.
Stringer
String
Get
itable
接口值中的第二个字指向实际数据,在本例中为b. 赋值var s Stringer = b创建一个副本b而不是指向副本的b原因与var c uint64 = b创建副本相同:如果b以后发生更改,s并且c应该具有原始值,而不是新值。 存储在接口中的值可能是任意大的,但只有一个字专门用于保存接口结构中的值,因此赋值会在堆上分配一块内存并将指针记录在一个字槽中。
b
var s Stringer = b
var c uint64 = b
s
c