2012-05-07 78 views
16

我試圖從[]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) 

我敢肯定有一個很好的理由。最好的方式是什麼?

回答

15

在說x.(T)變量x應該是接口類型,因爲只有類型接口動態類型的變量不固定。而Node是一個界面,[]Node不是。切片是一種獨特的非接口類型。因此,假設一片界面值也是一個界面是沒有意義的。

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

我不同意你的說法「因此,假設一片界面值也是一個界面是沒有意義的」。轉化是轉化 - 界面是界面。他們是不同的概念(至少在我看來)。 Go作者可能已決定支持從[] Node到[] Symbol的轉換,但這並不是因爲代價太高,而且這種轉換不是常見的編程模式。從理論上講,任何不會產生矛盾或問題的轉換都是合理的 - 但語言設計師需要選擇將哪種轉換放入語言中。 – 2012-05-07 11:17:00

+1

我無法確定Go作者怎麼看待這件事,但我仍然認爲我的假設是真實的。你說得對,這種轉換成本太高,但我認爲這不是違法的原因。正如我所說,在切片是一種類型。你可以說'輸入Nodes [] Node'。 Nodes是一種接口類型嗎?不,所以我看到這就是我們不能斷言'[] Node'類型變量的原因。你想在golang-nuts郵件列表上做這個討論嗎? – Mostafa

+0

@Atom:這個問題並沒有提出有關轉換的問題。它會詢問類型斷言 – newacct

5

Go不允許這樣做。您需要分別將Node轉換爲Symbol

不允許的原因是[]Node[]Symbol有不同的表示,所以轉換需要爲[]Symbol分配內存。

+0

的事情是,這個問題甚至沒有問轉換。它是問一個類型斷言 – newacct

+0

你說得對,我的答案很混亂。我從我的答案中刪除了最後一句。 – 2012-05-07 19:55:31

相關問題