英文:
Confused with Type conversions in golang
问题
我最近尝试学习golang。但是我对来自https://tour.golang.org/basics/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的背景,但我无法理解上面的代码。
英文:
I recently tried to learn golang. But I got confused with this code from https://tour.golang.org/basics/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)
}
That one works well. Then I tried
var f = math.Sqrt(9 + 16)
which also works. But when I change it to var f = math.Sqrt(x*x + y*y)
why is it not working? It says cannot use x * x + y * y (type int) as type float64 in argument to math.Sqrt
I have javascript background, and I somehow can't understand the code above.
答案1
得分: 7
math.Sqrt 函数的签名:
func Sqrt(x float64) float64
要求你传递 float64
类型的参数。
在这种情况下:
var f float64 = math.Sqrt(float64(x*x + y*y))
你直接将参数转换为 float64
类型。
在这种情况下:
var f = math.Sqrt(x*x + y*y)
你传递了一个 int
类型的参数,而实际需要的是 float64
类型。
在这种情况下:
var f = math.Sqrt(9 + 16)
编译器能够推断出类型,并为你传递 float64
类型的参数。
英文:
The math.Sqrt function signature:
func Sqrt(x float64) float64
requires that you pass float64
In this case:
var f float64 = math.Sqrt(float64(x*x + y*y))
You are converting to float64
directly
In this case:
var f = math.Sqrt(x*x + y*y)
you are passing an int
, when float64
is required.
In this case:
var f = math.Sqrt(9 + 16)
The compiler is able to infer the type, and pass float64
for you.
答案2
得分: 4
当我们直接传递一个数字时,它会自动转换吗?
不,实际上并不会。你所说的"直接数字"在Go语言中被称为"常量",常量通常是"无类型"的,并且(几乎)具有任意精度。常量有特殊的规则:常量5
和通过a := 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视为两个整数的和,结果为一个整数,而Go语言将其视为两个无类型整数常量,并将此表达式计算为一个新的任意精度、无类型的常量。只有在稍后才将常量转换为实际的整数。
英文:
> But when we pass a number directly, it automatically converted?
No, not really *). Your "direct numbers" are called "constants" in Go and constants are often "untyped" and (almost) of arbitrary precision. There are special rules for constants: A constant 5
and the integer a
defined by a := 5
behave differently because 5
is a constant with special rules and not an int
.
Constant expressions like 9 + 16
are evaluated at compile time like if you had typed 25
. This 25
is still a (constant.
While Go does not have automatic type conversions for types it does have automatic conversions from constants to several types. The constant 25
can be converted to float64 or int, uint8 or even complex128 automatically.
Please read the blog post https://blog.golang.org/constants and the official language spec for a full explanation and all details: https://golang.org/ref/spec#Constants . This explains the strange notion of
"untyped integer" better than I could.
*) "not really" because it is not helpful to think about it that way. The distinction of constants is special in Go: Most other languages tread 3+5 as a sum of two ints resulting in an int while Go sees two untyped integer constants and evaluates this expression into a new arbitrary precision, untyped constant. Only later are constants converted to actual integers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论