搜 索

Go语言从入门到放弃

  • 253阅读
  • 2022年04月28日
  • 0评论
首页 / 正文

go语言号称better c,同时兼具c的运行效率和php的开发效率,对于后端程序员可兼顾开发效率和运行效率,在WEB/中间件/容器化/虚拟货币上都有较为广泛的应用。

go基础语法

  • go语言的基础语法,go的语法很灵活
  • 和java相同基础类型有bool, byte, int8, int16, int32, rune, float32, float64,
  • 除此以外还有int,int64,complex,uintptr(存储指针),string(初始值为""),array,struct(结构体,和c一脉相承),function,interface等类型
  • 引用类型包括: map,slice,channel
var x = "xx" // 全局变量
func defVar() {
    // 定义变量有2种方式
    var a = "123"
    var a0 int // go语句结尾不用写封号
    b, c := "4", "5"
    // go语言中不允许定义了变量而不使用,否则编译不通过
    fmt.Println(a, a0, b, c)
    // 常量可以定义而不使用
    const d = "cc"

    println(&x, x)
    x := "yy"
    println(&x, x)

    {
        // 不同作用域可重新定义变量
        b, c := "6", "7"
        fmt.Println(b, c)
    }

    // 对err进行退化赋值处理
    f, err := os.Open("/opt/file/test.txt")
    buf := make([]byte, 1024)
    n, err := f.Read(buf)
    println(err, n)
}

func defReference() {
    // 数组定义(第一次看到时语法有点不太能接受)
    s := []int{1, 2, 3, 4}
    s = append(s, 5)
    // 切片语法和python完全一样
    fmt.Println(s[1:])
    // map的语法
    m := make(map[string]int)
    m["a"] = 1
    // 判断map是否包含某个元素
    if _, ok := m["b"]; ok {
        // do nothing
    } else {
        m["b"] = 2
    }
    fmt.Println(m)
}

/**
 * go语言中为啥要保留struct这个结构体呢,有点不太明白,数据结构java中一般都是定义个class解决的
 *
 */
func defType() {
    type (
        user struct {
            name string
            age  uint8
        }
        event func(string) bool
    )

    u := user{"tom", 20}
    fmt.Println(u)

    var f event = func(s string) bool {
        println(s)
        return s != ""
    }

    f("abc")
}

func main() {
    //defVar()
    defReference()
    defType()
}

go函数

  • go的25个关键字如下:
  • break,default,func,interface,select,case,defer,go,map,struct,chan,else,goto,package,switch,const,fallthrough,if,range,type,continue,for,import,return,var
  • 其中与java有差异的func方法/select(信道)/fallthrough(控制语句) map/struct/const/range/var(变量和数据) defer(延迟)/go(协程)/chan()

import (
    "errors"
    "fmt"
    "runtime/debug"
)

func defIncrement() {
    a := 1
    //++a  // 前置的方式go取消了
    a++
    p := &a // 将a的地址赋给p
    *p++    // 类似于c的指针操作语法
    fmt.Println(a)
    /**
     * & 取地址运算符 - 用于获取对象地址
     * * 指针运算符 - 间接引用目标对象
     * **T 二级指针
     */
}

func defInit() {
    // 定义一个结构体数据类型
    type student struct {
        name   string
        height int
        age    int
    }
    // 使用花挂号来初始化结构体
    var joey student = student{"joey", 120, 5}
    judy := student{"judy", 115, 5}
    fmt.Println(joey)
    fmt.Println(judy)
}

func defArr() {
    // array定义 []int{} 这种方式
    c := []int{1, 2, 3}
    d := []int{1, 2, 3, 4, 5}
    fmt.Println(c, d)
}

func defIf() {
    // if-else if-else 流程和Java一样,只是可省略括号
    var age int = 6
    if age < 7 {
        fmt.Println("学龄前")
    } else if 7 <= age && age < 13 {
        fmt.Println("小学生")
    } else {
        fmt.Println("其他")
    }
    if age++; age >= 7 {
        fmt.Println("小学生及以上")
    }
    // go语言不支持以下的三元运算符
    //a := (age>=7 ? "":"")
    //省略: go的switch和其他语言的差异在于只要case执行成功就不会执行后面的语句,只有case全失败才会执行default,更符合普通使用的判断场景[备注:fallthrough强制进入下一个判断流程],不过我推测应该使用的很少,省略这部分
}

func defFor() {
    // go中只有for循环,没有while和do-while.
    for i := 0; i < 3; i++ { // 普通的for循环
        fmt.Println(i)
    }
    x := 0
    for x < 10 { // 类似于while(x<10){}
        x++
    }
    for { // while(true){}
        break
    }
    // for range
    data := []string{"a", "b", "c"}
    for i, s := range data {
        fmt.Println(i, s)
        if i == 0 {
            data[0] = "b"
        }
    }

    // range会复制目标数据,循环时数组发生变化变量不变
    m := [3]int{10, 20, 30}
    for i, x := range m {
        if i == 0 {
            m[0] += 100
            m[1] += 200
            m[2] += 300
        }
        //x: 10,data: 110
        //x: 20,data: 220
        //x: 30,data: 330
        fmt.Printf("x: %d,data: %d\n", x, m[i])
    }

}

// func不支持嵌套
func add(x, y int) int {
    return x + y
}

func exec(f func(x, y int) int, x int, y int) int {
    return f(x, y)
}

// 指针是go与其他语言最显著的区别
func testPointer() *int{
    a := 10
    return &a
}

// 匿名函数, 和js基本一样
func testAnonymous(){
    func(s string){
        fmt.Println(s)
    }("test it")
    add := func(x, y int) int {
        return x+y
    }
    fmt.Println(add(1,2))
}

// 闭包closure,defer todo:暂时省略

// 错误处理 error handle
// 此处的error为官方接口
func div(x, y int)(int, error){
    if y == 0{
        return 0, errors.New("divide by zero")
    }
    return x/y, nil
}

// panic-recover-类似于try...catch...,但是感觉比try catch难用很多
func testPanic(){
    defer func(){
        if err:=recover();err!=nil{
            debug.PrintStack()
        }
    }()
    panic("holy shit")
    // 下面这句执行不到了
    fmt.Println("test shit")
}


func main() {
    defIncrement()
    defInit()
    defArr()
    defIf()
    defFor()
    fmt.Println(exec(add, 1, 2))
    testAnonymous()
    res,err := div(1,0)
    fmt.Println(res, err)
    testPanic()
}

数据类型

  • 数据类型:包含array,slice,map,struct

    
    func defStruct(){
      // 定义了一个会员,包含name/age/idNo/mobileNo/registerDate字段
      type Member struct{
          name string
          age int
          idNo string
          mobileNo string
          registerDate string
      }
      zhangsan := Member{"Zhang San",20,"310xxxxxx","+86-11111111111","2022-03-15 10:10"}
      fmt.Println(zhangsan)
      var lisi Member
      lisi.name = "Li Si"
      lisi.age = 21
      lisi.idNo = "333xxxxxx"
      lisi.mobileNo = "+86-1234567890"
      lisi.registerDate = "2022-05-15 00:00"
      fmt.Println(lisi)
      // 定义struct指针
      var zhangsanCopy *Member
      zhangsanCopy = &zhangsan
      fmt.Println(zhangsanCopy)
    }
    
    // 切片-slice和python中的类似,string/数组使用[:]这种格式
    func defSlice(){
      var nums [] int
      fmt.Println(nums, len(nums), cap(nums))
      nums = append(nums, 0)
      nums = append(nums, 1)
      nums = append(nums, 2)
      nums = append(nums, 3,4)
      /* 创建切片 numbers1 是之前切片的两倍容量*/
      nums2 := make([]int, len(nums), (cap(nums))*2)
      //复制数组nums熬nums2
      copy(nums2,nums)
      fmt.Println(nums2, len(nums2), cap(nums2))
    
    }
    
    // map和python中的基本一致
    func defMap(){
      // 初始化方式1: map初始化为nil
      var memberIdMap map[string]string
      memberIdMap = make(map[string]string)
      memberIdMap["zhangsan"] = "310xxxxxx"
      memberIdMap["lisi"] = "333xxxxxx"
      fmt.Println(memberIdMap)
      // 初始化方式2
      testMap := map[string]string{"a":"1","b":"2","c":"3"}
      for key:= range testMap{
          fmt.Println(key, testMap[key])
      }
      // 删除元素
      delete(testMap, "a")
    }
    
    func main(){
      defStruct()
      defSlice()
      defMap()
    }

    并发

    *

    测试

    *

无标签
评论区
暂无评论
avatar