2012-05-07 5 views
16

アサートを[]Nodeから[]Symbolに入力しようとしています。私のコードでは、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) 

私はこのために正当な理由があると確信しています。進むべき最善の方法は何ですか?

答えて

15

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) 
+0

私はあなたのセンセンスに同意しません "それでは、インターフェース値の一部もインターフェースだと仮定するのは意味がありません"。変換はコンバージョンです。インターフェイスはインターフェイスです。彼らは別々の概念です(少なくとも私の心の中で)。 Goの著者は '[] Node'から' [Symbol']への変換をサポートすることに決めた可能性がありますが、コストがかかり過ぎて共通のプログラミングパターンではないため変換しませんでした。理論的には、矛盾や問題を伴わない変換は意味をなさないが、言語設計者はどの変換を言語に適用するかを選択する必要がある。 –

+1

私は、この問題についてGoの著者が何を考えているのかを確かめることはできませんが、私はまだ私の仮定が正しいと思います。あなたはこの変換がコストがかかりすぎるのは間違いありませんが、それを違法にする理由はないと思います。私が言ったように、Goスライスはタイプです。 'Node []ノードをタイプすると言うことができます。 'Nodes'はインターフェースタイプですか?いいえ、私たちが '[] Node'型の変数を宣言することができない理由がわかりました。 golang-nutsメーリングリストでこの議論をしたいですか? – Mostafa

+0

@Atom:質問はコンバージョンについては問いません。それは型アサーションについて尋ねる – newacct

5

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

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

+0

事は質問にも変換について尋ねていない、です。それはタイプアサーションについて質問しています – newacct

+0

あなたは正しいです、私の答えは混乱しています。私は私の答えから最後の文を削除しました。 –

関連する問題