Могу ли я набрать утвердительный фрагмент значений интерфейса? - программирование
Подтвердить что ты не робот

Могу ли я набрать утвердительный фрагмент значений интерфейса?

Я пытаюсь набрать assert от a []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)

Я уверен, что для этого есть веская причина. Какой лучший способ продолжить?

4b9b3361

Ответ 1

Говоря, что x.(T) переменная x должна быть типа интерфейса, потому что только для переменных типа интерфейса динамический тип не фиксирован. И хотя Node является интерфейсом, []Node нет. Срез - это отдельный, неинтерфейсный тип. Поэтому просто не имеет смысла предполагать, что срез значений интерфейса также является интерфейсом.

Тип Node имеет четкое определение в вашем коде и, таким образом, является интерфейсом. Вы указали список методов для него. Тип []Node не такой. Какие методы он определяет?

Я понимаю, откуда вы пришли. Это может быть полезным ярлыком, но просто не имеет смысла. Это похоже на то, что syms.Method() работает, когда syms type []Symbol и Method для Symbol.

Замена строки 47 этим кодом делает то, что вы хотите:

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

Ответ 2

Go не допускает этого. Вам нужно преобразовать Node в Symbol индивидуально.

Причина, по которой это недопустимо, заключается в том, что []Node и []Symbol имеют разные представления, поэтому для преобразования потребуется выделить память для []Symbol.