首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Go接口中,“动态类型”是什么意思?

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

Stack Overflow用户
提问于 2015-10-26 02:04:47
回答 3查看 10.4K关注 0票数 9

前进之路: Go编程语言(Ivo Balbaert)的详细介绍包含了这句话,我不太明白:

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

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

EN

回答 3

Stack Overflow用户

发布于 2015-10-26 11:50:45

假设您有一个接口:

代码语言:javascript
运行
复制
type I interface{ F() }

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

代码语言:javascript
运行
复制
type S struct{}
func (S) F() { }

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

然后:

代码语言:javascript
运行
复制
var x I
x = S{}

现在x的静态类型是I,它的动态类型是S

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

代码语言:javascript
运行
复制
x = T{}

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

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

票数 10
EN

Stack Overflow用户

发布于 2015-10-26 08:54:25

定义

接口具有所谓的动态类型。

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

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

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

来源

示例

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

假设您有以下接口。

代码语言:javascript
运行
复制
type Locker interface {
  Lock()
  Unlock()
}

这实际上是来自Lockersync包。

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

代码语言:javascript
运行
复制
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() {
  // ...
}

因此,根据你给出的定义:

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

可以将其翻译为:

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

在法典中,这意味着:

代码语言:javascript
运行
复制
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()

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

为什么有用?

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

票数 3
EN

Stack Overflow用户

发布于 2015-10-27 04:23:29

每个变量都有一个类型。该类型要么是静态类型(int、string、bool、map、struct、片等),要么是接口类型。

接口可以由任何静态类型(通常是别名类型)实现。

接口类型的变量实际上存储在两个部分中。第一部分是基础静态类型的符号名。第二部分是静态类型的数据。

因此,如果一个变量声明为接口类型,这意味着它的类型是动态的,因为底层类型最终可能是实现接口的任何静态类型。

通常,此模式的有用性在于从某些共享行为中定义一类类型的扩展行为。这样,您就可以在任何特定情况下封装您所关心的功能,而不是担心给定类型的细节。例如,任何读取器都可以读取,一旦您决定有一个读取器,您就不需要担心底层类型可能具有的所有其他方法,这意味着您可以很容易地定义一个使用任何读取器的函数。

这接近于多态,并且分享了大部分好处。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33337403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档