go学习笔记02-表达语句

if else

1
2
3
4
5

// a == 100不需要加(),否则编译报错
 if a == 100 {
  ...
  }

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
48
49
50
51
52
package main

import "fmt"

func main() {
   var grade string = "B"
   var marks int = 90

   switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"
   }

// 根据type
   var x interface{}
   switch i := x.(type) {
      case nil:
         fmt.Printf(" x 的类型 :%T",i)
      case int:
         fmt.Printf("x 是 int 型")
      case float64:
         fmt.Printf("x 是 float64 型")
      case func(int) float64:
         fmt.Printf("x 是 func(int) 型")
      case bool, string:
         fmt.Printf("x 是 bool 或 string 型" )
      default:
         fmt.Printf("未知型")
   }

//  fallthrough 会强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true。下面输出为:2 3 4
   switch {
    case false:
            fmt.Println("1")
            fallthrough
    case true:
            fmt.Println("2")
            fallthrough
    case false:
            fmt.Println("3")
            fallthrough
    case true:
            fmt.Println("4")
    case false:
            fmt.Println("5")
            fallthrough
    default:
            fmt.Println("6")
    }
}

select

select 语句只能用于通道(chan)操作,每个 case 必须是一个通道操作,要么是发送要么是接收。

select 语句会监听所有指定的通道上的操作,一旦其中一个通道准备好就会执行相应的代码块。

如果多个通道都准备好,那么 select 语句会随机选择一个通道执行。如果所有通道都没有准备好,那么执行 default 块中的代码。

 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
package main

import (
    "fmt"
    "time"
)

func main() {

// make(chan string)创建一个传输字符串的通道实例
    c1 := make(chan string)
    c2 := make(chan string)

    /*
    make()专门用于初始化三种内建引用类型:切片、映射map、通道channel
    */

// go 表示异步执行这个函数,不阻塞当前程序
// func()表示定义一个匿名函数
// 最后的 () 表示立即调用这个匿名函数
    go func() {
        time.Sleep(1 * time.Second)
        //向c1通道发消息
        c1 <- "one"
    }()

    go func() {
        time.Sleep(2 * time.Second)
        //向c2通道发消息
        c2 <- "two"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}

循环

Go 语言的 For 循环有 3 种形式,只有其中的一种使用分号。

break关键字会终止最内层的for循环。continue关键字会跳过最内层循环的本次迭代。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 和 C 语言的 for 一样:
//for init; condition; post { }
for i := 0; i <= 10; i++ {
         sum += i
}

//和 C 的 while 一样只保留循环条件:
//for condition { }
for input != "quit" {
    fmt.Print("请输入 (输入 'quit' 退出): ")
    fmt.Scanln(&input)
    fmt.Println("你输入了:", input)
}

//和 C 的 for(;;) 一样,死循环,永远也不会退出:
//for { }
for {
      sum++ // 无限循环下去
}

for range 遍历可迭代的数据结构,如数组,切片,字符串,映射表,通道:

1
2
3
4
5
6
func main() {
   sequence := "hello world"
   for index, value := range sequence {
      fmt.Println(index, value)
   }
}

数组和切片

  • 数组是定长的数据结构,长度被指定后就不能被改变。在声明时长度只能是一个常量,不能是变量。

切割数组的格式为arr[startIndex:endIndex],切割的区间为左闭右开。数组在切割后,就会变为切片类型,因为右边是开的,长度不确定!

1
2
3
4
5
6
7
8
9
var nums [5]int

nums := [5]int{1, 2, 3}

//等价于nums := [5]int{1, 2, 3, 4, 5},省略号必须存在,否则生成的是切片,不是数组
nums := [...]int{1, 2, 3, 4, 5}

// 通过new函数获得一个指针
nums := new([5]int)
  • 切片是不定长的,切片在容量不够时会自行扩容,切片的初始化方式有以下几种:
1
2
3
4
var nums []int /
nums := []int{1, 2, 3}//len = 3, cap = 4
nums := make([]int, 0, 0)
nums := new([]int) // 指针

cap指容量,len指元素数量, Go 切片具有自动扩容机制,会将元素容量自动扩到2的幂!

切片的底层实现依旧是数组,是引用类型,可以简单理解为是指向底层数组的指针(本质上切片在Go中是一个结构体,包含指向底层数组的指针、长度值、容量值)。因此切片作为函数参数传递时不复制底层数组,函数内对传入切片的修改会反映在原切片中。

若要将数组转换为切片类型,不带参数进行切片即可,转换后的切片与原数组指向的是同一片内存,修改切片会导致原数组内容的变化,如果要对转换后的切片进行修改,建议使用下面这种方式进行转换:

1
2
3
4
5
6
7
func main() {
  arr := [5]int{1, 2, 3, 4, 5}
  slice := slices.Clone(arr[:])
  slice[0] = 0
  fmt.Printf("array: %v\n", arr)
  fmt.Printf("slice: %v\n", slice)
}

数组、切片使用

插入元素:

1
2
3
4
5
6
7
8
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

// 头部插入元素 [-1 0 1 2 3 4 5 6 7 8 9 10]
nums = append([]int{-1, 0}, nums...)

// 尾部插入元素 [1 2 3 4 5 6 7 8 9 10 99 100]
nums = append(nums, 99, 100)
fmt.Println(nums)

删除元素:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 从头部删除 n 个元素
nums = nums[n:]

// 尾部删除 n 个元素
nums = nums[:len(nums)-n]

// 中间指定下标 i 位置开始删除 n 个元素
nums = append(nums[:i], nums[i+n:]...)

// 删除所有元素
nums = nums[:0]

拷贝:

1
2
3
4
5
func main() {
  dest := make([]int, 0)
  src := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
  fmt.Println(copy(dest, src))
}

clear:

clear 会将切片内所有的值置为零值.

1
2
3
4
func main() {
    s := []int{1, 2, 3, 4}
    clear(s)
}
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计