英文:
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 anint
: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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论