【问题标题】:Go: Type assertions on structs?Go:在结构上键入断言?
【发布时间】:2014-09-07 20:01:50
【问题描述】:
package main

import "fmt"

type Number int

func (n *Number) IncreaseMe(i int) {
        *n += i
}

func main() {
        n := Number(10)

        n.IncreaseMe(90) // n is now supposed to be 100

        fmt.Println(n)
}

运行上面的代码时,它给了我错误消息

无效操作:*n += i(不匹配的类型 Number 和 int)

这是意料之中的,因为它试图对不同类型的变量进行数学运算。

然后我尝试了

*n.(int) += i

这告诉编译器不要担心,因为 *n 可以安全地被视为整数,这导致我

invalid type assertion: n.(int) (non-interface type *Number on left)

我相信这种情况正在发生,因为类型断言仅适用于接口,而不适用于自定义类型。

那么有什么解决办法呢?

【问题讨论】:

    标签: go


    【解决方案1】:

    如“Go: Named type assertions and conversions”中所述

    类型断言仅适用于接口。接口可以有任意的底层类型,所以我们有类型断言和类型切换来救援。

    你不需要类型断言:你可以:

    • *n 转换为intint(*n)(因为您完全了解实际类型)。
    • 进行添加
    • 转换回Number

      *n = Number(int(*n) + i)
      

    看到这个play.golang.org:输出是100。


    正如ruakh 提到in the comments

    Go 将“强制转换”的概念拆分为两个独立的概念:

    • 一个(“类型转换”)用于编译器知道正确的转换,并且
    • 一个(“类型断言”)用于必须在运行时检查的转换。

    后者仅适用于接口,因为只有接口在运行时具有额外的类型信息,而这些信息在编译时是未知的。

    【讨论】:

    • +1。换句话说,Go 将“强制转换”的概念分成两个独立的概念:一个(“类型转换”)用于编译器知道正确的转换,一个(“类型断言”)用于必须在运行时检查的转换。后者仅适用于接口,因为只有接口在运行时具有额外的类型信息,而这些信息在编译时是未知的。
    • @ruakh 好点。我已将您的评论包含在答案中以提高知名度。
    • (@ruakh,喜欢这个描述;从没听说过这样说)
    猜你喜欢
    • 2017-02-09
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2016-05-26
    • 2021-06-22
    • 2016-05-22
    • 2021-02-10
    • 1970-01-01
    相关资源
    最近更新 更多