我可以对接口值的切片进行类型断言吗?

huangapple go评论94阅读模式
英文:

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的类型是[]SymbolMethod是为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.

huangapple
  • 本文由 发表于 2012年5月7日 16:00:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/10478641.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定