go的基础知识

go 的一些基础知识和用法

变量声明

  • 使用 var 关键字
1
2
3
4
5
6
7
8
9
10
11
// 可在函数内,也可在包内
var a int
var a,b int = 1,2
var a,b,c = 1,true,"def"

// 使用var()集中定义变量
var (
a = 1
b = true
c = "def"
)
  • 编译器自动判断类型
1
2
// 只能在函数内使用
a,b,c: = 1,true,"def"

强制类型转换

1
2
var a,b int = 3,4
var c int = int(math.Sqrt(float64(a*a + b*b)))

常量和枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const a string = "def"

// 没有char 只有rune

func enum(){
const (
java = iota
python
golang
javascript
)
const (
b = 1 << (10*iota)
kb
mb
gb
tb
pb
)
}

条件语句

  • if 条件语句
1
2
3
4
5
6
7
8

// 条件语句里面可以进行变量赋值,变量作用域就在if的block里
const filename = "a.txt"
if content, err := ioutil.ReadFile(filename); err != nil {
fmt.println(err)
} else {
fmt.printf("%s", content)
}
  • switch 条件语句
1
2
3
4
5
6
7
8
switch {
case score < 60 :
fmt.printf("不及格")
case score > 60 && score <100 :
fmt.printf("合格")
default:
panic(fmt.Sprintf("wrong score: %d",score))
}
  • for 循环
1
2
3
4
5
6
7
8
9
10
11
12
13
// 死循环
for{

}

// 单语句
for a>2 {
a--
}

for a :=1; a<10; a++{

}

函数

函数 return 方式

1
2
3
4
5
6
7
8
9
10
11
12
13
func div(a,b int) (q,r int){
q = a / b
r = a % b
return
}

func sum (numbers ...int) int{
sum := 0
for i := range numbers {
sum += numbers[i]
}
return sum
}

指针

go 语言里面,函数传递都是用的值传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func swap (a, b *int){
*a, *b = *b, *a
}

func swap2 (a,b int)( int, int ){
return b, a
}

a, b := 3, 4
swap(&a, &b)
swap2(a ,b)

// *a代表的是变量a所在地址的值,更改*a会导致函数外部的a也改变
func adjust(a *int) *int {
var b int = 2
*a = 20 // 这里导致函数外部a改为20
a = &b // 这里只是函数内部的a改为了b的指针
return a
}

var i int = 3
adjust(&i)
fmt.Printf("value: %d \n", i) // value: 20

数组

数组是值类型,函数传参会 copy 数组

1
2
3
4
5
6
7
8
9
10
11
// 数组声明
var arr1 [5]int
// [3]
var arr2 = [3]int{1, 23, 4}
arr3 := [...]int{1, 23, 4, 5, 6} // 根据定义确定类型长度
var arr4 [4][5]int

sum := 0
for _, v := range numbers{
sum += v
}
  • slice 切片
    1. slice 就是数组的视图,对切片进行赋值操作,就是数组进行的操作
    2. slice 包含三个值,指针,len,cap(容量)
1
2
3
4
5
6
7
8
9
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println(arr[2:6], arr[1:], arr[:6], arr[:])

arr1 := arr[2:]
arr1[0] = 100

// cap 和 len
fmt.Println(arr) // [0 1 100 3 4 5 6 7]
fmt.Println(arr1, len(arr1), cap(arr1)) // [100 3] 2 6
  • slice 的操作
    1. 添加元素时,如果超越 cap,系统会重新分配更大的底层数组
    2. 由于值传递的关系,必须要接收 append 的结果 s = append(s, val)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s1 := append(arr[5:], 8)
s2 := append(s1, 110)
s3 := append(s1, 110, 112, 119)
s2[0] = 12

fmt.Println(arr, len(arr), cap(arr)) // [0 1 2 3 4 5 6 7] 8 8

// s2添加元素没有超越s1的cap
fmt.Println(s1, len(s1), cap(s1)) // [12 6 7 8] 4 6
fmt.Println(s2, len(s2), cap(s2)) // [12 6 7 8 110] 5 6

// s3添加元素超越了s1的cap,重新分配了新内存来保存s3
fmt.Println(s3, len(s3), cap(s3)) // [5 6 7 8 110 112 119] 7 12
1
2
3
4
5
6
7
8
9
10
11
12
s1 = []int{1, 23, 4, 5}
s2 = make([]int, 5, 32)

// 复制slice
copy(s2, s1) // s2 = [1 23 4 5 0]

// 删除slice中间第二个元素
s2 = append(s2[:2], s2[3:]...) // [1 23 5 0]

// 删第一个元素
s2 = s2[1:] // [23 5 0]
s2 = s2[:len(s2)-1] // [23 5]

Map

  • Map 的创建
1
2
3
4
5
m := map[string]string {
"name": "lee"
}
m1 := make(map[string]string) // m1 == empty map
var m2 map[string]string // m2 == nil
  • Map 的赋值、取值、删除
    1. key 不存在的时候,返回 value 类型的初始值
    2. map 使用哈希表,除了 slice,map,function 的内建类型都可以作为 key(struct 类型不包含上述字段,也可以作为 key)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
m := map[string]string {
"name": "lee",
"desc": "I'm lee"
}

for key, val := range m {
fmt.Println(key, val)
}

// 取值
name := m["name"]
// 赋值
m["name"] = "li"

// 可以根据获取状态来判断是否有值
if cname, ok := m["cname"]; ok{
fmt.Println(cname)
} else {
fmt.Printf("key doesn't exist !")
}

// 删除属性
delete(m, desc)

获取字符串的最长子串

  • rune 相当于 go 的 char
    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
28
29
30
31
32
33
34
35
36
37

str := "test,为了测试"

for i, char := range str {
fmt.Println(i, char)
}

// 获取字符数量
fmt.Println(utf8.RuneCountInString(str))

bytes := []byte(str)
for len(bytes) > 0 {
ch, size := utf8.DecodeRune(bytes)
bytes = bytes[size:]
fmt.Println(ch, size, bytes)
}

var longestStrInString = func(str string) int {
var length int = 0
var start int = 0
lastOcc := make(map[rune]int)
for i, char := range []rune(str) {
fmt.Printf("(%c %d) ", char, i)
if index, ok := lastOcc[char]; ok && index >= start {
start = i
}
if i-start+1 > length {
length = i - start + 1
}
lastOcc[char] = i
}
fmt.Println()
return length
}

fmt.Println(longestStrInString("pwbds6786868767867wbertyuio")) // 11
fmt.Println(longestStrInString("这里是你最偶偶的地方")) // 6

float四舍五入转化为int

1
2
3
4
5
6
7
8
9
around := func(f float64) int {
val := math.Floor(f)
if f-val > 0.5 {
val = math.Ceil(f)
}
return int(val)
}
fmt.Println(around(5.2))
fmt.Println(around(16.9))