回答

收藏

interface{} 的含义是什么?

技术问答 技术问答 283 人阅读 | 0 人回复 | 2023-09-12

我是接口新手,试着通过github执行 SOAP 请求
1 k  V% q2 K( J2 f) J5 P* m0 J我不明白这是什么意思( |! P2 t3 b( e- p' \
    Msg interface{}
    2 r8 e6 C5 W6 `: O  ~. b# Z9 j
代码:/ q  b$ Y. @. P4 o* X  l* j* {
    type Envelope struct    Body `xml:"soap:"`}type Body struct    Msg interface{}}
    + T7 v9 T9 e2 ~' y( ~7 L
我观察到了相同的语法) n- O7 P) u2 D
    fmt.Println9 Q% U+ u, s( h; U8 s
但我不明白我在取得什么6 y2 G( J; s$ Q: F, w
    interface{}# M) u( R7 E. k% k; ?
               
0 p% z0 P2 k2 o6 V  O  r4 @" e  J    解决方案:                                                               
: g- O, s. T& j. E                                                                接口是两件事:
3 _+ |) n6 R" G# R" [& w* N这是一组方法,
2 b( h  v& o) m  \5 O但它也是一种类型
interface{}类型的空接口是没有方法的接口。
5 c8 m4 |9 F* @由于没有implements所有类型的关键字至少实现零方法,并自动满足接口,所有类型都满足空接口的要求0 }, c' E2 K3 r7 F4 P" K0 e
这意味着如果你写一个,你会写一个interface{}作为参数的函数,{}值该函数可以提供任何值# y- b7 P* A  V' }: o+ N3 q6 |
(这就是Msg你的问题所代表的:任何价值)
# ~0 b  |6 v" R8 p
    func DoSomething(v interface{}...}
    % L+ Y* X; _5 Y
这是一个令人困惑的地方:
4 @8 S. W# O- x& h4 x在DoSomething函数内部,什么是v类型?
. o: x3 M' G: K) k初学者地鼠被引导相信v但这是错误的。  P5 b# y% Y' ?: v8 R$ T
v不属于任何类型;它是interface{}类型.$ q2 o# w$ g# q- [+ y' J
将值传递给DoSomething函数时,Go 操作时执行类型转换(如有必要),并将值转换为interface{}值
5 r; P' ~: z' c2 I所有值运行时只有一种类型,v静态类型是interface{}.1 {/ k: c( S$ k+ S" P! s2 p
接口值由两个数据字组成
' @, P: @' l5 o; j# p一个词用于指向值的基本类型的方法表,$ ~: U1 Q9 s/ U: Y% h0 `
另一个词用于指向该值持有的实际数据。
附录:这是 Russ 关于接口结构非常完整的文章:; u% a0 h0 R3 s" X: M: B0 [
    type Stringer interface    String() string}$ x' s1 R. q) a3 K" I
接口值表示两个字对,给出一个指向存储在接口中的类型信息向相关数据的指针。, f$ z+ G+ B( B$ X/ e/ J* d4 r
将 b 分配给 Stringer 类型的接口值将设置接口值。- M0 f2 e$ K3 `
5 R/ f+ M( |6 l1 B+ t
接口值中的第一个词指向我所说的接口表或 itable(发音为 i-table;运行时源,C 实现名称为 Itab)。# D1 u2 ?) S  \% p$ V
itable 从涉及类型的元数据开始,然后成为函数指针列表。
, S; L/ J+ X9 D8 D1 F) ?) F4 h请注意,itable 与接口类型相对应,而不是动态类型* C& i* H  Z. L
就我们的例子而言,Stringer持有类型 Binary的 itable列出满足 Stringer 方法,这只是String: Binary 的其他方法 ( Get) 没有出现itable.
: _9 y+ |5 U3 o! y9 G+ T接口值中的第二个字指向实际数据,在本例中为b.
& h% R4 o9 j6 d' L2 _! @赋值var s Stringer = b创建副本b而不是指向副本b原因与var c uint64 = b创建相同的副本:如果b以后会发生变化,s并且c应该有原始值,而不是新值。' B# t* Q% ^8 i" ?* b' r( s
存储在接口中的值可能很大,但只有一个单词专门用于保存接口结构中的值,因此赋值将在堆上分配一个内存,并在字槽中记录指针。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则