这是继" Hello world"之后我的第一个
问题:用语言假设
1 2 3 4 5 6 7 8 9 10 11 | package main import ( "fmt" ) func Arithmetic(a,b int8) (int8,string,int16,int32){ return a-b,"add",a*b,a/b } func main() { a,b,c,d :=Arithmetic(5,10) fmt.Println(a,b,c,d) } |
错误:
1 2 3 4 5 6 | C:/Go\bin\go.exe run C:/GoWorkspace/src/tlesource/ff.go # command-line-arguments .\ff.go:15: cannot use a * b (type int8) as type int16 in return argument .\ff.go:15: cannot use a / b (type int8) as type int32 in return argument Process finished with exit code 2 |
-
您不能将
int8 分配给int16 或int32 ,但是可以安全地进行转换。 -
您必须使用
int16() 等显式转换它 - @JimB,谢谢您的评论。我可能是错的,但是安全分配和转换是不同的。
- @ShmulikKlein,谢谢您的评论。如果我们尝试降低投放量,则投放可能是有效的。但是,这是一种过度铸造的情况。因此,我认为,这对于没有任何帮助的编译器来说应该是一件容易的事。
-
@Nair:你到底在问什么?您不能将
int8 分配给int16 /int32 / etc。仅仅因为它的"安全"并不意味着它们是可分配的。他们是不同的类型。 golang.org/ref/spec#Assignability - @JimB,是否确实int8 / int16 / int32是具有可变存储容量的整数/整数类型。
- @Nair多数民众赞成正确的,int8 / int16 / int32是8位,16位和32位宽,如您所期望的。您可能会发现tour.golang.org/basics/13有用。您还正确地认为,编译器可以轻松扩展较小的类型以匹配返回类型,但事实并非如此。仅仅因为您可以做某事并不意味着您应该做,在这种情况下,您应该明确对待此类事情,这是围棋哲学。这满足了最小惊奇原则。
- 我不确定我们中有些人是否沉迷于否决投票,而没有解释他们所发现的与主题无关的问题。
- @SamWhited,如果这是Go旨在处理这种情况的方式,那么我会接受它,并且我足够开放以尊重每种语言的水平。您可以将您的评论作为答案发布在答案部分。
-
@Nair:这个问题可能被否决了,因为"语言是否可以安全地假定int8可安全地分配给int16或int32"是不清楚的,这是否决的标准之一(此处的注释数表明:许多人不明白你在问什么)。从理论上讲"语言"(Go?)将
int8 分配给int16 可能是安全的,这一事实是无关紧要的,因为指定的语言不允许在不同的基础类型之间进行分配(请参见参考资料中的"可分配性"规范链接)。我之前的评论)。 - @JimB,谢谢您的指导。我必须遵循Go及其严格的类型限制,以了解为什么无法实现这种可分配性。对不起,还在学习。
Is it it safe for language to assume int8 is safely assignable to int16 or int32
是的,如果Go在分配时进行了隐式转换,那就可以了。 但这不是(仅适用时进行接口包装)。
有以下几个原因:
- 如果不引入类型层次结构的概念,则不能将自动转换的概念推广到所有类型。 而且,您知道,Go中的所有具体类型都是不变的。
- Go是"反魔术的",按照这种精神,它不会执行您未要求执行的操作(例如,指针的写屏障除外)。
该错误表明您必须返回int16和int32,您要做的就是将结果转换为:
1 2 3 | func Arithmetic(a, b int8) (int8, string, int16, int32) { return a - b,"add", int16(a * b), int32(a / b) } |
- 谢谢你的支持。 我的问题不是如何解决错误消息。 相反,我有兴趣知道为什么Go无法进行安全转换
- @Nair为什么无法进行安全转换?"因为这是语言的定义方式"。
-
最好做
int16(a) * int16(b) 而不是int16(a * b) ...除非可以保证a * b 不会包装,否则。