Go语言中的字面量
什么是字面量
在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(notation)。
简单的说,字面量或者说字面值就是一个变量的值。
整型和浮点型的字面值
var i int = 1
var f float64 = 3.14159
字符串的字面值
字符串值也可以用字符串面值方式编写,只要将一系列字节序列包含在双引号即可:
"Hello 世界"
`世界`
世界
一个原生的字符串面值形式是
`...`
使用反引号代替双引号。在原生的字符串面值中,没有转义操作;全部的内容都是字面的意思,包含退格和换行,因此一个程序中的原生字符串面值可能跨越多行(译注:在原生字符串面值内部是无法直接写```````字符的,可以用八进制或十六进制转义或+"`"
链接字符串常量完成)。唯一的特殊处理是会删除回车以保证在所有平台上的值都是一样的,包括那些把回车也放入文本文件的系统(译注:Windows系统会把回车和换行一起放入文本文件中)。
原生字符串面值用于编写正则表达式会很方便,因为正则表达式往往会包含很多反斜杠。原生字符串面值同时被广泛应用于HTML模板、JSON面值、命令行提示信息以及那些需要扩展到多行的场景。
const GoUsage = `Go is a tool for managing Go source code.
Usage:
go command [arguments]
...`
GoUsage
Go is a tool for managing Go source code.
Usage:
go command [arguments]
...
常量的字面值
对于常量面值,不同的写法可能会对应不同的类型。例如0、0.0、0i和\u0000虽然有着相同的常量值,但是它们分别对应无类型的整数、无类型的浮点数、无类型的复数和无类型的字符等不同的常量类型。同样,true和false也是无类型的布尔类型,字符串面值常量是无类型的字符串类型。
数组的字面值
使用数组字面值语法用一组值来初始化数组:
var q [3]int = [3]int{1, 2, 3}
var r [3]int = [3]int{1, 2}
r[2]
0
在数组字面值中,如果在数组的长度位置出现的是“…”省略号,则表示数组的长度是根据初始化值的个数来计算。因此,上面q数组的定义可以简化为
import "fmt"
q := [...]int{1, 2, 3}
fmt.Printf("%T\n", q) // "[3]int"
[3]int
7 <nil>
数组、slice、map和结构体字面值的写法都很相似。上面的形式是直接提供顺序初始化值序列,但是也可以指定一个索引和对应值列表的方式初始化,就像下面这样:
type Currency int
const (
USD Currency = iota // 美元
EUR // 欧元
GBP // 英镑
RMB // 人民币
)
//这个看起来和字典很相似,但其实USD等标识是index下标
symbol := [...]string{USD: "$", EUR: "€", GBP: "£", RMB: "¥"}
fmt.Println(RMB, symbol[RMB]) // "3 ¥"
symbol[EUR] == symbol[1]
3 ¥
true
Slice的字面值
slice和数组的字面值语法很类似,它们都是用花括弧包含一系列的初始化元素,但是对于slice并没有指明序列的长度。这会隐式地创建一个合适大小的数组,然后slice的指针指向底层的数组。就像数组字面值一样,slice的字面值也可以按顺序指定初始化值序列,或者是通过索引和元素值指定,或者两种风格的混合语法初始化。
s := []int{0, 1, 2, 3, 4, 5}
s
[0 1 2 3 4 5]
a := []string{"one", "two", 4:"three"}
a[4]
three
Map的字面值
用map字面值的语法创建map,同时还可以指定一些最初的key/value:
ages := map[string]int{
"alice": 31,
"charlie": 34,
}
这相当于
ages := make(map[string]int)
ages["alice"] = 31
ages["charlie"] = 34
结构体的字面值
第一种写法
type Point struct{ X, Y int }
p := Point{1, 2}
更常用的是第二种写法,以成员名字和相应的值来初始化,可以包含部分或全部的成员
anim := gif.GIF{LoopCount: nframes}
repl.go:1:9: undefined "gif" in gif.GIF <*ast.SelectorExpr>
两种写法不能混用