小生又准备跳新坑了(无奈脸),假装自己是一个很好学的孩纸…
包
Go 程序由包构成,程序入库是 main
包,在程序开头定义文件所属的包
package main
// 这里定义当前程序为包 main
func main() {
// 这里就是程序的入口啦~~~
}
在程序中使用其他包里的对象时,首先要导入包, 按照惯例,包名与导入的路径的最后一个目录一致
package main
import (
// 导入 package fmt
"fmt"
// 多个包分行排列,注意行末没有逗号
// 导入 math 路径下的 package rand
"math/rand"
)
func main() {
fmt.Println(rand.Intn)
}
在包中,首字母大写的对象会被导出,即在
import
包时, 可以访问到的对象只有包中首字母大写了的对象
函数
func add(x int, y int) int {
return x + y
}
如上述,add
为函数名, x
和 y
为传入参数, 其后跟的是对应的参数类型 int
,
而括号之后的 int
为返回值类型
在例子中,连续多个参数的类型相同可以只写最后一个参数的类型,如上参数列表可以缩写为
x, y int
在 Go 中,函数并不只能返回单一值,可以返回多个值,如下:
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
// 注意这里使用了 := 而不是 =
a, b := swap("fuck", "world")
fmt.Println(a, b)
}
Go 程序中的函数返回值可以被命名,并且作为变量在函数中使用,
而后使用没有参数的 return
语句,返回变量的当前值
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
// 返回 x, y 的当前值
return
}
注:命名返回值只应该被运用在短函数中,在长函数中影响代码的可读性
变量
var (变量名) (变量类型), (变量名) (变量类型) ... = (变量值), (变量值)
// 如:
var a int = 1
var a, b int = 1, 2
var a bool, b string = true, "3"
var a, b = true, 3
// 变量在声明时没有赋值,则默认为 零值
// 数值为 0
var a int
// 布尔类型为 false
var b bool
// 字符串为 "" 空字符串
var c string
在函数中, :=
简洁赋值语句在明确类型的地方,可以用于替代 var
定义
func main() {
var a, b = 1, 2
k := 2
c, d = true, "false"
}
注:
:=
结构仅能用在函数体之中
Go 程序之中必须要求显示的类型转换,转换函数即为对应的类型名称,如 float64
常量
常量使用 const
关键字来定义
const a = 1
const (
a = 1
b string = "test"
)
for 循环
for i:=0; i<10; i++ {
// 循环体...
}
Go 程序中只有一种循环结构,for 循环, 其后的三个组成部分初始化语句,循环条件,后置语句不需要括号, 但是循环体必须要使用花括号
其中,初始化语句与后置语句可以省略,与 while 循环类似
for ; sum<1000; {
sum += sum
}
或者省略分号,直接写成 for sum<1000 {}
,
无限循环可以省略条件,直接写成 for {}
if 条件
if x > 0 {
...
}
if 语句中的条件不需要括号,而且可以在执行条件检查之前, 执行一条简单的语句,如赋值等
// 这里声明的变量只在 if...else... 语句范围内有效
if v := x * 3; v < lim {
...
} else {
return v
}
switch 语句
// 与 if 类似,可以在判断条件前执行一个语句
switch name := "Han MeiMei"; name {
case "Li Lei":
fmt.Println("How are you?")
// 这里分支回自动结束
case "Han MeiMei":
fmt.Println("I'm fine, thank you!")
fmt.Println("And you?")
// fallthrough 可以继续执行下一个 case 分支的语句
fallthrough
case f():
...
default:
fmt.Println("Hi!")
}
switch 的条件从上到下的执行,当匹配成功的时候停止。
上例中函数 f()
就不会执行
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
没有条件的 switch 可以用于替代 if-elif-else 结构
defer 语句
defer 语句会延迟函数的执行直到上层函数返回。 延迟调用的参数会立刻生成,但是在上层函数返回前函数都不会被调用。
package main
import "fmt"
func test(x string) string {
fmt.Println("test function invoked")
return x
}
func main() {
defer fmt.Println(test("world"))
fmt.Println("hello")
}
这里会先执行 test 函数,计算出参数值, 然后输出 hello,最后输出 world, 对于同一个函数中多次调用 defer 语句的情况, 延迟的函数调用被压入一个栈中。当函数返回时, 会按照后进先出的顺序调用被延迟的函数调用。
// 会依次输出从 9 到 0
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}