这是继" Hello world"之后我的第一个Golang程序。 请找到以下旨在执行基本算术和多类型返回演示的代码块。 这只是学习Go func的假设样本。 但是,我在编译时遇到以下异常。 我从例外出发,假设对int8操作数的操作将int16/int32作为返回类型返回,并且每次执行都不正确。

问题:用语言假设int8可安全地分配给int16int32是不安全的

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分配给int16int32,但是可以安全地进行转换。
  • 您必须使用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不会包装,否则。