interface{} 的含义是什么?

本文介绍了interface{} 的含义是什么?的处理方法,对大家解决问题具有一定的参考价值

问题描述

我是接口的新手,并尝试通过 似乎指出了any作为 Go 1.18(2022 年第一季度)中 interface{} 的别名

Russ Cox 解释:

<块引用>

  1. 'any' 仅用于约束是泛型的每一篇文章中都会出现的一个细节——书籍、博客文章等等.如果我们认为我们最终可能会允许它,那么从一开始就允许它并避免使所有书面材料无效是有意义的.

  2. 'any' 仅用于约束是一种意外的删减,它降低了概念的通用性和正交性.说让我们拭目以待"很容易,但处方用途往往会产生比完全通用性更多的参差不齐的特征.我们也通过类型别名看到了这一点(谢天谢地,我们抵制了几乎所有提议的删减).

  3. 如果泛型中允许使用any"而不是非泛型代码,那么它可能会鼓励人们过度使用泛型,因为any"更好编写比 'interface{}' 时,真正应该考虑其他因素来决定是否使用泛型.

  4. 如果我们也允许 'any' 用于普通的非泛型用法,那么在代码中看到 interface{} 可以作为一种信号,表明代码早于泛型并且在后泛型世界中尚未被重新考虑.一些使用 interface{} 的代码应该使用泛型.其他代码应该继续使用接口.
    以一种或另一种方式重写它以删除文本interface{}"将使人们清楚地了解他们更新了什么和没有更新什么.(当然,出于向后兼容性的原因,一些可能更适合泛型的代码仍必须使用 interface{},但仍可以更新它以确认已考虑并做出决定.)>

该线程还包括关于接口{}的说明:

<块引用>

这不是一个特殊的设计,而是 Go 的类型声明语法的逻辑结果.

您可以使用具有多个方法的匿名接口:

func f(a interface{Foo(); Bar()}) {a.Foo()一间酒吧()}

类似于如何在需要类型的任何地方使用匿名结构:

func f(a struct{Foo int; Bar string}) {fmt.Println(a.Foo)fmt.Println(a.Bar)}

一个空接口恰好匹配所有类型,因为所有类型至少有零个方法.

如果您想保持一致/不想引入特殊情况,那么删除 interface{} 意味着从语言中删除所有界面功能.

I'm new to interfaces and trying to do SOAP request by github

I don't understand the meaning of

Msg interface{}

in this code:

type Envelope struct {
    Body `xml:"soap:"`
}

type Body struct {
    Msg interface{}
}

I've observed the same syntax in

fmt.Println

but don't understand what's being achieved by

interface{}

解决方案

You can refer to the article "How to use interfaces in Go" (based on "Russ Cox’s description of interfaces"):

What is an interface?

An interface is two things:

  • it is a set of methods,
  • but it is also a type

The interface{} type, the empty interface is the interface that has no methods.

Since there is no implements keyword, all types implement at least zero methods, and satisfying an interface is done automatically, all types satisfy the empty interface.
That means that if you write a function that takes an interface{} value as a parameter, you can supply that function with any value.

(That is what Msg represents in your question: any value)

func DoSomething(v interface{}) {
   // ...
}

Here’s where it gets confusing:

inside of the DoSomething function, what is v's type?

Beginner gophers are led to believe that "v is of any type", but that is wrong.
v is not of any type; it is of interface{} type.

When passing a value into the DoSomething function, the Go runtime will perform a type conversion (if necessary), and convert the value to an interface{} value.
All values have exactly one type at runtime, and v's one static type is interface{}.

An interface value is constructed of two words of data:

  • one word is used to point to a method table for the value’s underlying type,
  • and the other word is used to point to the actual data being held by that value.


Addendum: This is were Russ's article is quite complete regarding an interface structure:

type Stringer interface {
    String() string
}

Interface values are represented as a two-word pair giving a pointer to information about the type stored in the interface and a pointer to the associated data.
Assigning b to an interface value of type Stringer sets both words of the interface value.

The first word in the interface value points at what I call an interface table or itable (pronounced i-table; in the runtime sources, the C implementation name is Itab).
The itable begins with some metadata about the types involved and then becomes a list of function pointers.
Note that the itable corresponds to the interface type, not the dynamic type.
In terms of our example, the itable for Stringer holding type Binary lists the methods used to satisfy Stringer, which is just String: Binary's other methods (Get) make no appearance in the itable.

The second word in the interface value points at the actual data, in this case a copy of b.
The assignment var s Stringer = b makes a copy of b rather than point at b for the same reason that var c uint64 = b makes a copy: if b later changes, s and c are supposed to have the original value, not the new one.
Values stored in interfaces might be arbitrarily large, but only one word is dedicated to holding the value in the interface structure, so the assignment allocates a chunk of memory on the heap and records the pointer in the one-word slot.


Issue 33232 seems to point out to any as an alias to interface{} in Go 1.18 (Q1 2022)

Russ Cox explains:

  1. 'any' being only for constraints is a detail that will be in every writeup of generics - books, blog posts, and so on. If we think we are likely to allow it eventually, it makes sense to allow it from the start and avoid invalidating all that written material.

  2. 'any' being only for constraints is an unexpected cut-out that reduces generality and orthogonality of concepts. It's easy to say "let's just wait and see", but prescribing uses tends to create much more jagged features than full generality. We saw this with type aliases as well (and resisted almost all the proposed cut-outs, thankfully).

  3. If 'any' is allowed in generics but not non-generic code, then it might encourage people to overuse generics simply because 'any' is nicer to write than 'interface{}', when the decision about generics or not should really be made by considering other factors.

  4. If we allow 'any' for ordinary non-generic usage too, then seeing interface{} in code could serve as a kind of signal that the code predates generics and has not yet been reconsidered in the post-generics world. Some code using interface{} should use generics. Other code should continue to use interfaces.
    Rewriting it one way or another to remove the text 'interface{}' would give people a clear way to see what they'd updated and hadn't. (Of course, some code that might be better with generics must still use interface{} for backwards-compatibility reasons, but it can still be updated to confirm that the decision was considered and made.)

That thread also includes an explanation about interface{}:

It's not a special design, but a logical consequence of Go's type declaration syntax.

You can use anonymous interfaces with more than zero methods:

func f(a interface{Foo(); Bar()}) {
   a.Foo()
   a.Bar()
}

Analogous to how you can use anonymous structs anywhere a type is expected:

func f(a struct{Foo int; Bar string}) {
   fmt.Println(a.Foo)
   fmt.Println(a.Bar)
}

An empty interface just happens to match all types because all types have at least zero methods.

Removing interface{} would mean removing all interface functionality from the language if you want to stay consistent / don't want to introduce a special case.

这篇关于interface{} 的含义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2

admin_action_{$_REQUEST[‘action’]}

do_action( "admin_action_{$_REQUEST[‘action’]}" )动作钩子::在发送“Action”请求变量时激发。Action Hook: Fires when an ‘action’ request variable is sent.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$_REQUEST['action']引用从GET或POST请求派生的操作。源码(Source)更新版本源码位置使用被使用2.6.0 wp-admin/admin.php:...

日期:2020-09-02 17:44:16 浏览:1158

admin_footer-{$GLOBALS[‘hook_suffix’]}

do_action( "admin_footer-{$GLOBALS[‘hook_suffix’]}", string $hook_suffix )操作挂钩:在默认页脚脚本之后打印脚本或数据。Action Hook: Print scripts or data after the default footer scripts.目录锚点:#说明#参数#源码说明(Description)钩子名的动态部分,$GLOBALS['hook_suffix']引用当前页的全局钩子后缀。参数(Parameters)参数类...

日期:2020-09-02 17:44:20 浏览:1059

customize_save_{$this->id_data[‘base’]}

do_action( "customize_save_{$this-&gt;id_data[‘base’]}", WP_Customize_Setting $this )动作钩子::在调用WP_Customize_Setting::save()方法时激发。Action Hook: Fires when the WP_Customize_Setting::save() method is called.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_data...

日期:2020-08-15 15:47:24 浏览:798

customize_value_{$this->id_data[‘base’]}

apply_filters( "customize_value_{$this-&gt;id_data[‘base’]}", mixed $default )过滤器::过滤未作为主题模式或选项处理的自定义设置值。Filter Hook: Filter a Customize setting value not handled as a theme_mod or option.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_date['base'],指的是设置...

日期:2020-08-15 15:47:24 浏览:884

get_comment_author_url

过滤钩子:过滤评论作者的URL。Filter Hook: Filters the comment author’s URL.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/comment-template.php:32610...

日期:2020-08-10 23:06:14 浏览:925

network_admin_edit_{$_GET[‘action’]}

do_action( "network_admin_edit_{$_GET[‘action’]}" )操作挂钩:启动请求的处理程序操作。Action Hook: Fires the requested handler action.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$u GET['action']引用请求的操作的名称。源码(Source)更新版本源码位置使用被使用3.1.0 wp-admin/network/edit.php:3600...

日期:2020-08-02 09:56:09 浏览:870

network_sites_updated_message_{$_GET[‘updated’]}

apply_filters( "network_sites_updated_message_{$_GET[‘updated’]}", string $msg )筛选器挂钩:在网络管理中筛选特定的非默认站点更新消息。Filter Hook: Filters a specific, non-default site-updated message in the Network admin.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分$_GET['updated']引用了非默认的...

日期:2020-08-02 09:56:03 浏览:854

pre_wp_is_site_initialized

过滤器::过滤在访问数据库之前是否初始化站点的检查。Filter Hook: Filters the check for whether a site is initialized before the database is accessed.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/ms-site.php:93910...

日期:2020-07-29 10:15:38 浏览:825

WordPress 的SEO 教学:如何在网站中加入关键字(Meta Keywords)与Meta 描述(Meta Description)?

你想在WordPress 中添加关键字和meta 描述吗?关键字和meta 描述使你能够提高网站的SEO。在本文中,我们将向你展示如何在WordPress 中正确添加关键字和meta 描述。为什么要在WordPress 中添加关键字和Meta 描述?关键字和说明让搜寻引擎更了解您的帖子和页面的内容。关键词是人们寻找您发布的内容时,可能会搜索的重要词语或片语。而Meta Description则是对你的页面和文章的简要描述。如果你想要了解更多关于中继标签的资讯,可以参考Google的说明。Meta 关键字和描...

日期:2020-10-03 21:18:25 浏览:1688

谷歌的SEO是什么

SEO (Search Engine Optimization)中文是搜寻引擎最佳化,意思近于「关键字自然排序」、「网站排名优化」。简言之,SEO是以搜索引擎(如Google、Bing)为曝光媒体的行销手法。例如搜寻「wordpress教学」,会看到本站的「WordPress教学:12个课程…」排行Google第一:关键字:wordpress教学、wordpress课程…若搜寻「网站架设」,则会看到另一个网页排名第1:关键字:网站架设、架站…以上两个网页,每月从搜寻引擎导入自然流量,达2万4千:每月「有机搜...

日期:2020-10-30 17:23:57 浏览:1294