【Golang学习笔记】02

要点
- 部分运算符
- 控制语句
- 函数

部分运算符

  • byte运算
    const (
        a byte = 1 << iota
        b
        c
        d
    )

    x := a | b | c
    y := a | b | d

    fmt.Printf("%4b &^ %04b = %04b", x, y, x &^ y)  // 111 &^ 1011 = 0100
    // %nb, n代表占n位,0用空格代替, %0nb,0用0代替
  • 后缀运算
    前缀++ - - 被移除了, 后缀 ++ - - 只能作为语句 不能在放入表达式了
    q := 1
    //w:= q++       q++是语句不是表达式,此行编译不通过
    q++
    w:= &q
    *w++
    fmt.Println(q)   // 3

控制语句

  • if else
    if 语句; bool{}else{}
    // 
    if x:=6;x > 5 {
        fmt.Println(x)  // 这么赋值的话作用域只在if语句范围内
    } else if x < 7{
        fmt.Println(x)
    }
  • for
    循环只有for, while dowhile被移除了
    for i:=0; i < 10; i++ {
        fmt.Println(i)
        if i > 5 {
            break
        }
    }

使用range做循环
循环时使用range i代表序号, s代表value

    DataArray := [5]int{10,20,30,40,50}
    for i,s := range DataArray {  //    for i := range DataArray { 也可以使用占位符或者省略s
        fmt.Println(i,s, &i, &s)
    }

    /*
        0 10 0xc0420500d0 0xc0420500d8
        1 20 0xc0420500d0 0xc0420500d8
        2 30 0xc0420500d0 0xc0420500d8
        3 40 0xc0420500d0 0xc0420500d8
        4 50 0xc0420500d0 0xc0420500d8
    i和s的地址始终一样,说明循环时用的时同一块内存空间
     */
  • goto
    q := 0
here:
    q++
    if q < 3 {
        goto here
    }
    fmt.Println(q)    // 3
  • switch case
    不需要break; 执行完当前case后就会自动跳出
    choice := 2
    switch choice {
    case 1:
        fmt.Println(1)
    case 2:
        fallthrough         //关键字 直接执行下一个case
    case 3:
        fmt.Println(3)
    case 4,5,6:
        fmt.Println(4)
    default:
        fmt.Println("default")
    }
// 3

函数

不需要前置声明

func main() {
    test()
}

func test()  {      
    fmt.Println("不需要前置声明")
}

匿名函数

    a := func() {fmt.Println("匿名函数")}
    a()
    // 或者
    func() {fmt.Println("匿名函数")}()

函数赋值,必须是同一类型的函数

func test1(){
    fmt.Println("test1")
}

func test2(){
    fmt.Println("函数赋值")
}

func main() {
    b := test1
    c := test2
    b = c
    b()       // 函数赋值
}

go的escape analysis

func test3() *int{
    a := 1                      // 在函数内创建,应该是申请的栈内存,但是因为外部有引用所以逃逸到了堆上(go的escape analysis)
    fmt.Println(a, &a)
    return &a
}

func main() {
    d := test3()
    fmt.Println(*d, d)
}

//1 0xc042050090
//1 0xc042050090
//内存地址完全一样,所以说明外部得到的就是在函数内申请的内存空间。
  • 带多返回值的函数
func Divide(a int, b int) (int, error) {
    if (b == 0) {
        return 0, errors.New("Can't Divide 0")
    }
    return a/b,nil
}

func main() {
    w, err := Divide(2, 0)// err也可以用_占位符代替
    fmt.Println(w, err)
}
  • 不定长参数
// 不定长参数函数   参数名 ... 数据类型
func VariableLength(a ... int)  {
    fmt.Printf("%T, %v \n", a, a)
}

func main() {
    q := []int{1,2,3,4,5,6}
    VariableLength(q...)    // 无敌的省略号
}
  • 将函数作为参数传递
// 将函数作为参数传过去
func test(q int, w string,f func(a int,s string)(int, string))  {
    f(q, w)
}

func n1(a int, s string)(int, string){
    fmt.Println(a, s)
    return  a,s
}

func main() {
    test(1,"abc0", n1)
}
  • 延迟调用
func main() {
    // 延迟调用 关键字 defer
    defer fmt.Println("a001")
    defer fmt.Println("a002")
    fmt.Println("a003")
    fmt.Println("a004")
}

/*
a003
a004
a002
a001 先defer的排在最后
*/
  • 错误处理
    panic recover
func main() {
    // 错误处理
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("recover", err)  // 恢复中断的程序 可以用作释放资源之类的操作
        }
    }()

    panic("here panic")     // 中断程序
    fmt.Println("after panic")//这句不会执行
}

你可能感兴趣的:(Golang学习笔记)