golang language []interface{} and interface{}

golang language[]interface{}

interface (interface)

Interface (interface) is one of the most important features of golang. The Interface type can define a set of methods, but these do not need to be implemented.

Please note: here is limited to a group of methods, since it is a method, it cannot be a variable; and it is a group, indicating that there can be multiple methods.

The interface is for the realization of polymorphism, and polymorphism refers to the ability of code to take different behaviors according to the specific implementation of the type. If a type implements an interface, all uses of the interface can support values ​​of that type.

The most exquisite design in the Go language should be the interface, which makes object-oriented and content organization very convenient.

interface application scenarios

Type conversion
realizes polymorphism

interface{} empty interface

There is a special type in Goland: interface{} , the empty interface. Other types in go do not have {}, only interface{} has.

The interface{} type is an interface without methods. Since there is no implements keyword, all types implement at least 0 methods, so all types implement the empty interface. This means that if you write a function that takes an interface{} value as a parameter, you can supply any value to the function, and []interface{} can also be considered an interface{} in golang.

Summary: The universal type (interface{}) is amazing, like void* in C, and Object type in Java. Any variable can be assigned to a variable of type interface{}.
At work, when we use interface{} as a function parameter, we can pass in any type as a parameter, because any type implements the interface{} interface.

[]interface{}

Things change when we declare the interface{} array

func Foo(a []interface{
    
    }) {
    
    }

Foo([]int{
    
    1, 2, 3}) // 报错
Foo([]string{
    
    "1", "2", "3"}) // 报错

According to its own assumption, no matter what kind of array can be passed in here as a parameter, but the result is just the opposite: we can only pass in elements of type []interface{}.

Since interface{} can represent any type, why can't a slice of interface{} represent a slice of any type?

Because the []interface{} type variable has a specific memory structure.

Each interface{} occupies two words (one word is 32 bits on a 32-bit machine, and one word is 64 bits on a 64-bit machine). Among them, one word is used to store the type of data actually passed in by interface{}; the other word is used to point to the actual data.

type eface struct {
    
    
    _type *_type
    data  unsafe.Pointer
}

For variables of type []interface{}, each element in the slice can store a different type of variable, for example

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

The size of the data allocation behind a []Type slice of length n is n * sizeof(Type) words.
Naturally, you can't pass the []int type as the []interface{} type, you can only write a loop yourself to convert each Type into interface{}.
Even if the data stored in the slice is of a specific type, it cannot be forced to be converted by type inference, because the underlying data storage structure is different

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.

Each interface{} takes two words (one word for the contained type and another word for the data or pointer word). As a result, a slice of length n and type []interface{} is backed by a block of data n*2 words long.

This is not the same as a piece of data backed up with type []mytype and the same length. Its data lot will be n*sizeof(mytype) words.

The upshot is that you can't quickly assign something of type[]mytype to something of type[]interface{}; the data behind them look different.

Summary: interface slice is different from the universal type empty interface. You can directly pass any type of value to the universal type, but you cannot pass any type of slice directly to the interface slice, because the interface slice is not a universal type, but it contains The thing is a universal type, so in turn you can't directly cast an interface slice to a specific type of slice.

Why can't []string directly convert []interface{} in golang

Why can't []string directly convert []interface{} in
golang

Troubleshooting at work

interface{} type assignment other variable error cannot use variable (type interface {}) as type int in assignment: need type assertion

package main

import "fmt"

func main() {
    
    
	var tmp interface{
    
    }
	var i int
	tmp = 1
	i = tmp
	fmt.Println(i)
}

The line of code that reports the error is the line i = tmp.

It can be seen that the interface{} type can be assigned to any type, but the interface{} cannot be directly assigned to other types.

Solution

//i = tmp
i = tmp.(int)

refer to

InterfaceSlice
reference URL: https://github.com/golang/go/wiki/InterfaceSlice
interface{} and []interface{}
reference URL: https://blog.csdn.net/lwldcr/article/details/77370948
Golang []interface{} type
Reference URL: https://www.cnblogs.com/xhyccc/p/15807778.html
Understanding []interface{} and interface{} in Golang
Reference URL: https://blog.csdn. net/qq_39220627/article/details/119191249

Guess you like

Origin blog.csdn.net/inthat/article/details/127170455