go

作者: 嘤嘤嘤998 | 来源:发表于2019-04-30 14:04 被阅读0次
    • go build vs go run image.png
    • 一个project只能有一个main包

    • go不用分号

    • go

    //go的基本格式
    package main
    import "fmt"
    func main(){
    
    }
    
    image.png image.png image.png
    • Printf PrintIn image.png
    • 多重赋值和匿名变量 image.png
    • 多个变量常量定义 image.png
    • iota枚举(只用于常量) image.png image.png
    • bool image.png
    • float image.png
    • ASCII码 image.png
    • 字符串类型 image.png
    • 字符和字符串区别(字符是以数字存储的,所以字符的数据类型是int) image.png
    • 复数类型 image.png
    • 格式化输出

      %T image.png image.png image.png
    • 输入的使用 image.png
    • 类型转换 image.png
    • 类型别名 image.png
    • 运算符 image.png
         /,取商
         %,取余,取模
         8/5 = 1
         8%5 = 3
         3/4 = 0
         3%4 = 3
         7/3 = 2
         7%3 = 1
         2/1 = 2
         2%1 = 0
    
    • if image.png
    • if else image.png
    • switch image.png image.png image.png image.png
    • for循环(go没有while和do while) image.png
    • range(迭代) image.png
    • break 和 continue

      break可以用于for switch和select,continue只能用于循环 image.png
    • goto
    • 函数(函数的顺序无所谓) image.png image.png
    • 不定参数(args...type) image.png
    //一个函数里可以同时传固定参数和不定参数
    func Myfunc03(a int, args ...int) {
    }
    
    func main () {
        MyFunc03(111,1,2,3)
    }
    
    //不定参数的传递
    func myfunc(tmp ...int){  //注意要有空格
        for _, data := range tmp {
            fmt.PrintIn("data=", data)
        }
    }
    func test(args ...int){
        myfunc(args...)  //把全部不定参数传递给myfunc
        myfunc(args[:2]...)  //把arg[2]之前(不包括arg[2]的所有参数传递给myfunc
        myfunc(args[2:]...)  //从arg[2]开始(包括arg[2])把后面所有参数传递给myfunc
    }
    func main(){
        test(1,2,3,4)
    }
    
    • 返回值
      写在func myfunc() 这里是返回值 {}
    package main
    import fmt
    //返回值基础写法
    func myfunc() int {
        return 666
    }
    //返回值常用写法/go推荐写法(给返回值取名并赋值)
    func myfunc1() (result int) {
        result = 666
        return
    }
    func main(){
        a := myfunc()
        fmt.PrintIn("a=", a)
        b := myfunc1()
        fmt.PrintIn("b=", b)
    }
    
    //多个返回值写法,go推荐写法
    func myfunc2() (a,b,c int) {
        a,b,c = 111,222,333
        return
    }
    func main(){
        a,b,c := myfunc2()
        fmt.Printf("a=%d, b=%d, c=%d\n",a,b,c)
    }
    
    • 有参有返回值
    func myfunc(a,b int) (max,min int) {
        if a>b {
            max = a
            min = b
        }else{
            max = b
            min = a
        }
        return
    }
    func main(){
        max,min := myfunc(10,20)
        fmt.Printf("max = %d, min = %d\n",max,min)
        //通过匿名变量丢弃某个返回值
        a,_ := myfunc(30,40)
        fmt.Printf("a = %d\n",a)
    }
    
    • 普通函数调用流程(先调用完成,再逐一打印) image.png
    • 递归函数的调用流程 image.png
    • 数字累加
    //实现1+2+3+...100
    //普通函数方法
    func funca () {
        for var i=1,i<=100,i++ {
            sum += i
        }
        return
    }
    func main () {
        var sum int
        sum = funca()
        fmt.PrintIn("sum=",sum)
    }
    //递归函数方法
    //100+99+98+...1
    func funcb (i int) int {
        if i = 100 {
            return 100
        }
        return i + funcb(i+1)
    }
    //1+2+3+...100
    func funcc (i int) int {
        if i = 1 {
            return 1
        }
        return i + funcc(i-1)
    }
    func main () {
        var sum1,sum2 int
        sum1 = funcb(1)
        sum2 = funcc(100)
        fmt.PrintIn("sum=",sum)
    }
    
    • 函数类型 & 回调函数
      回调函数就是参数里面有函数
    package main
    import "fmt"
    //为FuncType(自定义名称)定义类型为函数,两个int参数,一个int返回值
    type FuncType func(int,int) int
    
    func Add (a,b int) int {
        return a+b
    }
    func Minus(a,b int) int {
        return a-b
    }
    func Mul(a,b int) int {
        return a*b
    }
    func Calc(a,b int, fTest FuncType) (result int) {
        result = fTest(a,b)
        return
    }
    func main () {
        a := Calc(1,2,Add)
        fmt.PrintIn("a=",a)
        b := Calc(3,4,Mul)
        fmt.PrintIn("b=",b)
    }
    
    • 匿名函数
    package main 
    import "fmt"
    func main () {
        a := 10
        str := "mike"
        //定义匿名函数同时调用(无参无返回值)
        fanc () {
            fmt.Printf("a=%d, str=%s\n",a,str)
        }()
        //带参数的匿名函数
        f1 := func (i,j int) {
            fmt.Printf("i = %d, j = %d\n",i,j)
        }
        f1(1,2)
        //带参数匿名函数自调用
        func () {
            fmt.Printf("i = %d, j = %d\n",i,j)
        } (1,2)
        //匿名函数(有参有返回值)
        ma,mi := func (i,j int) (max,min int) {
            if i>j {
                max = i
                min = j
            }else{
                max = j
                min = i
            }
            return
        } (1,2)
        fmt.Printf("max = %d, min = %d\n",ma,mi)
    
    }
    
    • 闭包(调用了外部变量的函数) image.png

      闭包以引用方式捕获外部变量(函数内部可以读取和修改外部变量)

    func main () {
        a := 10
        str := "mike"
        func () {
            a := 20
            str := "go"
            fmt.Printf("a = %d, str = %s\n",a,str)    //输出 20 go
        } ()
        fmt.Printf("a = %d, str = %s\n",a,str)    //输出 20 go
    }
    

    没有闭包调用,函数调用完毕,内部变量自动释放:

    func test () int {
        //函数被调用时,x才分配空间,才初始化为0
        var x int  //未初始化,值为0
        x++
        return x * x  //函数调用完毕,x自动释放
    }
    func main () {
        fmt.PrintIn(test())  //输出1
        fmt.PrintIn(test())  //输出1
        fmt.PrintIn(test())  //输出1
    }
    

    有闭包调用,内部变量不释放:

    func test1() func() int {    //test1()返回一个函数func(),函数func()返回一个int
        var x int
        return func() int {
            x++
            return x*x
        }
    }
    func main() {
        f := test1()
        fmt.PrintIn(f())  //输出1
        fmt.PrintIn(f())  //输出4
        fmt.PrintIn(f())  //输出9
    }
    
    • defer (加了defer的语句会在函数结束前的瞬间执行)
    //先输出bbbbb,再输出aaaaa
    func main() {
        defer fmt.PrintIn("aaaaa")
        fmt.PrintIn("bbbbb")
    }
    
    多个defer(last in first out) image.png
    func test (x int) {
        result := 100 / x
        fmt.PrintIn(result)
    }
    //先输出aaaaa,再输出bbbbb,再输出错误消息,不再执行ccccc语句
    func main() {
        fmt.PrintIn("aaaaa")
        fmt.PrintIn("bbbbb")
        test(0)
        fmt.PrintIn("ccccc")
    }
    //先输出ccccc,再输出bbbbb,再输出aaaaa,最后是错误消息
    func main() {
        defer fmt.PrintIn("aaaaa")
        defer fmt.PrintIn("bbbbb")
        defer test(0)
        defer fmt.PrintIn("ccccc")
    }
    
    • defer结合匿名函数
    func main() {
        a := 10
        b := 20
        defer func () {
            fmt.Printf("a = %d, b = %d\n",a,b)  //后输出 111 222
        }
        a = 111
        b = 222
        fmt.Printf("外部:a = %d, b = %d\n",a,b)  //先输出 111 222
    }
    
    func main() {
        a := 10
        b := 20
        defer func (a,b int) {
            fmt.Printf("a = %d, b = %d\n",a,b)  //后输出 10 20 已经先传递参数,只是没有调用
        } (a,b)
        a = 111
        b = 222
        fmt.Printf("外部:a = %d, b = %d\n",a,b)  //先输出 111 222
    }
    
    • 局部变量
      定义在{}里的变量就是局部变量,只在{}里面有效(也包括if条件语句中的变量)
      执行到定义变量的那句话才开始分配空间,离开作用域自动释放
    func test() {
        a := 10
        fmt.PrintIn("a=",a)
    }
    func main() {
        a = 111 //报错,a undefined
        {
            i :=10
            fmt.PrintIn("i=",i)
        }
        i = 111  //报错,i undefined
    
        if flag := 3; flag ==3 {
            fmt.PrintIn("flag=",flag)
        }
        flag = 4  //报错,flag undefined
    }  
    
    • 全局变量:定义在函数外部的变量,全局都可以使用
    • 不同作用域,允许定义同名变量
      使用变量的原则,就近原则
    var a byte
    func main() {
        var a int
        fmt.Printf("%T\n",a)  //int
        test()  //unit8,就是byte
    }
    func test() {
        fmt.Printf("%T\n",a)  
    }
    
    • 复合类型 image.png
    • 指针 image.png image.png image.png
    • new函数 image.png image.png
      值传递: image.png
      地址传递: image.png
    • 数组
    //数组的长度必须是常量,且是类型的组成部分。[2]int和[3]int是不同类型。
    var a [n]int  //err
    
    n := 10
    var b [n]int  //err 不是常量
    
    var c [10]int  //ok
    fmt.Printf("len(c)=", len(c))  //10
    //赋值
    for c := 0; i<len(c);i++ {
        c[i] = i+1
    }
    for i,data := range c {
        fmt.Printf("i=%d, data=%d\n",i,data)
    }
    //如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小:
    var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
    
    //数组的下标可以是变量或常量
    i := 1
    a[i] = 2
    
    //数组初始化(声明定义同时赋值叫初始化)
    //全部初始化
    var a [5]int = [5]int{1,2,3,4,5}
    b := [5]int{1,2,3,4,5}
    fmt.PrintIn("a=",a)  //[1 2 3 4 5]
    fmt.PrintIn("b=",b)  //[1 2 3 4 5]
    //部分初始化,没有初始化的部分,自动赋值为0
    c := [5]int{1,2,3}
    fmt.PrintIn("c=",c)  //[1 2 3 0 0]
    //指定某个元素初始化
    d := [5]int{2:10, 4:20}
    fmt.PrintIn("d=",d)  //[0 0 10 0 20]
    
    //数组的比较  只支持==和!=,比较是不是每一个元素都一样,数组类型要一样
    a := [5]int{1,2,3,4,5}
    b := [5]int{1,2,3,4,5}
    c := [5]int{1,2,3}
    fmt.PrintIn("a==b", a==b)  //true
    fmt.PrintIn("a==c", a==c)  //false
    //同类型数组可以赋值
    var e [5]int
    e = a
    fmt.PrintIn("e=", e)  //{1,2,3,4,5}
    

    二维数组

    a := [3][4]int{{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}
    //部分初始化,没有初始化的部分,自动赋值为0
    b := [3][4]int{{1,2,3}, {5,6,7,8}, {9,10}}
    c := [3][4]int{{1,2,3,4}, {5,6,7,8}}  //{{1,2,3,4}, {5,6,7,8}, {0,0,0,0}}
    //指定某个元素初始化
    d := [3][4]int{1: {5,6,7,8} 
    //循环写二维数组
    var e [3][4]int
    k := 0
    for i := 0; i<3; i++ {
        for j := 0; j<4; j++ {
            k++
            e[i][j] = k
        }
    }
    fmt.PrintIn("e=",e)  //{{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}
    
    • 随机数
    package main
    import (
        "fmt"
        "math/rand"
        "time"
    )
    func main() {
        //rand.Seed(666)  //固定seed数,每次运行程序产生的随机数都是一样的
        rand.Seed(time.Now().UnixNano())  //以当前系统时间作为随机数,每次运行产生的数不一样
        for i := 0; i < 5; i++ {
            //fmt.Println("rand=", rand.Int())        //随机很大的数
            fmt.Println("rand=", rand.Intn(100))  //控制在100以内的数
        }
    }
    
    • 数组做函数参数 image.png
      数组指针做函数参数 image.png
    • 切片slice image.png image.png image.png
      切片创建 image.png
      切片和底层数组的关系: image.png
    • 切片作为函数参数传递,传递的是路径,而不仅仅是复制,所以会改变原有形参
    • 切片截取 image.png
    • append image.png
      image.png image.png
    • copy image.png
    • map

      map创建: image.png
      map赋值; image.png
      map遍历: image.png
      map删除一个键值: image.png
      map做函数参数,是引用传递: image.png
    • 结构体 image.png
      结构体普通变量初始化 image.png
      结构体指针变量初始化 image.png
    结构体成员的使用——普通变量: image.png
    结构体比较和赋值 image.png
    结构体作为函数参数传递 image.png image.png
    • go语言可见性规则 image.png
    • 深浅拷贝 image.png
    //深拷贝
    a := 10
    b := a  //深拷贝
    fmt.PrintIn(a,b)  //10,10
    b = 20
    fmt.PrintIn(a,b)  //10,20
    
    arr1 := [4]int{1,2,3,4}
    //深拷贝
    arr2 := arr1
    arr2[0]{100}
    //浅拷贝
    arr3 := &arr1
    (*arr3)[0] = 200  //理论的写法
    arr3[0] = 200     //go的语法糖
    
    
    

    相关文章

      网友评论

          本文标题:go

          本文链接:https://www.haomeiwen.com/subject/qhrdnqtx.html