【问题标题】:Can I type assert a slice of interface values?我可以键入断言一部分接口值吗?
【发布时间】:2012-05-15 18:11:17
【问题描述】:

我正在尝试将断言从 []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)

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

【问题讨论】:

    标签: interface type-conversion go type-assertion


    【解决方案1】:

    在说x.(T)变量x应该是接口类型的,因为只针对接口类型的变量动态类型是不固定的。虽然Node 是一个接口,但[]Node 不是。切片是一种独特的非接口类型。所以假设接口值的一部分也是一个接口是没有意义的。

    类型Node 在您的代码中有明确的定义,因此是一个接口。您已经为其指定了方法列表。 []Node 类型不是这样的。它定义了哪些方法?

    我了解您的出处。这可能是一个有用的捷径,但没有任何意义。当syms 的类型是[]SymbolMethodSymbol 时,这有点像期待syms.Method() 工作。

    用此代码替换第 47 行即可:

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

    【讨论】:

    • 我不同意你的说法“所以假设接口值的一部分也是一个接口是没有意义的”。转换就是转换——接口就是接口。它们是独立的概念(至少在我看来)。 Go 作者本可以决定支持从 []Node[]Symbol 的转换,但他们没有这样做,因为它的成本太高而且这种转换不是一种常见的编程模式。从理论上讲,任何不引起矛盾或问题的转换都是有意义的 - 但语言设计者需要选择将哪些转换放入语言中。
    • 我无法确定 Go 作者对此事的看法,但我仍然认为我的假设是正确的。你是对的,这种转换成本太高,但我不认为这是非法的原因。正如我所说,在 Go 中 slice 是一种类型。你可以说type Nodes []NodeNodes 是接口类型吗?不,所以我明白这就是我们不能断言[]Node 类型变量的原因。您愿意在 golang-nuts 邮件列表上进行此讨论吗?
    • @Atom:这个问题不问转化;它询问类型断言
    【解决方案2】:

    Go 不允许这样做。您需要将Node 单独转换为Symbol

    不允许这样做的原因是[]Node[]Symbol有不同的表示,所以转换需要为[]Symbol分配内存。

    【讨论】:

    • 问题是,问题甚至不是关于转换的问题。它在询问类型断言
    • 你是对的,我的回答令人困惑。我从答案中删除了最后一句话。
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 2021-04-24
    相关资源
    最近更新 更多