Types 常数1被截断为整数?
为什么这段代码不能编译Types 常数1被截断为整数?,types,go,weak-typing,Types,Go,Weak Typing,为什么这段代码不能编译 package main const a = 1.000001 const base = 0 const b = a+base func main() { f(b) } func f(int) {} 是说1被截断了?或者1不能被截断?它说的是哪一个1 有人回答说上面的代码没有编译,因为b是float64。但为什么要编译: package main import "fmt" const a = 1.000001 const b = a-0.000001 func
package main
const a = 1.000001
const base = 0
const b = a+base
func main() {
f(b)
}
func f(int) {}
是说1被截断了?或者1不能被截断?它说的是哪一个1
有人回答说上面的代码没有编译,因为b
是float64
。但为什么要编译:
package main
import "fmt"
const a = 1.000001
const b = a-0.000001
func main() {
fmt.Printf("%T %v\n",a,a)
fmt.Printf("%T %v\n",b,b)
f(b)
}
func f(int) {}
?
b
在这里是一个float64
,但它可以传递到f
免责声明:我对Go没有任何经验,但下面的答案基于与数据类型相关的一般原则
函数f
采用类型为int
的输入参数,但传递给它的实际值,即b
具有基于代码的浮点值。这将导致将浮点值截断为整数值,如错误消息所述
我相信您可以通过更改函数签名来解决这个问题,将浮点类型值作为输入参数,即
func f(float64) {}
要将其与我熟悉的语言(C#)进行比较,您可以查看以下代码:
public static void Main(string[] args)
{
var a = 1.3;
var b = 1.3 + 9;
f(b);
Console.WriteLine("Hello, world!");
}
public static void f(int a)
{
}
使用var
关键字,我们没有显式地将a
和b
变量设置为数据类型double
。但是,由于浮点值被分配给它们,因此它们的类型被推断为double
。现在,如果将方法f
定义为获取数据类型int
的输入参数,然后传入a
或b
。它会给你一个错误。但是,如果将方法更改为采用double
值而不是int
,则代码将编译而不会出现问题
围棋小组最近做了一个报告,我建议您阅读
从介绍开始
Go是一种静态类型语言,不允许
混合数字类型。不能将浮点64添加到int,甚至不能将浮点32添加到int
但写入1e6*time.Second或math.Exp(1)或
即使是1Go也有常数:
在以下任何情况下,常量值x可转换为T型:
可由类型为x
的值表示T
是浮点常量,T是浮点类型,x在使用IEEE 754四舍五入后可由x
类型的值表示 公平规则。常数T
是四舍五入值T(x)
是整数常量,x
是字符串类型。与非常量T
相同的规则适用于这种情况x
但是为什么我把它改成这个呢<代码>常数a=1.000001;常数b=a-0.000001
在本例中,
b
等于1。1可以表示为整数,因此不涉及舍入和信息丢失。因此,这不是错误,因为它符合浮点值的转换规则(如前所述)。您的第一个程序可以这样重写:
package main
func main() {
f(1.000001)
}
func f(int) {}
package main
import "fmt"
func main() {
fmt.Printf("%T %v\n",1.000001,1.000001)
fmt.Printf("%T %v\n",1,1)
f(1)
}
func f(int) {}
这显然不是将整数值传递给整函数
您的第二个程序也可以这样重写:
package main
func main() {
f(1.000001)
}
func f(int) {}
package main
import "fmt"
func main() {
fmt.Printf("%T %v\n",1.000001,1.000001)
fmt.Printf("%T %v\n",1,1)
f(1)
}
func f(int) {}
看起来不错
我所做的只是手动替换
a
和b
常量。这就是我要做的一切。但是当我把它改成这个时,为什么它能工作呢<代码>常数a=1.000001;const b=a-0.000001同样,我没有围棋的经验,所以你应该得到第二个意见,但我认为1.000001-0.000001=1.000000被视为整数1,它满足int
参数要求。有趣的是,reflect.TypeOf(b)
显示float64
,但PrintLn(b)
显示1和reflect.TypeOf(1)
显示int
@shree.pat18这是因为常量值的计算涉及浮动,因此内部表示仍然是float64
。但是结果是完全可转换的,所以这里没有错误。你是说f
得到1.000001?在我看来,非类型化常量b
被截断为1(因此错误“常量1被截断为整数”),这将使其可以表示为int。如果我将b
更改为1.2,则错误为“常量1.2被截断为整数”。很明显,这里发生了更多的事情。它说,如果要编译,1.000001将需要被截断。换句话说,非类型化值1.000001不能用int类型表示。在第二个示例中,1.000001-0.000001是值1。您可以按自己喜欢的方式编写它(0x1、1.0等),但这不会改变它的内容。1可以用整数表示,因此可以编译。如果a=1.000001
,则表示“常数1被截断为整数”。如果我将a
或b
更改为1.2,则错误为“常数1.2截断为整数”。很明显,这里发生了更多的事情。在一种情况下,它报告被截断的版本,而在另一种情况下,它不报告。
const b = 1.01
c := b
f(int(c))
package main
func main() {
f(1.000001)
}
func f(int) {}
package main
import "fmt"
func main() {
fmt.Printf("%T %v\n",1.000001,1.000001)
fmt.Printf("%T %v\n",1,1)
f(1)
}
func f(int) {}