Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I type assert a slice of interface values?

Tags:

I am trying to type assert from a []Node, to []Symbol. In my code, Symbol implements the Node interface.

Here is some surrounding code:

 43 func applyLambda(args []Node, env Env) Node {  44     if len(args) > 2 {  45         panic("invalid argument count")  46     }  47     fixed, rest := parseFormals(args.([]Symbol))  48     return Func{  49         Body: args[1],  50         FixedVarNames: fixed,  51         RestVarName: rest,  52     }  53 } 

Here's the error I get:

./builtins.go:47: invalid type assertion: args.([]Symbol) (non-interface type []Node on left) 

I'm sure there's a good reason for this. What's the best way to proceed?

like image 460
Matt Joiner Avatar asked May 07 '12 08:05

Matt Joiner


People also ask

How does type assertion work in Golang?

Type assertions in Golang provide access to the exact type of variable of an interface. If already the data type is present in the interface, then it will retrieve the actual data type value held by the interface. A type assertion takes an interface value and extracts from it a value of the specified explicit type.

What is a type assertion?

In Typescript, Type assertion is a technique that informs the compiler about the type of a variable. Type assertion is similar to typecasting but it doesn't reconstruct code. You can use type assertion to specify a value's type and tell the compiler not to deduce it.

What is interface type in Golang?

Interface Types: The interface is of two types one is static and another one is dynamic type. The static type is the interface itself, for example, tank in the below example. But interface does not have a static value so it always points to the dynamic values.


1 Answers

In saying x.(T) variable x should be of interface type, because only for variables of type interface dynamic type is not fixed. And while Node is an interface, []Node is not. A slice is a distinct, non-interface type. So it just doesn't make sense to assume a slice of interface values is an interface too.

Type Node has a clear definition in your code and thus is an interface. You have specified the list of methods for it. Type []Node isn't like that. What methods does it define?

I understand where your are coming from with this. It may be a useful shortcut, but just doesn't make sense. It's kind of like expecting syms.Method() to work when syms's type is []Symbol and Method is for Symbol.

Replacing line 47 with this code does what you want:

symbols := make([]Symbol, len(args)) for i, arg := range args { symbols[i] = arg.(Symbol) } fixed, rest := parseFormals(symbols) 
like image 117
Mostafa Avatar answered Oct 07 '22 22:10

Mostafa