-2

I tried :

var a [100]int
func fun1(src interface{}) interface{} {
    src, _ = src.([100]int) // changed []int to [100]int
    fmt.Println(reflect.TypeOf(src)) // result: []int
    dest := make([]int, len(src))
    return dest
}

there is an error:

message: 'invalid argument src (type interface {}) for len'

But if I redefine a variable:

var a [100]int
func fun1(src interface{}) interface{} {
    slice_src, _ := src.([100]int) //changed []int to [100]int
    fmt.Println(reflect.TypeOf(slice_src)) // result: []int
    dest := make([]int, len(slice_src))
    return dest
}

it will be ok.

why reflect.TypeOf(src) will print []int after I used src.([]int) but error shows src is still interface{} ? I have checked this convert interface{} to int, but I still don't understand how to use correct conversion.

There is another question:

I changed the []int to [100]int since the type assertion before will return [] and false.

But if I don't know the type of a, how can I use type assertion to transfer an array (like[99]int) as a interface{} to function and return slice ([]int)?

Diya Li
  • 1,048
  • 9
  • 21
  • 1
    The type assertion in your first example is a red herring. You can remove it without changing the semantics. A variable cannot change its static type. – Peter Oct 28 '17 at 16:30

3 Answers3

2

when you first declare src, in fun1(src interface{}) you are making a variable of type interface. Which, of course cannot have len called on it.

The reason reflect.TypeOf says []int is due to how TypeOf works. It takes an interface{} and tells you the type of the thing in the interface{}

so, in the first example, you already had an interface and in the second example, go automatically created an interface{} instance to hold your []int slice.

David Budworth
  • 11,248
  • 1
  • 36
  • 45
0

Quoting dynamic type from Variables :

The static type (or just type) of a variable is the type given in its declaration, the type provided in the new call or composite literal, or the type of an element of a structured variable. Variables of interface type also have a distinct dynamic type, which is the concrete type of the value assigned to the variable at run time (unless the value is the predeclared identifier nil, which has no type). The dynamic type may vary during execution but values stored in interface variables are always assignable to the static type of the variable.

In the first example, src has a dynamic type. Value of the src will be of type []int during execution but eventually, type will be interface since it is dynamic type & it was of type interface at the time of declaration. Hence, you need to change variable src to the new variable during type assertion.

Similar to what you did in second example: slice_src, _ := src.([]int)

You can not even do src, _ := src.([]int) as you will end up with error no new variables on left side of :=

Satyam Zode
  • 175
  • 4
0

There is a type switch method using reflect.TypeOf() : golang type assertion using reflect.Typeof() and How to get the reflect.Type of an interface?

Quote How to get the reflect.Type of an interface? :

You can't. Type assertions allow you to take advantage of the static type checking that the language gives you even if you have an interface, whose type isn't statically checked. It basically works something like this:

You have some statically typed variable s, which has type t. The compiler enforces the guarantee that s always has type t by refusing to compile if you ever try to use s as if it were a different type, since that would break the guarantee.

Community
  • 1
  • 1
Diya Li
  • 1,048
  • 9
  • 21