去:界面{}的含义是什么?
我是新来的接口,并尝试通过github做SOAP请求
我不明白的意思
Msg interface{}
在这个代码中:
type Envelope struct { Body `xml:"soap:"` } type Body struct { Msg interface{} }
我已经观察到相同的语法
fmt.Println
但不明白什么是通过
interface{}
您可以参考文章“ 如何使用Go中的接口 ”(基于“ Russ Cox对接口的描述 ”):
什么是接口?
一个接口是两件事情:
- 这是一套方法,
- 但它也是一种types
interface{}
types, 空接口是没有方法的接口。由于没有implements关键字,所有types都至less实现零方法,自动满足一个接口, 所有types满足空接口 。
这意味着如果你编写一个以interface{}
为参数的函数, 那么你可以给该函数提供任何值 。
(这是什么Msg
代表你的问题:任何价值)
func DoSomething(v interface{}) { // ... }
这是令人困惑的地方:
在
DoSomething
函数里面,v
的types是什么?初学者地鼠被认为“
v
是任何types”,但这是错误的。
v
不是任何types的; 它是interface{}
types 。将值传递给
DoSomething
函数时,Go运行时将执行types转换 (如有必要), 并将该值转换为interface{}
值 。
所有值在运行时都只有一种types,而v
是一种静态types是interface{}
。一个接口值由两个数据字构成 :
- 一个单词用于指向该值的基础types的方法表,
- 而另一个字用来指向由该值保存的实际数据。
附录:这是Russ关于接口结构的文章:
type Stringer interface { String() string }
接口值被表示为一个双字对,它给出一个关于存储在接口中的types信息的指针和一个指向相关数据的指针。
将b分配给Stringertypes的接口值将设置接口值的两个字。
接口值中的第一个单词指向我称之为接口表或itable (发音为i-table;在运行时源中,C实现名称为Itab)。
可以从一些有关所涉及types的元数据开始,然后成为一个函数指针列表。
请注意,itable对应于接口types,而不是dynamictypes 。
就我们的例子而言,Stringer
控制typesBinary的可用范例列出了用于满足Stringer的方法,它只是String
:Binary的其他方法(Get
)在其中并没有出现。接口值中的第二个单词指向实际数据 ,在这种情况下是
b
的副本。
赋值var c uint64 = b
var s Stringer = b
作为var s Stringer = b
的副本,而不是指向b
,原因与var c uint64 = b
进行复制相同:如果b
后来更改,s
和c
应该具有原始值,而不是新的一。
存储在接口中的值可能是任意大的,但是只有一个字专用于保存接口结构中的值,因此分配会在堆上分配一块内存,并将指针logging在单字槽中。
interface{}
意味着你可以把任何types的值,包括你自己的自定义types。 Go中的所有types都满足空接口( interface{}
是一个空接口)。
在你的例子中,Msg字段可以有任何types的值。
例:
package main import ( "fmt" ) type Body struct { Msg interface{} } func main() { b := Body{} b.Msg = "5" fmt.Printf("%#v %T \n", b.Msg, b.Msg) // Output: "5" string b.Msg = 5 fmt.Printf("%#v %T", b.Msg, b.Msg) //Output: 5 int }
去游乐场
它被称为空接口,并且被所有types实现,这意味着你可以在Msg
字段中放置任何东西。
例如:
body := Body{3} fmt.Printf("%#v\n", body) // -> main.Body{Msg:3} body = Body{"anything"} fmt.Printf("%#v\n", body) // -> main.Body{Msg:"anything"} body = Body{body} fmt.Printf("%#v\n", body) // -> main.Body{Msg:main.Body{Msg:"anything"}}
这是一个types实现一个接口的事实的逻辑扩展,只要它具有接口的所有方法。
来自Golang规格 :
一个接口types指定一个称为其接口的方法集。 接口types的variables可以存储任何types的值,方法集是接口的任何超集。 据说这种types实现了界面。 接口types的未初始化variables的值为零。
一个types实现了任何包含其方法子集的接口,因此可以实现几个不同的接口。 例如,所有types都实现空的接口:
接口{}
graps的概念是:
- 一切都有一个types 。 你可以定义一个新的types,我们称之为T.假设现在我们的types
T
有三种方法:A
,B
,C
。 - 为types指定的一组方法称为“ 接口types ”。 让我们在我们的例子中调用它:T_interface。 等于
T_interface = (A, B, C)
- 您可以通过定义方法的签名来创build“接口types”。
MyInterface = (A, )
- 当你指定一个types为 “interface type”的variables的时候,你只能给它分配一个接口是你的接口超集的types。 这意味着
MyInterface
包含的所有方法都必须包含在T_interface
你可以推断出所有types的“接口types”都是空接口的超集。