Go: Type assertions on structs?

huangapple go评论91阅读模式
英文:

Go: Type assertions on structs?

问题

包含翻译的代码部分:

package main

import "fmt"

type Number int

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

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

    n.IncreaseMe(90) // n现在应该是100

    fmt.Println(n)
}

当运行上述代码时,它给出了错误信息:

invalid operation: *n += i (mismatched types Number and int)

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

然后我尝试了以下代码:

*n.(int) += i

它告诉编译器不用担心,因为*n可以安全地被视为整数,但是这导致了以下错误:

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

我认为这是因为类型断言只适用于接口,而不适用于自定义类型。

那么这个问题的解决方案是什么呢?

英文:
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)
}

When running the code above, it gives me the error message

> invalid operation: *n += i (mismatched types Number and int)

Which is to be expected as it's trying to do a math operation on variables which don't share the same type.

I then tried

*n.(int) += i

which tells the compiler not to worry as *n can be safely treated as an integer, which leads me to

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

I believe this is happening because type assertions works only with interfaces, not custom types.

So what is the solution for this?

答案1

得分: 5

正如在“Go:命名类型断言和转换”中提到的:

类型断言仅适用于接口。接口可以具有任意的底层类型,因此我们有类型断言和类型切换来解决问题。

你不需要类型断言:你可以直接将*n转换为int(因为你完全知道实际类型)。

进行加法运算后,再将其转换回Number类型。

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

在这个[kbd]play.golang.org[/kbd]上查看示例:输出结果为100。

正如[ruakh]在[评论中]提到的:

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

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

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

英文:

As mentioned in "Go: Named type assertions and conversions"

> Type assertion works for interfaces only. Interface can have arbitrary underlying type, so we have type assertion and type switch to the rescue.

You don't need type assertion: you can just:

  • convert *n to an int: int(*n) (since you know full well the actual type).

  • make the addition

  • convert back to Number

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

See this <kbd>play.golang.org</kbd>: the output is 100.


As ruakh mentions in the comments:

> Go splits the concept of "casting" into two separate concepts:

> - one ("type conversions") for conversions that the compiler knows are correct, and

  • one ("type assertions") for conversions that must be checked at runtime.

> The latter only applies to interfaces, since only interfaces have additional type information at runtime that that's not known at compile time.

huangapple
  • 本文由 发表于 2014年9月8日 04:01:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/25714266.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定