golang any 之中的类型及 interface 接口

这篇具有很好参考价值的文章主要介绍了golang any 之中的类型及 interface 接口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在 golang 之中 any 类型,从字面意思上看是任意类型,这很类似我们在 C#、C++ 之中的任意指针类型 void*(原生),C# 之中诡异的 object。

any 是一个接口类型,其语法声明为:

// any is an alias for interface{} and is equivalent to interface{} in all ways.

type any = interface{}

即 interface{} 等于 any,这是一种类似 C++ 之中语法为:

using 别名 = 类型;

别名定义方式,C# 这块只允许为命名空间定义别名,就像在 C++ 使用 namespace 别名 = 命名空间; 类似这样子。

Golang 与 C/C++、C# 这样的语言是不同的,在 VC++ 之中微软提供了 __interface 关键字,将 C/C++ 混乱不堪的定义 Abstract class 为强行理解为 interface 行为给取缔,但可惜的是:它只被允许在 Microsoft VC++ 、CL 编译器上工作。

例如:

interface IFoo {
    void Say();
};

在 C++ 及 C# 之中,接口必须在具象类(Representational class)之中被显示派生才可以,它是基于对于 __vfptr 类虚函数表重写实现的。

当然与 Golang 相同,接口函数必须被具象类按照 “Function signature 函数签名” 实现才可以,但不同的是,Golang 之中不需要在 struct 之中声明派生具体的接口类型。

在 Golang 之中类型是否可以 “Covariations 协变” 为某个接口类型,只需要该类型实现,欲被协变的接口所需要的成员。

例如:

type IFoo interface {
	Say()
}

type FooImplement struct {
}

func (*FooImplement) Say() {
	fmt.Println("你好!")
}

func main() {
	var foo IFoo
	foo = &FooImplement{}

	foo.Say()
}

 举一反三:

type IFoo interface{}

type FooImplement struct{}

func (*FooImplement) Say() {
	fmt.Println("你好!")
}

func test_foo(foo IFoo) {

}

func test_any(v any) {
	test_foo(v)
}

func main() {
	foo := &FooImplement{}
	test_any(foo)
}

如上所示:

所以:当用户 interface 被定义为空集时,它与 interface {} 或者说 any 类型(别名)是等价的,可以无障碍的相互传递。

注意:

Golang 接口只可定义接口函数,但C#、VB.NET、C++ .NET 可以允许定义,如接口成员属性、成员事件等。

当 interface 接口类型想要 “Contravariants 逆变” 为具体类型的时候,这个过程人们可以想象为一种 unbox 指令拆箱的过程。

例如:

type IFoo interface {
	Say()
}

type FooImplement struct{}

func (*FooImplement) Say() {
	fmt.Println("你好!")
}

func test_foo(foo IFoo) {
	f, ok := foo.(*FooImplement)
	if ok {
		f.Say()
		fmt.Println("拆箱成功!")
	} else {
		fmt.Println("拆箱失败!")
	}
}

func main() {
	foo := &FooImplement{}
	test_foo(foo)
}

在 Golang 之中 any 类型是一个很奇怪的东西,如果我们声明某个函数为 ... any 可变参数类型(any)会发生一些很有意思的参数转发问题。

举个例子:

func implement_print_args(a ...any) {
	fmt.Println(a...)
}

func forward_print_args(a ...string) {
	implement_print_args(a...)
}

上述代码是无法编译通过的,从人类易于理解的角度来说,any 类型的可变参数,应该是可以接受任何类型的,这也应当包含 string 类型。

但奇怪的是 forward_print_args 函数,根本无法把自己的可变字符串类型参数 a,转发给 implement_print_args 函数。

这是因为,在 Golang 语言之中,any 的确可以等于任何类型,但在不等于它不存在限制,另外在 Golang 之中的可变参数是像 C# 语言之中使用一个 object[] 数组来模拟的可变参数。

人们稍需注意一点,Golang 并非是像 C/C++ 语言之中,真正意义上的可变参数,即根据函数调用协议(如 __cdecl、__stdcall、__fastcall、__thiscall、__pascal)及平台来决定那些参数压入到寄存器,如RDX、RCX、那些参数PUSH到线程栈空间之中。

public void PrintNumbers(params object[] numbers)
{
    foreach (var number in numbers)
    {
        Console.WriteLine(number);
    }
}

所以在 golang 之中,如果人们需要转发类型为 ... any 的可变参数列表,应当:

func implement_print_args(a ...any) {
	fmt.Println(a...)
}

func forward_print_args(a ...any) {
	implement_print_args(a...)
}

但这并不仅仅是 any,定义任何类型的可变参数,都应当按照上述形式来声明函数及参数签名。文章来源地址https://www.toymoban.com/news/detail-819082.html

到了这里,关于golang any 之中的类型及 interface 接口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【TypeScript】TS接口interface类型(三)

    一、前言 TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。这些方法都应该是抽象的,需要由具体的类去实现,然后第三方

    2024年02月14日
    浏览(43)
  • go 结构体 - 值类型、引用类型 - 结构体转json类型 - 指针类型的种类 - 结构体方法 - 继承 - 多态(interface接口) - 练习

    目录 一、结构体 1、python 与 go面向对象的实现: 2、初用GO中的结构体:(实例化一个值类型的数据(结构体)) 输出结果不同的三种方式  3、实例化一个引用类型的数据(结构体) 4、引用类型(指针类型) vs 值类型(两者的区别) 引用类型(指针类型) - 值类型内存拓扑图:

    2024年02月14日
    浏览(50)
  • Go语言入门7(interface 接口)

    ​接口类型是对其它类型行为的抽象和概括,因为接口类型不会和特定的实现细节绑定在一 起,通过这种抽象的方式我们可以让我们的函数更加灵活和更具有适应能力 可以包含0个或多个方法的签名 只定义方法的签名,不包含实现 实现接口不需要显式的声明,只需实现相应

    2023年04月13日
    浏览(65)
  • Scala的特质trait与java的interface接口的区别,以及Scala特质的自身类型和依赖注入

    Scala中的特质(trait)和Java中的接口(interface)在概念和使用上有一些区别: 默认实现:在Java中,接口只能定义方法的签名,而没有默认实现。而在Scala的特质中,除了可以定义方法签名外,还可以定义方法的具体实现。这样,在混入(mix in)特质的类中,可以直接使用特质

    2024年02月10日
    浏览(36)
  • Golang中接口类型详解与最佳实践(二)

    之前的文章《Golang中的interface(接口)详解与最佳实践》详细介绍了接口类型的定义、使用方法和最佳实践。接口类型使得编写可扩展、可维护和可复用的高质量代码变得更加容易。 还是使用之前文章的例子,例如声明了如下一个接口MyInterface: 这个接口定义了两个方法Method

    2024年02月03日
    浏览(36)
  • 解决:安装VisualAssistX 时,出现安装错误This extension is not installable on any currently installed

    注 :该问题是在新的win10操作系统上出现的,安装绿色免费版VC++6.0后,番茄助手失效。 一句话总结,“国产”的纯净系统+完整版VC++6.0搭建好框架(猜测),再安装绿色免费的VC和番茄即可。  有用的线索只有这一条。原地址:我只安装了VC6.0,在安装 visual assist x时提示thi

    2024年02月11日
    浏览(51)
  • Golang内置类型和函数及接口、Init函数和main函数

    1.1. 值类型: 1.2. 引用类型:(指针类型) Go 语言拥有一些不需要进行导入操作就可以使用的内置函数。它们有时可以针对不同的类型进行操作,例如:len、cap 和 append,或必须用于系统级的操作,例如:panic。因此,它们需要直接获得编译器的支持。 go语言中 init 函数用于包

    2024年01月25日
    浏览(33)
  • 【Golang】认识Go语言中基本的数据类型

    目录 整形 基本整型  特殊整型 浮点型 布尔型 字符型 字符串转义符  多行字符串 字符串的常用操作 复数 我们不论在学习什么语言中,我们都要去认识一下这个语言中的数据类型,当然学习Go也不例外,我们也要去认识一下其相关的数据类型,当然这些数据类型基本上是大

    2023年04月08日
    浏览(45)
  • 【Golang】Golang进阶系列教程--为什么 Go 不支持 []T 转换为 []interface

    在 Go 中,如果 interface{} 作为函数参数的话,是可以传任意参数的,然后通过类型断言来转换。 举个例子: 不管是传 int 还是 string,最终都能输出正确结果。 那么,既然是这样的话,我就有一个疑问了,拿出我举一反三的能力。是否可以将 []T 转换为 []interface 呢? 比如下面

    2024年02月15日
    浏览(66)
  • 100天精通Golang(基础入门篇)——第5天: Go语言中的数据类型学习

    🌷 博主 libin9iOak带您 Go to Golang Language.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批

    2024年02月08日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包