天天看点

【Golang学习笔记】02

要点

- 部分运算符

- 控制语句

- 函数

部分运算符

  • byte运算
const (
        a byte =  << 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:=;x >  {
        fmt.Println(x)  // 这么赋值的话作用域只在if语句范围内
    } else if x < {
        fmt.Println(x)
    }
           
  • for

    循环只有for, while dowhile被移除了

for i:=; i < ; i++ {
        fmt.Println(i)
        if i >  {
            break
        }
    }
           

使用range做循环

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

DataArray := ]int}
    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 := 
here:
    q++
    if q <  {
        goto here
    }
    fmt.Println(q)    // 3
           
  • switch case

    不需要break; 执行完当前case后就会自动跳出

choice := 
    switch choice {
    case :
        fmt.Println()
    case :
        fallthrough         //关键字 直接执行下一个case
    case :
        fmt.Println()
    case ,,:
        fmt.Println()
    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 :=                       // 在函数内创建,应该是申请的栈内存,但是因为外部有引用所以逃逸到了堆上(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 ==) {
        return, errors.New("Can't Divide 0")
    }
    return a/b,nil
}

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

func main() {
    q := []int{,,,,,}
    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,"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")//这句不会执行
}
           

继续阅读