Go 接口中的“动态类型”是什么意思?

Qia*_* Li 5 go

The Way to Go: A Thorough Introduction To The Go Programming Language (Ivo Balbaert) 包含这句话,我不太明白:

接口类型可以包含对实现该接口的任何类型的实例的引用(接口具有所谓的动态类型)

这方面的一个例子是什么,为什么这很有用?

rig*_*old 9

假设你有一个接口:

type I interface{ F() }
Run Code Online (Sandbox Code Playgroud)

以及所述接口的两个实现:

type S struct{}
func (S) F() { }

type T struct{}
func (T) F() { }
Run Code Online (Sandbox Code Playgroud)

然后:

var x I
x = S{}
Run Code Online (Sandbox Code Playgroud)

现在的静态类型xI,动态类型是S

您可以重新分配x一个不同类型的值来实现I

x = T{}
Run Code Online (Sandbox Code Playgroud)

现在的静态类型xI(它永远不会改变),它的动态类型是T

IOW:接口值的动态类型是最初转换为接口类型的值的类型。


bas*_*gys 4

定义

接口具有所谓的动态类型

动态类型意味着它可以保存对不同类型(例如 string、int 等)的引用,并且可以在运行时更改,而静态类型在编译时检查并且不能更改。

然而,书中给出的定义受到质疑。根据 Golang 官方网站:

有人说 Go 的接口是动态类型的,但这是误导。它们是静态类型的:接口类型的变量始终具有相同的静态类型,即使在运行时存储在接口变量中的值可能会更改类型,该值也将始终满足接口的要求。

来源

例子

尽管接口并不是真正的动态类型,但以下是如何使用它们。

假设您有以下界面。

type Locker interface {
  Lock()
  Unlock()
}
Run Code Online (Sandbox Code Playgroud)

这实际上是Lockerfromsync包。

现在,如果您创建两个结构体来实现 Locker 接口定义的函数。换句话说,如果您履行Locker合同,您将能够使用结构FooBar作为Locker接口。

type Foo struct {
  A string
}

func (f *Foo) String() string {
  return f.A
}

func (f *Foo) Lock() {
  // ...
}

func (f *Foo) Unlock() {
  // ...
}

type Bar struct {}

func (b *Bar) Lock() {
  // ...
}

func (b *Bar) Unlock() {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

因此,鉴于您给出的定义:

接口类型可以包含对实现该接口的任何类型的实例的引用(接口具有所谓的动态类型)

它可以翻译成:

Locker(接口)类型可以包含对实现其协定的任何类型的实例的引用(例如,Foo、Bar...)。

代码中的意思是:

var lock Locker

lock = &Foo{"Foo"} // We assign an instance of type Foo to a Locker var
lock.Lock() // We can call all functions defined by the interface Locker
lock.Unlock()
lock.String() // This won't work because the Locker interface does not define the String() function, even though Foo implements it. 

lock = &Bar{}
lock.Lock()
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我们可以看到变量lock保存了对不同类型的引用,但它并不是真正动态的,因为分配类型的条件lock是其类型符合约定Locker。该部分是在编译时定义的。

为什么它有用?

这篇文章将解释为什么界面比我有用。https://softwareengineering.stackexchange.com/questions/108240/why-are-interfaces-useful