golang 的字面值与类型转换,来猜猜结果

2017-09-08 12:16:38 +08:00
 lizon
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

2215 次点击
所在节点    Go 编程语言
29 条回复
rrfeng
2017-09-08 18:13:59 +08:00
@lizon
前面说的很明白了,字面量要确定类型的时候跟其所处的位置有关
https://play.golang.org/
报错是: cannot convert "a" to type A

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

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

规则就是:如果算式中有一个操作数是字面量,那么就根据另一个操作数的类型来 cast,成功就计算,不成功就报错。
xrlin
2017-09-08 18:20:26 +08:00
golang 的字面值是没有类型的,赋值或者运算操作才判断类型,不过这确实有点不符合大部分语言的逻辑。
keenwon
2017-09-08 18:25:50 +08:00
https://play.golang.org/p/0daSoPmuEo

这样就清净了

本来就是强类型语言,是 int 就是 int,是 float 就是 float。
lizon
2017-09-08 18:28:55 +08:00
@rrfeng
a := 3.0
fmt.Printf("%T\n", a)
推导 a 的类型为 float64
https://play.golang.org/p/0VEgW1QOgk

这里 cast 为 float 的依据呢
reus
2017-09-08 18:38:04 +08:00
没什么奇怪的,po 主不知道 go 里 const 的概念吧。

3.0 是 const,需要是 int,就转换成 int,需要是 float64,就转换成 float64。
reus
2017-09-08 18:43:11 +08:00
https://golang.org/ref/spec#Constants

有明确的规范的,untyped constant 这个概念很多语言都没有。
rrfeng
2017-09-08 18:43:38 +08:00
赋值操作符下的 cast
其他操作符下的 cast

为什么会觉得这两者应该一样呢?
lizon
2017-09-08 19:18:14 +08:00
@rrfeng 为什么应该不一样呢?

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

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

a := 1

a / int(3.0)才应该编译通过,a / 3.0 应该报错
lizon
2017-09-08 19:20:46 +08:00
@reus 官方解释了就行,我指出来就是觉得这里反直觉,容易掉坑

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/389157

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX