预备知识
Go支持两种类型的注释,这跟C++是一样的。行注释(//) 以及多行注释 / and end with /.
Go标识符由数字和字母组成,第一个字符只能字母, 同时标识符不能为关皱字,比如if,for. 开头的字母可以为下划线_, 以及任何Unicoede字符 "中"。 编译器会阻止你使用以下的关键字作为标识符
Table 2.1 Go's Keyworkds
break | default | func | interface | select |
case | defer | go | map | struct |
chan | else | goto | package | switch |
const | fallthrough | if | range | type |
continue | for | import | return | var |
Go也有很多预定义标识符;
Table 2.2 Go's Predefined Identifiers
append | copy | int8 | nil | true |
bool | delete | int16 | panic | unit |
byte | error | int 32 | unit8 | |
cap | false | int64 | println | uint16 |
close | float32 | iota | real | unit32 |
complex | float64 | len | recover | unit64 |
complex64 | imag | make | rune | unitptr |
complex12 | int | new | string |
标识符是区分大小写的,比如LINECOUNT, Linecount, LineCount, lineCount, linecount是5个不同的标识符。 如果第一个字母为大写,则被认为它的public, 其它的则认为是private. (这条规则不适用于package names. 通常包的名字全部都是小写的).
空白标识符(_), 它是一个占位符
count, err = fmt.Println(x)
// get number of bytes printed and error
count, _ = fmt.Println(x)
// get number of bytes printed; discard error
_, err = fmt.Println(x)
// discard number of bytes printed; get error
fmt.Println(x)
// ignore return values
常量与变量
常量通过关键字const来声明。 变量通过var声明, 或者使用短变量声明语法。Go支持类型推断。 以下是一些例子:
const limit = 512 //constant; limit的类型可以为任何的数字
const top unit16 = 1421 //constant; 类型为unit16
start := -19 //variable; 推断出的类型为 int
end := int64(987653210) //variable; type: int64
var i int //variable; value 0; type: int
var debug = false //variable; inferred type: bool
checkResults := true //variable; inferred type: bool
stepSize := 1.5 //variable; inferred type: float:64
acronym := "FOSS" //variable; infferred type: string
对于数字字面量, Go的推断类型为int, 浮点型的则为float64. complex则为 complex128; 正常的原则是我们不指定类型,除非我们不需要Go推断,我们才需要指定具体的类型。 未指定数字类型的常量,可以表示任意的内置数据类型(e.g., limit 可以表示integers 或者浮点数).
变量 i 没有给定明确的值。 但Go会为没有给定值的类型分配此类型的零值(numeric 0, string 为‘’.
#### 枚举
在声明多个constants时,我们可以不用多次的使用const, 而是只需要使用一次const. 如下所示
const Cyan = 0 | const( | const (
const Magenta = 1 | Cyan = 0 | Cyan = iota //0
const Yellow = 2 | Magenta = 1 | Magenta //1
| Yellow = 2 | Yellow //2
| ) | )
上面三段代码都的效果都是一样的, 在第三段中,除非明确的指定了Cyan的值,否则分配一个0。 第二个以及后续的变量在此基础上加1
预定义标识符iota表示连续的整型常量。 每一个const group中,都会重置iota的值为0.
另一方面, 如果第三段代码段不是iota , Cyan 则为 0, Magenta的值则被设置为Cyan的值, 而Yellow 的值则设置为 Magenta的值。 所以它们的值都为0. 相似的, 如果Cyan设置为9, 则所有的都为9。 或者如果Magenta设置为5, 而Cyan没有明确的指定值或者iota, 则Cyan为0, Yellow 则为5.
type BitFlag int
const(
Active BitFlag = 1 << iota // 1 << 0 == 1
Send // Implicitly BitFlag = 1 << iota // 1 << 1 == 2
Receive // Implicitly BitFlag = 1 << iota // 1 << 2 == 4
)
flag := Active | Send
在这段代码里, 我们创建了三个位标志, 然后设置了变量flag的值为3。
BitFlay类已经可以正常使用, 但它对于调式信息却还不是很方便, 如果我们想要打印flag变量,我们只能得到一个3, 而没有更多的指示信息。在Go编程中可以很容易的控制自定义类型的输出。因为fmt包是调用自定义类型的 String方法。所以为了使用BigFlag类型可以打印更多的信息,我们可以添加一个合适的String()方法。
func (flag BitFlag) String() string {
var flags []string
if flag&Active == Active {
flags = append(flags, "Active")
}
if flag&Send == Send {
flags = append(flags, "Send")
}
if flag&Receive == Receive {
flags = append(flags, "Receive")
}
if len(flags) > 0 {
return fmt.Sprintf("%d(%s)", int(flag), strings.Join(flags, "| "))
}
return "0()"
}
fmt.Println(BitFlag(0), Active, Send, Receive, Active|Receive)
//0() 1(Active) 2(Send) 4(Receive) 5(Active| Receive)