Golang Go语言中的字面值与类型转换,来猜猜结果

发布于 1周前 作者 sinazl 来自 Go语言
package main

import “fmt”

func main() { a := 1 b := 3

fmt.Printf("%T\n", a / b) fmt.Printf("%T\n", a / 3) fmt.Printf("%T\n", a / 3.0) fmt.Printf("%T\n", 1 / 3) fmt.Printf("%T\n", 1 / 3.0) }

答案: https://play.golang.org/p/mgxFyXtzGv


Golang Go语言中的字面值与类型转换,来猜猜结果

更多关于Golang Go语言中的字面值与类型转换,来猜猜结果的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

30 回复

感觉没什么特别啊

更多关于Golang Go语言中的字面值与类型转换,来猜猜结果的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


不好意思,没看清,确实有特别,变量除小数,居然还是整形

https://play.golang.org/p/nJs3oLSwyZ 加了个 c:=3.0,这个居然编译错误

第一反应:golang 你个浓眉大眼的居然也叛变了

3# 这个才正常

没看出来有任何问题,为啥这么大惊小怪?

var a int = 3.0
fmt.Println(a)

楼主是想说这个?

为神马会这样?

看来编译器对 int 字面量有特殊的转换处理… 不过 go 本来就不是很严谨的语言,一直没搞懂怎么优雅的提供一个 bool 的饮用

没准儿 Po 主真这么想的

为啥会这样??谁能解释一下!

var a int
var b float

a / b -> type error

在算式中的字面量会按照算式其他变量的类型进行 cast,而不是字面量的默认类型。

<br>type A int<br><br>func main() {<br> var a A<br> a = 10<br> fmt.Printf("%T\n", a/"abc")<br> fmt.Printf("%T\n", a/3.0)<br>}<br>

可以说是在不同的操作符(复制操作、运算操作)下,对字面量进行类型判定的方式是不一样的。

这没有任何问题,并不是对 int 有特殊处理。

哪里的出来的 go 不是很严谨的语言……

golang 不会进行自动的类型转换,整数只能除以整数,不会自动转换成为浮点数,字面量类型是根据所在位置来决定的。

第三个位置需要一个整数,3.0 是合法的整数,没有报错。附言里面的 3.1 不是合法整数,炸了正常。

运行结果看起来符合预期。

本质上是 var a int = 3.0 是一个合法的操作。
这点去别的语言对比一下看看吧。

3.0 从数学上来说应该是整数吧?有些语言把带小数点的字面量当成浮点型,go 在这个地方当成整数。也说不上谁对谁错,习惯不一样。

极少会有把 3.0 当整数的语言吧,a / 3.0 和 1 / 3.0 结果不一样有点反应不过来

go 所有的类型转换都需要是显示的,所以报错也很正常。

我印象中 go 这个语言好像特别重视格式这方面的内容,要让这些“习惯”“失效”。

我希望 a / 3.0 的时候报类型错误,也不要把 3.0 不声不响的当成 int 处理


前面说的很明白了,字面量要确定类型的时候跟其所处的位置有关
https://play.golang.org/
报错是: cannot convert “a” to type A

并不是把 3.0 不声不响的当作 int 处理,而是因为算式中的另外一个操作数是 int 类型。

体会一下:
var a string = "haha"
a + 3.0 //报什么错?

规则就是:如果算式中有一个操作数是字面量,那么就根据另一个操作数的类型来 cast,成功就计算,不成功就报错。

golang 的字面值是没有类型的,赋值或者运算操作才判断类型,不过这确实有点不符合大部分语言的逻辑。

https://play.golang.org/p/0daSoPmuEo

这样就清净了

本来就是强类型语言,是 int 就是 int,是 float 就是 float。


a := 3.0
fmt.Printf("%T\n", a)
推导 a 的类型为 float64
https://play.golang.org/p/0VEgW1QOgk

这里 cast 为 float 的依据呢

没什么奇怪的,po 主不知道 go 里 const 的概念吧。

3.0 是 const,需要是 int,就转换成 int,需要是 float64,就转换成 float64。

https://golang.org/ref/spec#Constants

有明确的规范的,untyped constant 这个概念很多语言都没有。

赋值操作符下的 cast
其他操作符下的 cast

为什么会觉得这两者应该一样呢?

为什么应该不一样呢?

既然通过赋值语句能推导出类型,那这个字面值本身就蕴含一个类型

3.0 在任何情况下的推导类型应该保持一致,而不应该随环境的变化而变化

a := 1

a / int(3.0)才应该编译通过,a / 3.0 应该报错

官方解释了就行,我指出来就是觉得这里反直觉,容易掉坑

在Golang(Go语言)中,字面值与类型转换是两个常见且重要的概念。让我们通过一个简单的例子来探讨它们,并尝试猜测结果。

假设我们有以下代码片段:

package main

import (
    "fmt"
)

func main() {
    var a int32 = 42
    var b int64 = int64(a)
    var c float64 = float64(b)
    var d string = string(c) // 注意这里
    fmt.Println(a, b, c, d)
}

让我们来猜测一下这段代码的输出结果:

  1. a 是一个 int32 类型的字面值 42
  2. b 是将 a 转换为 int64 类型后的值,仍然是 42,但类型变为 int64
  3. c 是将 b 转换为 float64 类型后的值,变为 42.0,类型为 float64
  4. d 是尝试将 c 转换为 string 类型。这里需要注意的是,直接将浮点数转换为字符串会得到该浮点数的文本表示,即 "42"(注意这里不是 42.0,因为默认情况下浮点数转换为字符串时不会保留小数部分,除非特别指定格式)。

因此,输出结果应该是:

42 42 42 42

需要注意的是,直接将数值类型转换为字符串时,可能会丢失数值的类型信息(如小数部分),这在处理浮点数时需要特别注意。

回到顶部