golang语言 []interface{}和interface{}
文章目录
- golang语言 []interface{}
- interface(接口)
- interface应用场景
- interface{} 空接口
- []interface{}
- golang中为什么[]string 不能直接转换[]interface{}
- 工作中遇到问题整理
- interface{} 类型赋值其他变量报错 cannot use variable (type interface {}) as type int in assignment: need type assertion
- 参考
golang语言 []interface{}
interface(接口)
interface(接口)是golang最重要的特性之一,Interface类型可以定义一组方法,但是这些不需要实现。
请注意:此处限定是一组方法,既然是方法,就不能是变量;而且是一组,表明可以有多个方法。
interface是为实现多态功能,多态是指代码可以根据类型的具体实现采取不同行为的能力。如果一个类型实现了某个接口,所有使用这个接口的地方,都可以支持这种类型的值。
Go语言里面设计最精妙的应该算interface,它让面向对象,内容组织实现非常的方便。
interface应用场景
类型转换
实现多态功能
interface{} 空接口
在Goland中有一种特殊类型:interface{} ,空接口。go中其他的类型都是没有{}的, 只有interface{}有。
interface{} 类型是没有方法的接口。由于没有 implements 关键字,所以所有类型都至少实现了 0 个方法,所以 所有类型都实现了空接口。这意味着,如果编写一个函数以 interface{} 值作为参数,那么可以为该函数提供任何值,并且,[]interface{}在golang中也可以认为是interface{}。
总结:万能类型(interface{})很神奇,就像 C 里面的 void*、 像 Java 中的 Object 类型。任何变量都可以赋值给interface{}类型的变量。
工作中,当我们使用 interface{} 作为函数形参时, 我们可以传入任何类型作为参数,因为任何类型都实现了 interface{} 接口。
[]interface{}
当我们声明 interface{} 数组的时候,事情就变的不一样了
func Foo(a []interface{}) {}Foo([]int{1, 2, 3}) // 报错
Foo([]string{"1", "2", "3"}) // 报错
按照本身的设想,这里应该不管什么样的数组都可以作为参数传入,可是结果却恰恰相反:我们只能传入类型为 []interface{} 的元素。
既然interface{}能代表任意类型,那么interface{}的切片为什么不能代表任意类型的切片呢?
因为 []interface{} 类型变量拥有特定的内存结构。
每个 interface{} 占两个字(32 位机器一个字是 32 位,64 位机器一个字是 64 位)。其中,一个字用于存放 interface{} 真正传入的数据的类型;另一个字用于指向实际的数据。
type eface struct {_type *_typedata unsafe.Pointer
}
对于[]interface{}类型的变量来说,切片里的每个元素可以存储不同类型的变量,例如
func main() {var a = make([]interface{}, 0)a = append(a, []int{123, 456})a = append(a, []string{"abc", "ijk"})fmt.Println(a) // [[123 456] [abc ijk]]
}
长度为 n 的 []Type 切片的背后数据分配的大小为为 n * sizeof(Type) 字 长。
自然就不可以将 []int 类型作为 []interface{} 类型进行传递,只能自己写个循环将每一个 Type 都转化为 interface{}。
即使切片里存的数据都是某个特定的类型,也不能通过类型断定来强制转换,因为底层的数据存储结构不同
func main() {a := method()_, ok := a.([]int)fmt.Println(ok) // false
}func method() interface{} {var a = make([]interface{}, 0)a = append(a, []int{123, 456})a = append(a, []int{789, 111})return a
}
Each interface{} takes up two words (one word for the type of what is contained, the other word for either the contained data or a pointer to it). As a consequence, a slice with length N and with type []interface{} is backed by a chunk of data that is N*2 words long.
This is different than the chunk of data backing a slice with type []MyType and the same length. Its chunk of data will be N*sizeof(MyType) words long.
The result is that you cannot quickly assign something of type []MyType to something of type []interface{}; the data behind them just look different.
每个接口{}占用两个单词(一个单词,用于包含的类型,另一个单词包含数据或指针的单词)。结果,具有长度n和类型[]接口{}的切片是由一块n*2个单词长的数据支持。
这与以[] mytype类型和相同长度的类型备份的数据片段不同。它的数据很多将是n*sizeof(mytype)单词。
结果是您无法快速将某些类型[] mytype分配给类型[] interface {}的东西;它们背后的数据看起来不同。
总结:interface slice 与 万能类型 empty interface 是不一样的,可以直接将任何类型的值传给万能类型,但是不能将任何类型的 slice 直接传给 interface slice,因为 interface slice 并不是万能类型,只是里面装的东西是万能类型,所以反过来你也不能直接将 interface slice 强制转换成特定类型的 slice。
golang中为什么[]string 不能直接转换[]interface{}
golang中为什么[]string 不能直接转换[]interface{}
原文链接
工作中遇到问题整理
interface{} 类型赋值其他变量报错 cannot use variable (type interface {}) as type int in assignment: need type assertion
package mainimport "fmt"func main() {var tmp interface{}var i inttmp = 1i = tmpfmt.Println(i)
}
报错的代码行是 i = tmp 那行。
可见,interface{} 类型可以被任何类型赋值,但是 interface{} 不可以直接给其他类型赋值。
解决方法
//i = tmp
i = tmp.(int)
参考
InterfaceSlice
参考URL: https://github.com/golang/go/wiki/InterfaceSlice
interface{} 与 []interface{}
参考URL: https://blog.csdn.net/lwldcr/article/details/77370948
Golang 的 []interface{} 类型
参考URL: https://www.cnblogs.com/xhyccc/p/15807778.html
理解Golang中的[]interface{}和interface{}
参考URL: https://blog.csdn.net/qq_39220627/article/details/119191249
golang语言 []interface{}和interface{}相关推荐
- Golang面向API编程-interface(接口)
Golang面向API编程-interface(接口) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Golang并不是一种典型的面向对象编程(Object Oriented Pr ...
- Go语言-switch case | switch中判断多个值、interface conversion: interface {} is float64, not int
文章目录 Go语言-switch case 背景 switch case Golang中switch的特殊用法--fallthrough go语言switch中判断多个值 Type Switch,判断 ...
- 深度解密Go语言之关于 interface 的 10 个问题
12这次文章依然很长,基本上涵盖了 interface 的方方面面,有例子,有源码分析,有汇编分析,前前后后写了 20 多天.洋洋洒洒,长篇大论,依然有些东西没有涉及到,比如文章里没有写到反射,当然, ...
- go 调用c 编译器找不到方法_深度解密Go语言之关于 interface 的10个问题
这次文章依然很长,基本上涵盖了 interface 的方方面面,有例子,有源码分析,有汇编分析,前前后后写了 20 多天.洋洋洒洒,长篇大论,依然有些东西没有涉及到,比如文章里没有写到反射,当然,后面 ...
- log包在Golang语言的标准库中是怎么使用的?
Golang 语言的标准库中提供了一个简单的 log 日志包,它不仅提供了很多函数,还定义了一个包含很多方法的类型 Logger.但是它也有缺点,比如不支持区分日志级别,不支持日志文件切割等. 01. ...
- 语言与golang语言运行速度_Golang语言情怀第3期 Go 语言数据类型
本期给大家聊下Go语言的数据类型有哪些,数据类型用于声明函数和变量.数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言 ...
- golang语言编译的二进制可执行文件为什么比 C 语言大(转载)
最近一位朋友问我"为什么同样的hello world 入门程序"为什么golang编译出来的二进制文件,比 C 大,而且大很多.我做了个测试,来分析这个问题.C 语言的hello ...
- 算法和数据结构(golang语言实现)
算法和数据结构(golang语言实现) 第1节 选择.冒泡.插入.复杂度 选择排序 选择排序 时间复杂度为O(N^2) 额外空间复杂度O(1) 过程: arr[0-N-1]范围上,找到最小值所在的位置 ...
- panic: interface conversion: interface {} is nil, not chan *sarama.ProducerError
使用golang kafka sarama 包时,遇到如下问题: 高并发情况下使用同步sync producer,偶尔遇到crash: panic: interface conversion: int ...
最新文章
- Python20-Day05
- sqlalchemy.orm 多条件查询更新
- MSSql2005: Cube 和 RollUp 的区别
- 直接输出代码_C语言入门 | 优秀代码(四)A—F
- iphone练习之手势识别(双击、捏、旋转、拖动、划动、长按)UITapGestureRecognizer...
- Java网络编程2---Socket-TCP编程
- 记IOS8中碰到的一个JS bug
- 红米7正式首发:4GB+64GB版本售价999元
- keepalived mysql双主架构图_MySQL数据库架构和同步复制流程
- 晶体(谐振器)震荡电路与参数
- mysql 覆盖式索引_【MySQL】性能优化之 覆盖索引
- linux scp 使用简单说明
- 废旧手机变身服务器,打造私人云盘
- 使用阿里云ESC服务器的时候域名解析成功为何打不开网站?
- 6.4.2.时序逻辑测试模块
- UOS主动安全防护计划(UAPP)正式发布,共建信创基础软件平台安全底座
- android中热更新模式,Android热更新与开启Instant Run
- 商用清洁机器人:科沃斯“破圈”、高仙机器人“纵深”
- 友盟第三方QQ登录分享
- 【HDU】5238 Calculator 【中国剩余定理+线段树】