英文:
Can I type assert a slice of interface values?
问题
我正在尝试从[]Node
断言为[]Symbol
。在我的代码中,Symbol
实现了Node
接口。
以下是一些相关的代码:
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 }
这是我得到的错误:
./builtins.go:47: invalid type assertion: args.([]Symbol) (non-interface type []Node on left)
我确定这有一个很好的原因。继续进行的最佳方式是什么?
英文:
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?
答案1
得分: 25
在说x.(T)
时,变量x
应该是接口类型,因为只有对于接口类型的变量,动态类型才不固定。而Node
是一个接口,[]Node
不是。切片是一个独立的、非接口类型。所以假设一个切片的接口值也是一个接口是没有意义的。
类型Node
在你的代码中有一个明确的定义,因此是一个接口。你已经为它指定了方法列表。而[]Node
不是这样的。它定义了哪些方法呢?
我理解你的意思。这可能是一个有用的快捷方式,但是没有意义。这有点像期望当syms
的类型是[]Symbol
而Method
是为Symbol
时,syms.Method()
能够工作。
用以下代码替换第47行可以实现你想要的效果:
symbols := make([]Symbol, len(args))
for i, arg := range args { symbols[i] = arg.(Symbol) }
fixed, rest := parseFormals(symbols)
英文:
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)
答案2
得分: 6
Go不允许这样做。您需要逐个将Node
转换为Symbol
。
不允许这样做的原因是[]Node
和[]Symbol
具有不同的表示形式,因此转换需要为[]Symbol
分配内存。
英文:
Go does not allow this. You need to convert Node
to Symbol
individually.
The reason why it isn't allowed is that []Node
and []Symbol
have different representations, so the conversion would need to allocate memory for []Symbol
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论