前言
这是我学习Go语法的笔记。由于有C和Python的基础,上手Go很快。笔记很粗糙,好在自己够用。
此篇包括了Go相关的:变量声明,分支语句(if,switch),循环语句(for)。涉及关键字var const fallthrough goto range
等。
简单示例
// go语言以包作为管理单位
package main // 声明包
import "fmt" // 导入包
func main() { // 左括号必须与函数名同行
fmt.Println("hello world")
}
注意事项:
- 每个文件必须声明包;
- 程序必须有一个main包。
声明变量
声明变量的四种方式:
func main() {
var a int
a = 512
var b int = 513 // 此时类型可以省略,就像声明c一样
var c = 514
d := 515 // 简短声明,让编译器为d自动推导类型
fmt.Println("a =", a) // 打印语句,类似Python中的print
fmt.Println("b =", b)
fmt.Println("c =", c)
fmt.Println("d =", d)
}
// 输出:
a = 512
b = 513
c = 514
d = 515
同时多个同类型变量的声明:
// 第一种
var a int
var b int
// 第二种
var a, b int
如果多个变量类型不同,可以:
var (
a int
b int
c float64
)
// 或者赋初值
var (
a int = 512
b int = 1024
c float64 = 3.14
)
Go语言中,每个声明的变量如果未被初始化,编译器默认为其设置0值。每个类型都有其对应的0值,但不一定是0。
func main() {
var num int // int类型
var str string // 字符串类型
var p *int // int指针类型
fmt.Println("a =", num) // 输出0
fmt.Println("str =", str) // 输出空字符串
fmt.Println("p =", p) // 输出nil
}
// 输出:
a = 0
str =
p = <nil>
nil相当于Python中的NULL。
声明常量
关键字const
承担常量声明的职责,与var
声明变量的用法相同。
const num = 512
// 或者
const num int = 512
注意以下几点:
- 常量必须在声明的时候赋值;
- 常量没有简短声明方式(
:=
); - 常量一旦声明,就不可以赋值,否则报错:
cannot assign to num
。
iota枚举
iota
为每个常量自动赋值(从0开始),每次赋值后自动累加1。
func main() {
const (
a = iota
b = iota
c = iota
)
fmt.Printf("a = %d b = %d c = %d", a, b, c)
}
// 输出
a = 0 b = 1 c = 2
多个同一行的变量值相同:
func main() {
const (
a = iota
b, c, d = iota, iota, iota
e = iota
)
fmt.Printf("a = %d b = %d c = %d d = %d e = %d", a, b, c, d, e)
}
也可以简化代码,只开头写一个iota
。此时不允许一行多个变量:
const (
a = iota
b
c
)
iota
遇到const
会被重置为0
func main() {
const (
a = iota
b
)
const c = iota
fmt.Printf("a = %d b = %d c = %d", a, b, c)
}
// 输出:
a = 0 b = 1 c = 0
基础类型
布尔类型
Go语言中布尔值的false
和true
全小写,而Python是首字母大写:
func main() {
var flag bool // 声明
fmt.Println("flag =", flag)
var mark = true // 声明的同时初始化
fmt.Println("mark =", mark)
// 或者
// mark := true
}
// 输出
flag = false
mark = true
字符型
Go语言中,用单引号表示一个字符 (byte
),同时字符类型以数值的方式存储:
func main() {
var c byte = 'z'
fmt.Println("c =", c)
}
// 输出
c = 122
如果希望字节正常输出,可以用fmt.Printf
:
fmt.Printf("c = %c", c) // %c 是字节占位符
由于字节类型以数值方式存储,所以可以进行加减乘除运算:
func main() {
var c byte = 'z'
fmt.Println("c =", c)
fmt.Println("c + 1 =", c + 1)
fmt.Println("c - 1 =", c - 1)
fmt.Println("c / 2 = ", c / 2)
fmt.Println("c * 2 =", c * 2)
}
// 输出
c = 122
c + 1 = 123
c - 1 = 121
c / 2 = 61
c * 2 = 244
字符串类型
字符串(string
)双引号表示:
str := "hello world"
Go语言中,'a'
与"a"
是存在区别的(Python中没有区别)。事实上"a"
由两个字符组成:'a'+'\0'
。
一个字符串可以通过索引的方式来访问:
func main() {
str := "hello world"
fmt.Printf("%c, %c", str[0], str[10])
}
// 输出
h, d
甚至可以像Python那样使用切片:
func main() {
str := "hello world"
fmt.Printf("%s", str[:5])
}
// 输出
hello
输入输出
fmt.Scan()
func main() {
var str string
fmt.Scan(&str) // 无需格式占位符
fmt.Println(str)
}
fmt.Scanf()
func main() {
var str string
fmt.Scanf("%s", &str) // 需要格式占位符
fmt.Println(str)
}
fmt.Println()
类似Python中的print()函数。
fmt.Printf()
类似C语言中的printf()函数。
分支语句
if
同其他语言一样,Go语言也有if
语句,中规中矩(仅仅是不需要小括号,Python对此也是允许的):
func main() {
num := 512
if num == 512 {
fmt.Println("num的值为512")
}
}
还有if...else if ... else:
func main() {
var num int
fmt.Scan(&num)
if num == 512 {
fmt.Println("num的值为512")
} else if num > 512 {
fmt.Println("num的值大于512")
} else {
fmt.Println("num的值小于512")
}
}
俏皮的是,Go语言中的if语句支持初始化一个语句(if 初始化语句; 条件 {...}
)比如:
func main() {
var num int
fmt.Scan(&num)
if tmp:= 512; num == tmp {
fmt.Println("num等于512")
}
}
switch
Go语言中的swicth与C语言中的switch有一些区别。Go语言中,case
的结尾默认带有break,无需用户自己添加:
func main() {
num := 1
switch num { // 不需要break
case 0:
fmt.Println("num等于0")
case 1:
fmt.Println("num等于1") // 进入`case 1`之后执行Println,然后直接跳出switch
case 2:
fmt.Println("num等于2")
default:
fmt.Println("num等于其他")
}
}
// 输出
num等于1
也可以是其他类型,如字符串变量:
func main() {
str := "hello world"
switch str { // 不需要break
case "bye~bye":
fmt.Println("bye~bye")
case "hello":
fmt.Println("hello")
case "hello world":
fmt.Println("hello world")
default:
fmt.Println("没有匹配字符串")
}
}
// 输出
hello world
通过添加fallthrough
关键字,使代码进入case之后不要直接跳出switch:
func main() {
num := 1
switch num { // 不需要break
case 0:
fmt.Println("num等于0")
fallthrough
case 1:
fmt.Println("num等于1")
fallthrough
case 2:
fmt.Println("num等于2")
fallthrough
default:
fmt.Println("num等于其他")
}
}
// 输出
num等于1
num等于2
num等于其他
与C中swicth
最大区别,在于条件可以写在case
后面:
func main() {
var num int
fmt.Scan(&num)
switch { // 省略变量
case num > 512: // 加上条件
fmt.Println("num大于512")
case num == 512:
fmt.Println("num等于512")
default:
fmt.Println("num小于512")
}
}
循环语句
Go语言只有for循环,没有while,用法如下:
func main() {
for num:=0; num < 3; num++ {
fmt.Println(num)
}
}
可以省略第一个表达式,但需要保留分号;
:
func main() {
num := 0
for ; num < 3; num++ {
fmt.Println(num)
}
}
事实上for可以当作while来使用:
num := 0
for num < 3 {
num++
fmt.Println(num)
}
如果什么都不加,就是死循环:
for {
fmt.Println("这是一个死循环。")
}
关键字range
实现迭代效果,如:
func main() {
str := "hello"
// 第一个元素是索引值,第二个是索引出来的内容
for i, alpha := range str {
fmt.Printf("num = %d, alpha = %c\n", i, alpha)
}
}
上述代码中alpha可以省略,只需要获取索引值即可:
func main() {
str := "hello"
for i := range str {
fmt.Printf("num = %d, alpha = %c\n", i, str[i])
}
}
这跟Python中的enumerate()函数有些相似。
跳转语句
如同C语言,Go语言也有goto
关键字,用法相同:
func main() {
fmt.Println("start ...")
goto End // 执行到这儿之后不会执行下面的代码,而是执行End之后的代码
fmt.Println("first end ...")
End:
fmt.Println("second end ...")
}
// 输出
start ...
second end ...
goto
不能跨函数使用。
还不快抢沙发