web-dev-qa-db-ja.com

インターフェイス値のスライスをタイプアサートできますか?

[]Nodeから[]Symbolにassertと入力しようとしています。私のコードでは、SymbolNodeインターフェースを実装しています。

周囲のコードは次のとおりです。

 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)

これには正当な理由があると確信しています。続行するための最良の方法は何ですか?

20
Matt Joiner

x.(T)変数xはインターフェイスタイプである必要があります。これは、タイプインターフェイスの動的タイプの変数に対してのみ固定されていないためです。 Nodeはインターフェースですが、_[]Node_はそうではありません。スライスは、別個の非インターフェースタイプです。したがって、インターフェイス値のスライスもインターフェイスであると想定するのは意味がありません。

タイプNodeはコードで明確に定義されているため、インターフェースです。そのためのメソッドのリストを指定しました。タイプ_[]Node_はそのようではありません。それはどのような方法を定義していますか?

私はあなたがこれでどこから来ているのか理解しています。これは便利なショートカットかもしれませんが、意味がありません。これは、symsのタイプが_[]Symbol_で、MethodSymbolの場合、syms.Method()が機能することを期待するようなものです。

行47をこのコードに置き換えると、必要な処理が実行されます。

_symbols := make([]Symbol, len(args))
for i, arg := range args { symbols[i] = arg.(Symbol) }
fixed, rest := parseFormals(symbols)
_
19
Mostafa

Goはこれを許可しません。 NodeSymbolに個別に変換する必要があります。

許可されない理由は、[]Node[]Symbolの表現が異なるため、変換では[]Symbolにメモリを割り当てる必要があるためです。

6
user811773