2012-05-07 10 views
16

Sto provando a digitare asser da []Node, a []Symbol. Nel mio codice, Symbol implementa l'interfaccia Node.Posso digitare una fetta di valori dell'interfaccia?

Ecco alcuni codice circostante:

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 } 

Ecco l'errore che ottengo:

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

Sono sicuro che ci sia una buona ragione per questo. Qual è il modo migliore di procedere?

risposta

15

Nel dire x.(T) variabile x deve essere di tipo interfaccia, poiché solo per le variabili di tipo interfaccia il tipo dinamico non è fisso. E mentre Node è un'interfaccia, []Node no. Una sezione è un tipo distinto, non interfaccia. Quindi non ha senso pensare che una parte dei valori dell'interfaccia sia anche un'interfaccia.

Il tipo Node ha una definizione chiara nel codice e quindi un'interfaccia. Hai specificato l'elenco dei metodi per esso. Tipo []Node non è così. Quali metodi definisce?

Capisco da dove vieni. Potrebbe essere una scorciatoia utile, ma non ha senso. È un po 'come aspettarsi che syms.Method() funzioni quando il tipo di syms è []Symbol e Method è per Symbol.

Sostituzione linea 47 con questo codice fa ciò che si vuole:

symbols := make([]Symbol, len(args)) 
for i, arg := range args { symbols[i] = arg.(Symbol) } 
fixed, rest := parseFormals(symbols) 
+0

Non sono d'accordo con il tuo sentenso "Quindi non ha senso pensare che una porzione di valori dell'interfaccia sia anche un'interfaccia". Le conversioni sono conversioni: le interfacce sono interfacce. Sono concetti separati (almeno nella mia mente). Gli autori Go avrebbero potuto decidere di supportare le conversioni da '[] Node' a' [] Symbol', ma non lo hanno fatto perché è troppo costoso e tali conversioni non sono un modello di programmazione comune. Teoricamente, qualsiasi conversione che non implichi una contraddizione né un problema ha senso, ma i progettisti di linguaggi devono scegliere quali conversioni inserire nella lingua. –

+1

Non posso dire con certezza cosa ne pensino gli autori di questo argomento, ma continuo a pensare che la mia ipotesi sia vera. Hai ragione che questa conversione è troppo costosa, ma non penso che sia la ragione per renderla illegale. Come ho detto, in Go slice è un tipo. Puoi dire 'type Nodes [] Node'. 'Nodes' è un tipo di interfaccia? No. Quindi vedo che questo è il motivo per cui non possiamo affermare variabili di tipo '[] Nodo'. Ti piacerebbe fare questa discussione sulla mailing list golang-nuts? – Mostafa

+0

@Atom: la domanda non chiede informazioni sulle conversioni; chiede di tipo asserzioni – newacct

5

Go non lo consente. È necessario convertire Node in Symbol singolarmente.

Il motivo per cui non è consentito è che []Node e []Symbol hanno rappresentazioni diverse, quindi la conversione dovrebbe allocare memoria per []Symbol.

+0

la cosa è, la domanda non è nemmeno chiedere una conversione. sta chiedendo un tipo di affermazione – newacct

+0

Hai ragione, la mia risposta è confusa. Ho cancellato l'ultima frase dalla mia risposta. –

Problemi correlati