我只是使用官方的旅游/教程来学习golang。在其中一个示例中,我看到一个注释,上面写着An untyped constant takes the type needed by its context.
我正在尝试:
package main
import "fmt"
const (
// Create a huge number by shifting a 1 bit left 100 places.
// In other words, the binary number that is 1 followed by 100 zeroes.
Big = 1 << 100
)
func main() {
fmt.Printf("Big is of type %T\n", Big)
}
但这在我运行时失败了,
# command-line-arguments
./compile63.go:12:13: constant 1267650600228229401496703205376 overflows int
为什么我不能以这种方式发现常量的类型? (请注意,我是一个新手,很可能还没有对这种语言有足够的了解,无法自己解决这个问题。)
答案 0 :(得分:5)
func Printf(format string, a ...interface{}) (n int, err error)
Printf根据格式说明符格式化并写入标准 输出。它返回已写入的字节数和任何写入错误
变量声明创建一个或多个变量,并进行绑定 相应的标识符,并为每个标识符提供一个类型和一个 初始值。
如果给出了表达式列表,则变量将使用进行初始化 遵循分配规则的表达式。否则,每个 变量被初始化为其零值。
如果存在类型,则为每个变量指定该类型。除此以外, 给每个变量相应的初始化类型 赋值。如果该值是无类型常量,则为 首先转换为其默认类型;如果它是无类型的布尔值 值,首先将其转换为bool类型。预设值nil 不能用于初始化没有显式类型的变量。
常量可以是键入的,也可以是未键入的。文字常量,true,false, iota和某些仅包含未类型化的常量表达式 常量操作数是无类型的。
常量可以通过常量声明或 转换,或在变量声明或 赋值或作为表达式中的操作数。如果 常数值不能表示为各自的值 类型。
无类型的常量具有默认类型,即默认类型 在类型值是的上下文中隐式转换常量 例如在简短的变量声明(例如i:= 0)中是必需的 没有显式类型的地方。无类型的默认类型 常量是bool,符文,int,float64,complex128或字符串 分别取决于它是布尔值,符文,整数, 浮点数,复数或字符串常量。
数字类型表示整数或浮点值的集合。 一些预先声明的与体系结构无关的数字类型:
int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
n位整数的值是n位宽,并使用表示 二进制补码算法。
还有一些预先声明的数字类型 特定于实现的大小:
uint either 32 or 64 bits int same size as uint
Big
是无类型的常量。没有发现的类型。在变量或赋值中使用时,为其指定类型。无类型常量Big
的默认类型为int
。
const Big = 1 << 100
在Go中,所有参数都按值传递,就像通过赋值一样。对于fmt.Printf
,第二个参数的类型为interface{}
。因此,等效地,
var arg2 interface{} = Big // constant 1267650600228229401496703205376 overflows int
fmt.Printf("Big is of type %T\n", arg2)
无类型整数常量的默认类型为int
。溢出是编译时错误。
例如,
package main
import "fmt"
const (
// Create a huge number by shifting a 1 bit left 100 places.
// In other words, the binary number that is 1 followed by 100 zeroes.
Big = 1 << 100
)
func main() {
var arg2 interface{} = Big
fmt.Printf("Big is of type %T\n", arg2)
fmt.Printf("Big is of type %T\n", Big)
}
游乐场:https://play.golang.org/p/9tynPTek3wN
输出:
prog.go:12:6: constant 1267650600228229401496703205376 overflows int
prog.go:15:13: constant 1267650600228229401496703205376 overflows int
答案 1 :(得分:3)
虽然无类型常量确实是其上下文所需的类型,但是它可以假定的类型受语言原语的限制,因此,由于代码常量的存在,在代码中的任何地方实际上都无法使用大的常量。即使在uint64中也不适合的事实。它唯一可能的用途是在另一个常量表达式中使用它,否则将始终引发该错误。
请注意,在Printf
(和类似的函数)中,该常量将转换为interface{}
,因此默认情况下其类型为int
。对于32位计算机,如果您的常量表达式溢出int32,则需要首先进行类型转换。
const i = 1 << 50
fmt.Println(i) // => constant 1125899906842624 overflows int
fmt.Println(int64(i)) // => 1125899906842624
如果您想对任意大数进行适当的算术运算,则有一个方便的软件包:math/big
。
i := big.NewInt(1)
i.Lsh(i, 100)
fmt.Println(i.String())