type switch stringer nil golang error cast interface type-conversion go type-assertion

interface - switch - ¿Puedo escribir afirmar una porción de valores de interfaz?



switch interface type golang (2)

Estoy tratando de escribir aserción desde un []Node , a []Symbol . En mi código, Symbol implementa la interfaz Node .

Aquí hay un código circundante:

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 }

Aquí está el error que recibo:

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

Estoy seguro de que hay una buena razón para esto. ¿Cuál es la mejor manera de proceder?


Al decir x.(T) variable x debe ser del tipo de interfaz, ya que solo para las variables de tipo interfaz tipo dinámico no es fijo. Y mientras Node es una interfaz, []Node no lo es. Una porción es un tipo distinto, sin interfaz. Por lo tanto, simplemente no tiene sentido asumir que una porción de valores de interfaz es también una interfaz.

Type Node tiene una definición clara en su código y, por lo tanto, es una interfaz. Has especificado la lista de métodos para ello. Tipo []Node no es así. ¿Qué métodos define?

Entiendo de donde vienes con esto. Puede ser un atajo útil, pero simplemente no tiene sentido. Es algo así como esperar que syms.Method() funcione cuando el tipo de syms es []Symbol y Method es para Symbol .

Reemplazar la línea 47 con este código hace lo que quiere:

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


Ir no permite esto. Necesitas convertir Node a Symbol individualmente.

La razón por la que no está permitido es que []Node y []Symbol tienen diferentes representaciones, por lo que la conversión necesitaría asignar memoria para []Symbol .