我可以键入断言一片接口值吗?

Mat*_*ner 18 interface type-conversion go type-assertion

我想键入从断言[]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 }
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误:

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

我确信这是有充分理由的.什么是最好的方法?

Mos*_*afa 19

在说x.(T)变量x应该是接口类型,因为只有类型接口的变量动态类型不固定.虽然Node是界面,但[]Node不是.切片是一种独特的非接口类型.因此,假设一片接口值也是一个接口也没有意义.

Type Node在代码中有明确的定义,因此是一个接口.您已为其指定了方法列表.类型[]Node不是那样的.它定义了哪些方法?

我明白你的来源是什么.它可能是一个有用的捷径,但是没有意义.这有点像预期syms.Method()何时工作syms的类型[]SymbolMethodSymbol.

用这段代码替换第47行可以实现你想要的:

symbols := make([]Symbol, len(args))
for i, arg := range args { symbols[i] = arg.(Symbol) }
fixed, rest := parseFormals(symbols)
Run Code Online (Sandbox Code Playgroud)

  • 我不能肯定 Go 作者对这件事的看法,但我仍然认为我的假设是正确的。您说这种转换成本太高是对的,但我认为这不是将其设为非法的原因。正如我所说,在 Go 中 slice 是一种类型。你可以说`type Nodes []Node`。`Nodes` 是一种接口类型吗?不。所以我明白这就是我们不能断言 `[]Node` 类型的变量的原因。你想在 golang-nuts 邮件列表上进行这个讨论吗? (2认同)

小智 6

Go不允许这样做.你需要转换NodeSymbol个别.

它不被允许的原因是[]Node并且[]Symbol具有不同的表示,因此转换需要为其分配内存[]Symbol.