go interface{}使用
先上代码
func In(haystack []interface{}, needle interface{}) (bool, error) {
sVal := reflect.ValueOf(haystack)
kind := sVal.Kind()
if kind == reflect.Slice || kind == reflect.Array {
for i := 0; i < sVal.Len(); i++ {
if sVal.Index(i).Interface() == needle {
return true, nil
}
}
return false, nil
}
return false, fmt.Errorf("UnSupportType")
}
func test() {
a := []int{1,2}
b := 3
flag, err := In(a,b) // error, cannot user 'a'(type []int) as type []interface{}
}
为什么会报错?
因为空接口拥有两个指针,内存布局上会占用两个机器字长。
对于长度为n的空接口切片而言,它的每个元素都是以2机器字长为单位的连续空间,因此总共会占用 2n个机器字长的空间。然而对于普通的切片,[]int它的每个元素都是 int 类型的,由于 []int 和 []interface{} 内存布局不同,所以不能直接将 []int 作为 []interface{};
Introduction
Given that you can assign a variable of any type to an interface{}, often people will try code like the following.
var dataSlice []int = foo()
var interfaceSlice []interface{} = dataSlice
This gets the error
cannot use dataSlice (type []int) as type []interface { } in assignment
The question then, "Why can't I assign any slice to an []interface{}, when I can assign any type to an interface{}?"
Why?
There are two main reasons for this.
The first is that a variable with type []interface{} is not an interface! It is a slice whose element type happens to be interface{}. But even given this, one might say that the meaning is clear.
Well, is it? A variable with type []interface{} has a specific memory layout, known at compile time.
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.
What can I do instead?
It depends on what you wanted to do in the first place.
If you want a container for an arbitrary array type, and you plan on changing back to the original type before doing any indexing operations, you can just use an interface{}. The code will be generic (if not compile-time type-safe) and fast.
If you really want a []interface{} because you'll be doing indexing before converting back, or you are using a particular interface type and you want to use its methods, you will have to make a copy of the slice.
var dataSlice []int = foo()
var interfaceSlice []interface{} = make([]interface{}, len(dataSlice))
for i, d := range dataSlice {
interfaceSlice[i] = d
}
go interface{}使用的更多相关文章
- angular2系列教程(七)Injectable、Promise、Interface、使用服务
今天我们要讲的ng2的service这个概念,和ng1一样,service通常用于发送http请求,但其实你可以在里面封装任何你想封装的方法,有时候控制器之间的通讯也是依靠service来完成的,让我 ...
- 接口--interface
“interface”(接口)关键字使抽象的概念更深入了一层.我们可将其想象为一个“纯”抽象类.它允许创建者规定一个类的基本形式:方法名.自变量列表以及返回类型,但不规定方法主体.接口也包含了基本数据 ...
- Configure a bridge interface over a VLAN tagged bonded interface
SOLUTION VERIFIED February 5 2014 KB340153 Environment Red Hat Enterprise Linux 6 (All Versions) Red ...
- Create a bridge using a tagged vlan (8021.q) interface
SOLUTION VERIFIED April 27 2013 KB26727 Environment Red Hat Enterprise Linux 5 Red Hat Enterprise Li ...
- Configure a bridged network interface for KVM using RHEL 5.4 or later?
environment Red Hat Enterprise Linux 5.4 or later Red Hat Enterprise Linux 6.0 or later KVM virtual ...
- Set up VLAN (802.1q) tagging on a network interface?
SOLUTION VERIFIED October 13 2015 KB39674 KB741413 environment Red Hat Enterprise Linux 4 Red Hat En ...
- 谨慎使用Marker Interface
之所以写这篇文章,源自于组内的一些技术讨论.实际上,Effective Java的Item 37已经详细地讨论了Marker Interface.但是从整个Item的角度来看,其对于Marker In ...
- 浅析Go语言的Interface机制
前几日一朋友在学GO,问了我一些interface机制的问题.试着解释发现自己也不是太清楚,所以今天下午特意查了资料和阅读GO的源码(基于go1.4),整理出了此文.如果有错误的地方还望指正. GO语 ...
- 如何设计一门语言(七)——闭包、lambda和interface
人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...
- abstract与interface之房祖名张默版
最近把java基础知识拿出来看看,看到abstract与interface的时候,觉得有点模糊,好像面试官也喜欢问这个问题.我在百度了查了好长时间,觉得讲算比较清楚的是那篇讲 Door,然后想要带个报 ...
随机推荐
- “exec: "ssh-keygen": executable file not found in %PATH%” 问题解决
set PATH=%PATH%;C:\Program Files (x86)\Git\bin bash start.sh 将以上内容保存为start.bat,放在boot2docker根目录下,管理员 ...
- Redis数据结构详解(1)-redis中的字符串(SDS)
前提知识 我们先从百科上摘下Redis的解释: Redis是一个使用ANSI C编写的开源.支持网络.基于内存.分布式.可选持久性的键值对存储数据库. (不用过多在意ANSI,它只是一个标准,你可以理 ...
- Mysql之B+树索引实战
索引代价 空间上的代价 一个索引都对应一棵B+树,树中每一个节点都是一个数据页,一个页默认会占用16KB的存储空间,所以一个索引也是会占用磁盘空间的. 时间上的代价 索引是对数据的排序,那么当对表中的 ...
- 为MySQL加锁?
在日常操作中,UPDATE.INSERT.DELETE InnoDB会自动给涉及的数据集加排他锁,一般的 SELECT 一般是不加任何锁的.我们可以使用以下方式显示的为 SELECT 加锁. 共享锁: ...
- @Controller 注解?
该注解表明该类扮演控制器的角色,Spring不需要你继承任何其他控制器基类或引用Servlet API.
- 部署新项目自动对数据库进行migrate和让用户收到创建用户/超级用户信息
当项目中的models有数据表的时候,普通做法是用docke exec -it hello_web_1 bash,进入容器进行migrate,但是我们想要容器一启动就自动创建数据表,可以修改docke ...
- 面试问题之数据结构与算法:map与unordered_map
转载于:https://blog.csdn.net/u011475134/article/details/75810085 map map是STL的一个关联容器,它提供一对一数据处理能力.map内部自 ...
- 如何给 Spring 容器提供配置元数据?
这里有三种重要的方法给 Spring 容器提供配置元数据. XML 配置文件. 基于注解的配置. 基于 java 的配置.
- ReentrantLock 源代码之我见
ReentrantLock,英文意思是可重入锁.从实际代码实现来说,ReentrantLock也是互斥锁(Node.EXCLUSIVE).与互斥锁对应的的,还有共享锁Node.SHARED Reent ...
- [转载] Link prefetch
本来想翻译的但是有人翻译了,还是转过来吧.原文<HTML5 Link Prefetching>,译文<使用HTML5的页面资源预加载(Link prefetch)功能加速你的页面加载 ...