• 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
    }
    

      

  • 相关阅读:
    C#对象初始化器
    C#构造方法
    C#方法重载
    C#方法
    C#类 对象 字段和属性
    C#数组
    C#字符串
    C#原码反码补码
    字段、方法、属性
    单例模式、异常
  • 原文地址:https://www.cnblogs.com/juanmaofeifei/p/14299783.html
Copyright © 2020-2023  润新知