先上代码

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{}使用的更多相关文章

  1. angular2系列教程(七)Injectable、Promise、Interface、使用服务

    今天我们要讲的ng2的service这个概念,和ng1一样,service通常用于发送http请求,但其实你可以在里面封装任何你想封装的方法,有时候控制器之间的通讯也是依靠service来完成的,让我 ...

  2. 接口--interface

    “interface”(接口)关键字使抽象的概念更深入了一层.我们可将其想象为一个“纯”抽象类.它允许创建者规定一个类的基本形式:方法名.自变量列表以及返回类型,但不规定方法主体.接口也包含了基本数据 ...

  3. 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 ...

  4. 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 ...

  5. 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 ...

  6. 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 ...

  7. 谨慎使用Marker Interface

    之所以写这篇文章,源自于组内的一些技术讨论.实际上,Effective Java的Item 37已经详细地讨论了Marker Interface.但是从整个Item的角度来看,其对于Marker In ...

  8. 浅析Go语言的Interface机制

    前几日一朋友在学GO,问了我一些interface机制的问题.试着解释发现自己也不是太清楚,所以今天下午特意查了资料和阅读GO的源码(基于go1.4),整理出了此文.如果有错误的地方还望指正. GO语 ...

  9. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

  10. abstract与interface之房祖名张默版

    最近把java基础知识拿出来看看,看到abstract与interface的时候,觉得有点模糊,好像面试官也喜欢问这个问题.我在百度了查了好长时间,觉得讲算比较清楚的是那篇讲 Door,然后想要带个报 ...

随机推荐

  1. 使用python自动发放员工工资条到个人邮箱

    人力资源部每个月发工资条,以前靠人工手动一条一条的复制,200多号员工,差不多需要耗费一天时间. 用python写个脚本,分分钟的事情就可以全部发送完. 我这边工资表如下图 姓名在C列,邮箱在B列. ...

  2. sum 函数语法与应用

    一.sum 函数语法: SELECT SUM(expression )   FROM tables    WHERE predicates; expression 常量.列或函数,或者是算术.按位与字 ...

  3. C# 将CSV转为Excel

    CSV(Comma Separated Values)文件是一种纯文本文件,包含用逗号分隔的数据,常用于将数据从一个应用程序导入或导出到另一个应用程序.通过将CSV文件转为EXCEL,可执行更多关于数 ...

  4. Lua协程的一个例子

    很久没记录笔记了,还是养成不了记录的习惯 下面是来自 programming in lua的一个协程的例(生产者与用户的例子) 帖代码,慢慢理解 -- Programming in Lua Corou ...

  5. Springboot添加静态资源映射addResourceHandlers,可实现url访问

    @Configuration //public class WebMvcConfiger extends WebMvcConfigurerAdapter { public class WebMvcCo ...

  6. 有哪些不同类型的IOC(依赖注入)方式?

    构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖. Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参stati ...

  7. Java如何声明一个数组?JS如何声明一个数组?如何获取数组长度

    1 Long[] numbers; //一般使用的定义方式,可分为静态和动态两种定义方式,下有说明. 2 Long numbers[]; //跟上面用法一致. 3 Long... numbers; / ...

  8. 相对路径在IEAD中的位置

    相对路径在IEAD中的位置 工具栏-->Run -->Edit Configurations -->Working directory-->就是了 这里是直接到软件的地址:剩下 ...

  9. iOS全埋点解决方案-界面预览事件

    前言 ​ 我们先了解 UIViewController 生命周期相关的内容和 iOS 的"黑魔法" Method Swizzling.然后再了解页面浏览事件($AppViewScr ...

  10. 解决Mui中popover 顶部弹出菜单弹出位置不准确以及无法收回的问题

    前言 最近公司的项目转向使用Hbuilder开发移动端项目,其中想要通过在顶部标题栏加入弹出菜单的方式,来定位长列表的位置,如图所示. 问题 Mui的功能貌似还不是很完善,在使用这个弹出菜单的时候,发 ...