Interface 我可以输入并断言接口值的一部分吗?

Interface 我可以输入并断言接口值的一部分吗?,interface,type-conversion,go,type-assertion,Interface,Type Conversion,Go,Type Assertion,我正在尝试从[]节点到[]符号键入assert。在我的代码中,Symbol实现了节点接口 以下是一些相关代码: 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

我正在尝试从
[]节点
[]符号
键入assert。在我的代码中,
Symbol
实现了
节点
接口

以下是一些相关代码:

 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)

我相信这是有充分理由的。最好的方法是什么?

Go不允许这样做。您需要将
节点
分别转换为
符号

不允许的原因是
[]节点
[]符号
具有不同的表示形式,因此转换需要为
[]符号
分配内存,即
x.(t)
变量
x
应为接口类型,因为只有接口类型的变量动态类型是不固定的。虽然
节点
是一个接口,
[]节点
不是。切片是一种独特的非接口类型。因此,假设一部分接口值也是一个接口是没有意义的

类型
节点
在代码中有明确的定义,因此是一个接口。您已经为它指定了方法列表。键入
[]节点
不是这样的。它定义了什么方法

我理解你的想法。这可能是一条有用的捷径,但毫无意义。这有点像当
syms
的类型是
[]Symbol
Method
用于
Symbol
时,希望
syms.Method()
工作

用此代码替换第47行可以实现以下目的:

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

我不同意你的观点“所以假设一部分接口值也是一个接口是没有意义的”。转换就是转换——接口就是接口。它们是不同的概念(至少在我看来)。Go作者本可以决定支持从
[]节点
[]符号
的转换,但他们没有这样做,因为这样的转换成本太高,而且这种转换不是常见的编程模式。理论上,任何不包含矛盾或问题的转换都是有意义的,但语言设计者需要选择在语言中使用哪种转换。我不能确定Go作者对这一问题的看法,但我仍然认为我的假设是正确的。你是对的,这种转换成本太高,但我不认为这是非法转换的原因。正如我所说,in-Go-slice是一种类型。您可以说
type Nodes[]Node
节点
是一种接口类型吗?没有。所以我明白了这就是为什么我们不能断言
[]Node
类型的变量。您想在golang nuts邮件列表上进行此讨论吗?@Atom:问题不在于转换;它询问类型断言问题是,问题甚至不是询问转换。这是关于类型断言的问题。你是对的,我的答案令人困惑。我把答案的最后一句删去了。