Go 语言中的空接口(推荐)

在自己学习 Golang 的这段时间里,我写了详细的学习笔记放在我的个人微信公众号 《Go编程时光》,对于 Go 语言,我也算是个初学者,因此写的东西应该会比较适合刚接触的同学,如果你也是刚学习 Go 语言,不防关注一下,一起学习,一起成长。

我的在线博客:http://golang.iswbm.com
我的 Github:github.com/iswbm/GolangCodingTime

1. 什么是空接口?

空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法口,也因此,我们可以说所有类型都至少实现了空接口。

type empty_iface interface {
}

每一个接口都包含两个属性,一个是值,一个是类型。

而对于空接口来说,这两者都是 nil,可以使用 fmt 来验证一下

package main

import (
	"fmt"
)

func main() {
	var i interface{}
	fmt.Printf("type: %T, value: %v", i, i)
}

输出如下

type: <nil>, value: <nil>

2. 如何使用空接口?

第一,通常我们会直接使用 interface{} 作为类型声明一个实例,而这个实例可以承载任意类型的值。

package main

import (
	"fmt"
)

func main() {
	// 声明一个空接口实例
	var i interface{}

	// 存 int 没有问题
	i = 1
	fmt.Println(i)

	// 存字符串也没有问题
	i = "hello"
	fmt.Println(i)

	// 存布尔值也没有问题
	i = false
	fmt.Println(i)
}

第二,如果想让你的函数可以接收任意类型的值 ,也可以使用空接口

接收一个任意类型的值 示例

package main

import (
	"fmt"
)

func myfunc(iface interface{}){
	fmt.Println(iface)
}

func main() {
	a := 10
	b := "hello"
	c := true

	myfunc(a)
	myfunc(b)
	myfunc(c)
}

接收任意个任意类型的值 示例

package main

import (
	"fmt"
)

func myfunc(ifaces ...interface{}){
	for _,iface := range ifaces{
		fmt.Println(iface)
	}
}

func main() {
	a := 10
	b := "hello"
	c := true

	myfunc(a, b, c)
}

第三,你也定义一个可以接收任意类型的 array、slice、map、strcut,例如这边定义一个切片

package main

import "fmt"

func main() {
 any := make([]interface{}, 5)
 any[0] = 11
 any[1] = "hello world"
 any[2] = []int{11, 22, 33, 44}
 for _, value := range any {
 fmt.Println(value)
 }
}

3. 空接口几个要注意的坑

坑1:空接口可以承载任意值,但不代表任意类型就可以承接空接口类型的值

从实现的角度看,任何类型的值都满足空接口。因此空接口类型可以保存任何值,也可以从空接口中取出原值。

但要是你把一个空接口类型的对象,再赋值给一个固定类型(比如 int, string等类型)的对象赋值,是会报错的。

package main

func main() {
	// 声明a变量, 类型int, 初始值为1
	var a int = 1

	// 声明i变量, 类型为interface{}, 初始值为a, 此时i的值变为1
	var i interface{} = a

	// 声明b变量, 尝试赋值i
	var b int = i
}

这个报错,它就好比可以放进行礼箱的东西,肯定能放到集装箱里,但是反过来,能放到集装箱的东西就不一定能放到行礼箱了,在 Go 里就直接禁止了这种反向操作。(声明:底层原理肯定还另有其因,但对于新手来说,这样解释也许会容易理解一些。)

.\main.go:11:6: cannot use i (type interface {}) as type int in assignment: need type assertion

坑2::当空接口承载数组和切片后,该对象无法再进行切片

package main

import "fmt"

func main() {
	sli := []int{2, 3, 5, 7, 11, 13}

	var i interface{}
	i = sli

	g := i[1:3]
	fmt.Println(g)
}

执行会报错。

.\main.go:11:8: cannot slice i (type interface {})

坑3:当你使用空接口来接收任意类型的参数时,它的静态类型是 interface{},但动态类型(是 int,string 还是其他类型)我们并不知道,因此需要使用类型断言。

package main

import (
	"fmt"
)

func myfunc(i interface{}) {

	switch i.(type) {
	case int:
		fmt.Println("参数的类型是 int")
	case string:
		fmt.Println("参数的类型是 string")
	}
}

func main() {
	a := 10
	b := "hello"
	myfunc(a)
	myfunc(b)
}

输出如下

参数的类型是 int
参数的类型是 string

总结

到此这篇关于Go 语言中的空接口的文章就介绍到这了,更多相关go 语言空接口内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python采用django框架实现支付宝即时到帐接口

    因工作需要研究了支付宝即时到帐接口,并成功应用到网站上,把过程拿出来分享. 即时到帐只是支付宝众多商家服务中的一个,表示客户付款,客户用支付宝付款,支付宝收到款项后,马上通知你,并且此笔款项与交易脱离关系,商家可以马上使用. 即时到帐只对企业客户服务,注册成功企业账号以后,申请签约即时到帐产品,大约3-5个工作日后,签约成功,可以马上进入集成产品阶段. 这个是支付宝提供的接口,有asp,c#,java,php四种语言的,每种语言提供GBK和UTF-8两种方案.另带一份支付宝的文档,这份文档我感觉

  • Go语言服务器开发实现最简单HTTP的GET与POST接口

    本文实例讲述了Go语言服务器开发实现最简单HTTP的GET与POST接口.分享给大家供大家参考.具体分析如下: Go语言提供了http包,可以很轻松的开发http接口.以下为示例代码: 复制代码 代码如下: package webserver    import (      "encoding/json"      "fmt"      "net/http"      "time"  )    func WebServerB

  • Google PR查询接口checksum新算法第1/2页

    取而代之的是一大段"In your email, please send us the entire code displayed below"之类的Google terms_of_service错误提示信息.看来是原先的接口已经失效了. 但我装在Firefox工具栏的扩展插件SearchStatus仍然能够正常解析出每个受访页的PR值,找到 SearchStatus 的插件包解开来看源码,果然是使用了不一样的验证码生成算法,在原先的 checksum 生成之后,还需要再进行一次计算,

  • 利用google提供的API(JavaScript接口)获取网站访问者IP地理位置的代码详解

    首先引入JavaScript API文件 <script type="text/javascript" src="http://j.maxmind.com/app/geoip.js"></script> 此API提供的接口共有6个,geoip_country_code(){国家代码},geoip_country_ name(){国家名称},geoip_city() {城市名称},geoip_region(){地区代码},geoip_latit

  • Go语言中的方法、接口和嵌入类型详解

    概述 在 Go 语言中,如果一个结构体和一个嵌入字段同时实现了相同的接口会发生什么呢?我们猜一下,可能有两个问题: 1.编译器会因为我们同时有两个接口实现而报错吗? 2.如果编译器接受这样的定义,那么当接口调用时编译器要怎么确定该使用哪个实现? 在写了一些测试代码并认真深入的读了一下标准之后,我发现了一些有意思的东西,而且觉得很有必要分享出来,那么让我们先从 Go 语言中的方法开始说起. 方法 Go 语言中同时有函数和方法.一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的

  • 浅谈Go语言中的结构体struct & 接口Interface & 反射

    结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struct类型理解为类,可以定义方法,和函数定义有些许区别: struct类型是值类型. struct定义 type User struct { Name string Age int32 mess string } var user User var user1 *User = &User{} var user2 *User = new(User) struct使用 下面示例中user1和

  • Go 语言中的空接口(推荐)

    在自己学习 Golang 的这段时间里,我写了详细的学习笔记放在我的个人微信公众号 <Go编程时光>,对于 Go 语言,我也算是个初学者,因此写的东西应该会比较适合刚接触的同学,如果你也是刚学习 Go 语言,不防关注一下,一起学习,一起成长. 我的在线博客:http://golang.iswbm.com 我的 Github:github.com/iswbm/GolangCodingTime 1. 什么是空接口? 空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法口,也因此

  • golang中的空接口使用详解

    1.空接口 Golang 中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口.空接口表示,没有任何约束,因此任何类型变量都可以实现空接口.空接口在实际项目中用的是非常多的,用空接口可以表示任意数据类型 func main() { // 定义一个空接口 x, x 变量可以接收任意的数据类型 var x interface{} s := "你好 golang" x = s fmt.Printf("type:%T value:%v\n", x, x) i :=

  • 如何在python中实现capl语言里的回调函数(推荐)

    CAPL:回调函数 CAPL是一种程序语言,其中程序块的执行由事件控制. 这些程序块被称为事件程序.在事件程序中定义的程序代码在事件发生时执行.换句话说,事件程序就是事件函数,当事件函数关联的事件被触发时,会自动执行此事件函数函数体.事件函数也称为回调函数 事件函数的标志就是关键字on,比如: on key 表示当键盘按下小写字母a时触发此事件函数执行 on message 表示当接收到消息时触发此事件函数执行 on start 表示当canoe软件运行时触发此事件函数执行 on sysvar

  • 一文带你了解Go语言中接口的使用

    目录 接口 接口的实现 接口类型变量 空接口 类型断言 类型断言变种 type switch 小结 接口 在 Go 语言中,接口是一种抽象的类型,是一组方法的集合.接口存在的目的是定义规范,而规范的细节由其他对象去实现.我们来看一个例子: import "fmt" type Person struct { Name string } func main() { person := Person{Name: "cmy"} fmt.Println(person) //

  • Go 语言中关于接口的三个

    我的在线博客:http://golang.iswbm.com 我的 Github:github.com/iswbm/GolangCodingTime 1. 对方法的调用限制 接口是一组固定的方法集,由于静态类型的限制,接口变量有时仅能调用其中特定的一些方法. 请看下面这段代码 package main import "fmt" type Phone interface { call() } type iPhone struct { name string } func (phone i

  • Golang空接口与类型断言的实现

    目录 空接口 定义 使用场景 空接口几个要注意的坑 类型断言 Go语言中类型断言的两种语法 类型断言配合 switch 使用 空接口 定义 空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法口,也因此,我们可以说所有类型都至少实现了空接口. type test interface { } 每一个接口都包含两个属性,一个是值,一个是类型. var i interface{} fmt.Printf("类型:%T----值:%v\n", i, i) //类型:<n

  • 详解如何让Go语言中的反射加快

    目录 切入点案例 反射基本版 优化一:加入缓存策略 优化二:利用字段偏移量 优化三:更改缓存 key 类型 优化四:引入描述符 总结 最近读到一篇关于 Go 反射的文章,作者通过反射给结构体填充字段值的案例,充分利用 Go 的各种内在机理,逐步探讨让代码运行得更快的姿势. 文章(原文地址:https://philpearl.github.io/post/aintnecessarilyslow/)非常有学习价值,故翻译整理了下来. 不要使用反射,除非你真的需要.但是当你不使用反射时,不要认为这是因

  • 十个示例带你深入了解Go语言中的接口

    1.空接口既然可以存储任意类型的值,那么从空接口获取到的值是否可以直接使用?看下面栗子 package main import (  "fmt" ) var a interface{} var b interface{} func main() {  a = 1024  b = 100  res := a + b  fmt.Println(res) } 报错: invalid operation: operator + not defined on a (variable of typ

  • Go语言中更优雅的错误处理

    从现状谈起 Go语言受到诟病最多的一项就是其错误处理机制.如果显式地检查和处理每个error,这恐怕的确会让人望而却步.下面我们将给大家介绍Go语言中如何更优雅的错误处理. Golang 中的错误处理原则,开发者曾经之前专门发布了几篇文章( Error handling and Go和 Defer, Panic, and Recover.Errors are values )介绍.分别介绍了 Golang 中处理一般预知到的错误与遇到崩溃时的错误处理机制. 一般情况下,我们还是以官方博客中的错误

随机推荐