我最近尝试学习golang。 但是我对来自https://tour.golang.org/basics/13的这段代码感到困惑。

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
   "fmt"
   "math"
)

func main() {
    var x, y int = 3, 4
    var f float64 = math.Sqrt(float64(x*x + y*y))
    var z uint = uint(f)
    fmt.Println(x, y, z)
}

那一个很好。 然后我尝试

var f = math.Sqrt(9 + 16)

这也有效。 但是,当我将其更改为var f = math.Sqrt(x*x + y*y)时,为什么不起作用? 它说cannot use x * x + y * y (type int) as type float64 in argument to math.Sqrt

我具有javascript背景,但是我不知为何无法理解上面的代码。

  • 相关或可能重复的按时间分数进行的睡眠。

math.Sqrt函数签名:

1
func Sqrt(x float64) float64

要求您通过float64

在这种情况下:

1
var f float64 = math.Sqrt(float64(x*x + y*y))

您正在直接转换为float64

在这种情况下:

1
var f = math.Sqrt(x*x + y*y)

当需要float64时,您正在传递int

在这种情况下:

1
var f = math.Sqrt(9 + 16)

编译器能够推断类型,并为您传递float64

  • 因此,当传递具有数值的变量时,编译器不会自动将其转换吗? 但是当我们直接传递一个数字时,它会自动转换吗?
  • @muhajir,基本上是,当您传入显式声明为int的变量xy而不是float64时,因此编译器将其拒绝。 当您直接传递数字时,编译器会检查函数签名,并查看输入是否对float64有效,并且很有效,就像这样:var x float64 = 4

But when we pass a number directly, it automatically converted?

不,不是真的*)。您的"直接数字"在Go中称为"常量",常量通常是"无类型的"并且(几乎)具有任意精度。常量有特殊的规则:常量5a := 5定义的整数a的行为有所不同,因为5是具有特殊规则的常量,而不是int

9 + 16这样的常量表达式会在编译时求值,就像您键入25一样。此25仍然是(常量。

虽然Go没有针对类型的自动类型转换,但确实具有从常量到几种类型的自动转换。常量25可以自动转换为float64或int,uint8甚至complex128。

请阅读博客文章https://blog.golang.org/constants和官方语言规范,以获取完整说明和所有详细信息:https://golang.org/ref/spec#Constants。这解释了奇怪的概念
我比"无类型整数"更好。

*)"不是真的",因为这样思考是没有帮助的。常量的区别在Go中是特殊的:大多数其他语言将3 + 5作为两个int之和得出一个int,而Go看到两个未类型化的整数常量,并将此表达式求值为新的任意精度的未类型常量。仅在以后将常量转换为实际整数。