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,然后想要带个报 ...
随机推荐
- unicode和unicode编码
unicode编码是什么? 这其实是两个问题,unicode 是什么什么?unicode是怎样编码的? What is Unicode? Unicode provides a unique numbe ...
- Linux-Centos7学习笔记
镜像下载.域名解析.时间同步请点击阿里云开源镜像站 下载.安装与配置 下载 下载Centos镜像,网站见参考 点击大的版本,例如7,再选择isos进行下载 安装 这里使用的VMware 12 Pro, ...
- 装饰器property的简单运用
property函数:在类中使用,将类中的方法伪装成一个属性 使用方法:在函数,方法,类的上面一行直接@装饰器的名字 装饰器的分类: 装饰器函数 装饰器方法:property 装饰类 class St ...
- S7-1200在博途V16中新建数据块(DB)
硬件环境: S7-1200 CPU V4.4(6ES7 212-1AE40-0XB0) 软件环境: (1)Windows 10 Professional SP1 64位 (2)STEP7 V16 SP ...
- 七天接手react项目 系列 —— 尾篇(antd 和 mobx)
其他章节请看: 七天接手react项目 系列 尾篇 前面我们依次学习了 react 基础知识.react 脚手架创建项目.react 路由,已经花费了不少时间,但距离接手 spug_web 项目还有一 ...
- 基于JDK的动态代理原理分析
基于JDK的动态代理原理分析 这篇文章解决三个问题: What 动态代理是什么 How 动态代理怎么用 Why 动态代理的原理 动态代理是什么? 动态代理是代理模式的一种具体实现,是指在程序运行期间, ...
- session监听器和Attribute监听器
session监听器 有一个web项目,每次一个新的浏览器链接,都会走下面SessionListerenr 方法,该技术可用于网站当前用户的统计 package com.cisst.controlle ...
- 为什么 char 数组比 Java 中的 String 更适合存储密码?
另一个基于 String 的棘手 Java 问题,相信我只有很少的 Java 程序员可以正确回答这个问题.这是一个真正艰难的核心Java面试问题,并且需要对 String 的扎实知识才能回答这个问题. ...
- C# 如何让new 出来的form显示在最外层?
/// <summary> /// 显示比对不同点的位置 /// </summary> public void showDiffImage() { //在此处弹出不一样图 Bi ...
- memcached 与 redis 的区别?
1.Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储.而 memcache 只支持简单数据类型,需要客户端自己处理复 杂对象 2.R ...