A Tour of Go
中文版
(方法部分看完,并发没看)
一部分内容在无闻视频中讲解过了,笔记戳这里
大神写的练习解答,戳这里
Packages
- the package name is the same as the last element of the import path. For instance, the "math/rand" package comprises files that begin with the statement package rand.
引用如果是“name1/name2”形式,包名是name2
示例程序中是rand.Intn(10),输出1,每次输出不变,因为环境是确定的,如果想要不同输出,要用 rand.Seed
.链接里有解释,(If Seed is not called, the generator behaves as if seeded by Seed(1).)
Import
import (
"fmt"
"math"
)
Exported names
可见性原则
要使用 引入包中的参数,肯定是大写,不然是不能引用的
比如:math.pi ×,math.Pi √
Functions
可以一个参数或多个参数,参数名在前,类型灾后
Basic types
package main
import (
"fmt"
"math/cmplx"
)
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmplx.Sqrt(-5 + 12i)
)
func main() {
const f = "%T(%v)\n"
fmt.Printf(f, ToBe, ToBe)
fmt.Printf(f, MaxInt, MaxInt)
fmt.Printf(f, z, z)
}
//output:bool(false)
//uint64(18446744073709551615)
//complex128((2+3i))
输出结果的地方注意:输出类型,值
for
无闻视频中讲过,补充一点
死循环的实现在go里也非常简单
func main() {
for {
}
}
IF FOR 练习
牛顿法开平方(以前好像在知乎上看到过一个人说自己的面试经历,面试一家大公司,问了开平方,他讲了牛顿法,结果面试官不知道是啥,然后他就很详细的讲解了牛顿法,但是我找不到那段话了,不然可以放过来,如果有人也见过可以私我)
简单来说就是,比如开平方x,随便猜一个结果a,a+x/2得出新的结果,每次都这样算,得出的新结果会非常接近正确答案
package main
import (
"fmt"
"math"
)
func Sqrt(x float64) float64 {
z := 1.0
for {
tmp := z - (z*z-x)/(2*z)
fmt.Println(tmp)
if tmp == z || math.Abs(tmp-z) < 0.000000000001 {
break
}
z = tmp
}
return z
}
func main() {
fmt.Println(Sqrt(2.0))
fmt.Println(math.Sqrt(2.0))
}
Switch
Switch without a condition is the same as switch true.
Struct
Struct fields are accessed using a dot.
Struct fields can be accessed through a struct pointer.
注意!To access the field X of a struct when we have the struct pointer p we could write(p).X. However, that notation is cumbersome, so the language permits us instead to write just p.X, without the explicit dereference.*结构体,可以不加*,就是不用解引用
Struct Literals字面量赋值方式
type Vertex struct {
X, Y int
}
var (
v1 = Vertex{1, 2} // has type Vertex
v2 = Vertex{X: 1} // Y:0 is implicit
)
Slice
数组和slice的区别是声明的时候[]中有没有规定大小!
s := []struct { //匿名结构体,
i int
b bool
}{
//这里是slice 字面量赋值
{2, true},
{3, false},
{5, true},
{7, true},
{11, false},
{13, true},
}
fmt.Println(s)
func main() {
var s []int
printSlice(s)
// append works on nil slices.
s = append(s, 0)
printSlice(s)
// The slice grows as needed.
s = append(s, 1)
printSlice(s)
// We can add more than one element at a time.
//注意这里,扩容,之前cap=2,不够,所以cap=2*2=4, 还是不够, cap继续扩容=4*2=8
s = append(s, 2, 3, 4)
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
//输出
len=0 cap=0 []
len=1 cap=2 [0]
len=2 cap=2 [0 1]
len=5 cap=8 [0 1 2 3 4]
Range
package main
import "fmt"
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
一个经典例子,当初我查range的时候到处都是这个例子,还有一点提一下,返回值想舍弃的时候用_
exercise:Slice
注意:slice内部的slice要单独声明
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
picture := make([][]uint8, dy)
for i := 0; i < dy; i++ {
//注意这里,slice内部的slice要单独声明
picture[i] = make([]uint8,dx)
for j := 0; j < dx; j++ {
picture[i][j] = uint8((dx + dy) / 2)
}
}
return picture
}
func main() {
pic.Show(Pic)
}
Maps
//初始化
m := make(map[string]int)
//赋值
m["Answer"] = 42
//多返回值,ok,用来判断该key对应的有没有value值,返回bool
v, ok := m["Answer"]
fmt.Println("The value:", v, "Present?", ok)
map exercise
package main
import (
"golang.org/x/tour/wc"
"strings"
"fmt"
)
func WordCount(s string) map[string]int {
counter := make(map[string]int)
arr := strings.Fields(s)
for _, val := range arr {
counter[val]++
fmt.Println(counter[val],val)
}
return counter
}
func main() {
wc.Test(WordCount)
}
闭包、closures
package main
import "fmt"
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
pos(i),
neg(-2*i),
)
}
}
输出:
0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90
readers
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Hello, Reader!")
b := make([]byte, 8)
for {
n, err := r.Read(b)
fmt.Printf("n = %v err = %v b = %v\n", n, err, b,string(b))
fmt.Printf("b[:n] = %q\n", b[:n])
if err == io.EOF {
break
}
}
}
output;
n = 8 err = <nil> b = [72 101 108 108 111 44 32 82]
%!(EXTRA string=Hello, R)b[:n] = "Hello, R"
n = 6 err = <nil> b = [101 97 100 101 114 33 32 82]
%!(EXTRA string=eader! R)b[:n] = "eader!"
n = 0 err = EOF b = [101 97 100 101 114 33 32 82]
%!(EXTRA string=eader! R)b[:n] = ""