1. Go语言相关知识点
1.1 Go特点:
- 类型安全和内存安全
- 以非常直观和极低的代价实现高并发
- 高效的垃圾回收机制
- 快速编译
- 为多核计算机提供提升性能的方案
- 默认UTF-8编码
1.2 GOPATH下的三个目录:
1.3 相关命令:
1 2 3 4 5 6 7 8 9 10
| go run // 直接运行,调试 go build // 编译并生成可执行文件 go fmt // 格式化代码 go install // 先编译包文件,后编译整个程序 go test // 运行测试文件 (xxx_test.go测试程序xxx.go) go doc // 查看文档
godoc fmt Println // 查看具体的函数说明
godoc --http=:8080
|
1.4 包导入别名
1 2 3 4
| import "fmt" import . "fmt" import std "fmt" import _ "xxx"
|
1.5 可见性
1 2
| func getField() // private func Find() // public
|
2. 字符串格式化
2.1 占位符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| %v 默认格式 %+v 打印结构体时,添加字段名 %#v 使用Go语法表示 %T 对象类型 %% %
%t true 或 false
%b binary %c Unicode # Printf("%c", 0x4E2D) // 中 %d decimal %o octal %x hex %X HEX %#x add prefix "0x" # %#o add "0" prefix
%s string %q qutation
%f %.2f %e 科学计数法 %E %g 科学计数法,更紧凑的,无末尾的0 %G
%p 指针地址
|
2.2 键盘输入
1 2 3 4 5 6 7 8 9
| func main() { var name string var age int8
fmt.Scanln(&name) fmt.Scanf("%d", &age)
fmt.Println(name, age) }
|
2.3 字符串输入
1 2 3 4 5 6 7 8 9 10
| func main() { str := "Tom 23"
var name string var age byte
fmt.Sscanf(str, "%s %d", &name, &age)
fmt.Println(name, age) }
|
3. 位运算
3.1 原码、反码和补码:(有符号整数)
3.2 位移运算
- 右移(>>): 符号位不变,低位溢出,并用符号位补溢出的高位
- 左移(<<): 符号位不变,低位补0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| func main() { a := 1 >> 2 b := 1 << 2 fmt.Println(a, b)
c := -1 >> 2 d := -1 << 2 fmt.Println(c, d)
}
|
3.3 Go中特殊位运算符 &^
1 2
| var a int = 6 &^ 11 6 & (^11) => 6 & 4
|
3.4 负数位运算
1 2 3 4 5 6 7 8 9 10 11
| var a byte = 2 var b byte = -2 var c byte = a ^ b
|
4. 获取变量占用的字节数
unsafe.Sizeof(obj)
1 2 3 4
| func main() { var n = 100 fmt.Println(unsafe.Sizeof(n)) }
|
5. 控制语句
5.1 for循环
1 2 3 4 5 6 7 8 9 10 11
| for { }
for a <= 3 { }
for i := 1; i < 10; i++ { }
|
5.2 switch选择
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| func main() { var a = 1
switch a { case 0: fmt.Println("a=0") case 1: fmt.Println("a=1") default: fmt.Println("No Found") } }
func main() { var a = 1
switch { case a >= 0: fmt.Println("a>=0") fallthrough case a >= 1: fmt.Println("a>=1") default: fmt.Println("No Found") } }
switch a := 1; { }
func main() { var x interface{} = 10
switch x.(type) { case nil: fmt.Println("NULL") case int: fmt.Println("int") default: fmt.Println("interface{}") } }
|
5.3 for循环示例:打印空心金字塔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
func main() { N := 5
for i := 1; i <= N; i++ { for k := 1; k <= N-i; k++ { fmt.Print(" ") }
for j := 1; j <= 2*i-1; j++ { if j == 1 || j == 2*i-1 { fmt.Print("*") } else { if i == N { fmt.Print("*") } else { fmt.Print(" ") } } } fmt.Println() } }
|
5.4 for循环示例:九九乘法表
1 2 3 4 5 6 7 8
| func main() { for i := 1; i <= 9; i++ { for j := 1; j <= i; j++ { fmt.Printf("%d * %d = %d\t", j, i, i*j) } fmt.Println() } }
|
5.5 for循环示例:水仙花数
水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
func main() { var N int64 = 1000000
var i int64 for i = 100; i <= N; i++ { if isNarcissusFew(i) { fmt.Println(i) } } }
func isNarcissusFew(n int64) bool { s := strconv.FormatInt(n, 10) l := len(s) var sum int64 = 0 for j := n; ; { m := j % 10
sum += int64(math.Pow(float64(m), float64(l)))
j = j / 10 if j == 0 { break } }
return sum == n }
func isNarcissistic(n int64) bool { s := strconv.FormatInt(n, 10) l := len(s)
var sum int64 = 0 for _, c := range s { num, _ := strconv.Atoi(fmt.Sprintf("%c", c)) sum += int64(math.Pow(float64(num), float64(l))) }
return sum == n }
|
性能对比:
1 2 3 4 5 6 7 8
| go test -bench=. -run=none goos: darwin goarch: amd64 pkg: gomod/aaa BenchmarkIsNarcissistic-4 1 93848583244 ns/op BenchmarkIsNarcissusFew-4 1 31639945040 ns/op PASS ok gomod/aaa 125.791s
|
5.6 goto, break, continue LABEL用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| func main() { LABEL1: for { for i := 0; i < 10; i++ { if i > 3 { goto LABEL2 } } } LABEL2: fmt.Println("OK") }
|
6. 随机数
1 2 3 4 5
| func main() { rand.Seed(time.Now().UnixNano()) n := rand.Intn(100) + 1 fmt.Println(n) }
|
7. 时间和日期函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| func main() { now := time.Now()
year := now.Year() month := int(now.Month()) day := now.Day() fmt.Printf("%04d-%02d-%02d\n", year, month, day)
weekday := now.Weekday() fmt.Println(weekday)
ts := now.Unix() nano := now.UnixNano() fmt.Println(ts, nano)
dateStr := now.Format("2006-01-02 15:04:05") fmt.Println(dateStr) }
time.Sleep(100 * time.MilliSecond)
|
8. 内置函数
1 2 3 4 5 6 7 8 9 10
| len close
new make
nptr = new(int)
append panic/recover
|
9. new和make的区别
new(T) 返回 T 的指针 *T 并指向 T 的零值。
make(T) 返回的初始化的 T,只能用于 slice,map,channel。