go语言学习笔记

一、条件判断 if

1、条件判断

    if true {
        println(true)
    }

2、初始化; 条件判断

比较有特色的是goif支持初始化语句的执行。

  1. 可以减少行数
  2. 可以明确条件判断表达的意义
    x := 1
    if x++; x == 2 {
        println("先计算,再判断")
    }

    if c := 3; x == 2 {
        println("先赋值,再判断")
    }
    // 异常错误处理
    if value, err := check(); err!=nil {
        log.Println(err)
    }

二、循环遍历 for

1、传统用法

初始化;判断;计算

    for i := 0; i < 10; i++ {
        println(i)
    }

2、仅判断

相当于while i < 10 {},或者for ; x < 10 ; {}

    i := 5
    for i < 10 {
        println(i)
        i++
    }

3、无限循环

相当于while true {}

    i:=0
    for {
        println(i)
        i++
        if i > 20 {
            break
        }
    }

三、条件判断 switch

1、传统用法

可以不用写break,默认就带break

    switch x {
    case 1:
        println(1)
    case 2:
        println(2)
    case 3:
        println(3)
    default:
        println(0)
    }

2、不传参,多条件判断

    switch {
    case x == 1:
        println(1)
    case x == 2:
        println(2)
    case x == 3:
        println(3)
    default:
        println(0)
    }

3、带初始化语句

会先执行初始化语句,再传参,

    switch x++; x{
    case 1:
        println(1)
    case 2:
        println(2)
    case 3:
        println(3)
    default:
        println(0)
    }

4、条件通过后,继续执行

因为每条case默认带break,所以条件通过后,会结束执行。要加fallthrough

    switch x{
    case 1:
        println(1)  
        fallthrough
    case 2:
        println(2)
    case 3:
        println(3)
    default:
        println(0)
    }

四、数组 array

个人看法: array和java中的 [3]Integer 相对,固定,而 slice 和 java中的ArrayList相对,可动态添加

1、两数组比较

length 长度不一样的数组,不是同类型,不可比较
a,b可比较,a,c不可比较

var a = [2]int{1,2}
var b = [2]int{1,2}
var c = [3]int{1,2,3}

2、定义未知长度数组

会按实际初始值数量自动分配内存

var b = [...]int{1,2,3}
// 二维数组及以上,其中...符号只能用在第一维
var c = [...][2]int{
    {1,2},
    {3,4},
}

3、数组复制

无论是赋值、传参,数组都会完整的复制

    var k = [3]int{1,2,3}
    var g = k
    g[0] = 2
    fmt.Println(k, g) // [1 2 3] [2 2 3]

若希望改变原始数组,可以使用指针或切片

    var a = [3]int{1,2,3}
    b := &a
    b[2] = 4
    fmt.Println(a,*b) // [1 2 4] [1 2 4]

    var c = [3]int{1,2,3}
    d := c[:]
    d[2] = 5
    fmt.Println(c,d) // [1 2 5] [1 2 5]

4、数组参数

数组在函数中作为参数,会被完整复制,不会影响原始数组
若希望改变原始数组,可以使用指针或切片

    var e = [3]int{1,2,3}
    var say = func (arr [3]int){
        arr[2] = 9
        fmt.Println(arr)
    }
    fmt.Println(e)
    say(e)
    fmt.Println(e)
    // [1 2 3]
    // [1 2 9]
    // [1 2 3]

五、切片 slice

1、切片概念

切片本身是个只读对象,其工作机制类似数组指针的一种包装
切片优点:长度不固定,可以动态添加

    type slice struct{
        array unsafe.Pointer
        len int    // 表示切片当前实际元素的长度
        cap int    // 表示切片所引用的数组的真实长度,可理解为容量
    }

那cap的作用是什么?
cap确定了切片初始分配的内存,超过cap后,会动态分配内存。cap也会被动态改变。

2、切片切割

x[起点:终点:容量(cap-start)],
切片取值是左闭右开,就是起点值会被取到,终点值不会被取到,起始值起点是0

    x := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    fmt.Println(x[:])
    fmt.Println(x[2:5])
    fmt.Println(x[2:5:7])
    fmt.Println(x[4:])
    fmt.Println(x[:4])
    fmt.Println(x[:4:6])

    fmt.Println(len(x[2:5:7])) // 3 实际引用长度3
    fmt.Println(cap(x[2:5:7])) // 5 容量有5

3、切片赋值

切片是指针操作,所以赋值给其他变量后的操作依然会影响原始切片

    x := []int{1, 2, 3}
    c := x[:3]
    c[2] = 7
    fmt.Println(c, x) // [1,2,7],  [1,2,7]

4、切片比较

不能比较,就算是类型相同也不能,只能和nil比较

5、切片初始化

    var a = make([]int, 3)
        a = []int{1,2,3}

6、添加元素、复制切片

    a := []int{1,2,3}
    fmt.Println(a)
    a = append(a, 4)
    fmt.Println(a) // [1,2,3,4]
     var a = []int{1,2,3}
     var b = make([]int,3)
     copy(b,a)
     fmt.Println(b) // [1,2,3]

7、大数组切片引用

当一个大数组,len有100000,若有个切片需要长时间引用其中 [0,10]
这时候可以将切片复制,避免直接引用,释放大数组内存

        a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}  // 假设这有100000个元素
    b := make([]int, 3)
    copy(b, a[:4])
    fmt.Println(b)

六、常量 const

1、普通用法

const a = 1

2、同时声明多个常量

const a, b, c = 1, 2, 3

你可能感兴趣的:(go语言学习笔记)