去:界面{}的含义是什么?

我是新来的接口,并尝试通过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的接口值将设置接口值的两个字。

5c0TS.png

接口值中的第一个单词指向我称之为接口表或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后来更改, sc应该具有原始值,而不是新的一。
存储在接口中的值可能是任意大的,但是只有一个字专用于保存接口结构中的值,因此分配会在堆上分配一块内存,并将指针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的概念是:

  1. 一切都有一个types 。 你可以定义一个新的types,我们称之为T.假设现在我们的typesT有三种方法: ABC
  2. 为types指定的一组方法称为“ 接口types ”。 让我们在我们的例子中调用它:T_interface。 等于T_interface = (A, B, C)
  3. 您可以通过定义方法的签名来创build“接口types”。 MyInterface = (A, )
  4. 当你指定一个types为 “interface type”的variables的时候,你只能给它分配一个接口是你的接口超集的types。 这意味着MyInterface包含的所有方法都必须包含在T_interface

你可以推断出所有types的“接口types”都是空接口的超集。