golang知识点

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/winter_wu_1998/article/details/89048816

GO 命令

  • go build
    • 只对main包下的文件有效
    • 在当前目录下生成可执行文件
      • 使用 -o 参数显式指定路径和文件名
    • 默认作用范围为当前文件夹,编译单个文件需指定文件名
  • go install
    • 编译和安装文件
      • main包文件安装到bin文件夹(.exe)
      • 普通包文件安装到pkg/$GOOS文件夹(.a)
  • go run
    • 编译和执行程序,不生成文件
  • go get
    • 获取远程代码包并安装
    • -v 显示过程
    • -u 强制用网络更新

基础语法

  • 包导入
// 相对路径导入 该文件同一目录的model模块
import "./model"
// 绝对路径导入 $GOPATH/pkg/$GOOS/url/model
import "url/model"

import (
	f "fmt"
	. "http"
	_ “sql" // 只想使用包中的init函数
)
  • 变量

    • := 赋值只能在函数内部,全局变量采用var n int = 1的方式
    • :=为初始化,只能对于同名变量出现一次,=为修改,可以出现多次
    • 交换值:a, b = b, a
    • 大写开头的变量名能被包外引用
  • 字符串不可变string[0] = 'a'编译错误

  • 别名

    • type Color int
    • type f func(a int) string
  • ++只能作为后缀,且不可赋值

    • a = b++语法错误
  • iota枚举

    • 自动从0开始累积
    var(
    	RED Color = iota //0
    	BLUE // 1
    	GREEN //2
    	)
    
  • 初始化

    // 数组
    a := [...]int{1,2,3}
    var a [3]int
    
    // 切片
    var slice []int
    slice := []int{1,2,3}
    slice := a[0:2] // 注意此时slice是一个切片类型
    slice := make([]int, 10) // 此时一个切片指针
    
    // 字典
    var nums map[string]int
    nums := make(map[string]int)
    rate := map[stirng]float64{"a":4.5, "bbc":3.0}
    
    // 结构体
    p := person{"Tom", 35}
    p:= person{age:35, name:"Tom"}
    p := new(person)
    
    // channel
    ch := make(chan int)
    s := make(chan string, 1)
    var ch chan float64
    
  • make一般只用于初始化map, slice, channel

  • 条件判断(if, switch)

if x > 10 {
    ...
}

// 初始化并判断
// 此时变量的作用域仅在判断块内
if val, ok := func(); ok {
    ...
}

// switch无需break,通过fallthrough执行后面的case
switch i {
    case 1:
    	...
    	fallthrought
	case 2:
    	...
}
  • 循环(for)
for i := 0; i < 10; i++{
	...
}

for i >= 0 {
    i--
    ...
}

for k,v := range map{
    ...
}

// 无限循环
for {
    ...
}
  • 函数

    // 如果显式指定返回值名,则不用写在return后
    // 此时单值也要加括号
    func Max(a, b int) (c int) {
        if (a > b) {
            c = a
        } else {
            c = b
        }
        return 
    }
    
    // 变参函数
    func cout(arg ...string) {
        for index, val := range arg {
            ...
        }
    }
    
    cout("qwe", "asd", "zxc")
    // 使用slice作为实参时
    cout(slice...)
    
  • defer

    • 函数return后执行
    • 多个defer逆序执行
  • channel, slice, map本身就是引用类型,传参时不用变为指针

字符串

// 字符串->byte切片
c := []byte(str)

// 字符串排序
s :=14325”
c := strings.Splite(s, "")
sort.Strings(c)
s = strings.Join(c, "")
  • strings包包含常用字符串函数
  • strconv包包含字符串和别的类型转换的函数

方法

func (s *Struct1)funcName(a,b int) (stringint) {
    ...
}
  • 方法不仅可以作用于自定义的struct上还可以作用域任意类型(int, string等)
    • 但要内置类型要起一个别名
  • 如果想要改变对象,方法应该作用于指针而不是对象本身
    • 可以把recevier当做方法的第一个参数
  • 匿名字段
    • 结构体中只有类型名而没有变量名的字段
    • 于是该结构体继承了内嵌的匿名字段的内部字段和方法
      • 以此可以模拟C++中的继承

接口

  • 通过接口可以实现泛型和多态

  • 空接口可以被任意类型实现

    • type empty interface{}
  • fmt.Println()****函数就是接受一个实现了String() **方法的接口

  • 类型断言

    // 判断某一接口变量否是某一类型
    // value的类型为实际类型
    type Element interface{}
    var element Element
    
    if value,ok := element.(int); ok {
        ...
    } else if value, ok := element.(string); ok{
        ....
    }
    
    // 上面的写法太麻烦了,可以使用switch-type
    switch value := element.(type) {
    case string:
        ...
    case int:
        ...
    }
    
    // 判断某一变量的类型是否实现了某一接口
    // val 是一个被某一类型附了值的接口类型变量
    var empty Empty
    if sv, ok = val.(empty); ok {
        ...
    }
    
  • 当结构变量作为函数形参时,储存的实际参数不可寻址

    • 所以当实际参数是用指针实现接口方法时,如果我们传入是一个实参变量而不是指针,就无法调用指针方法

panic和recover

反射

并发

  • goroutine

    • 协程由线程组成,在每个线程上进行多路复用
    • 因此比线程更高效和轻量
    • 协程不保证执行顺序
  • channel

    • 无缓存的协程是柱塞式的,必须等待两边都准备好才开始传递数据,否则休眠
    • 有缓存的协程只有当缓冲区写满时才休眠
    // 收
    val, ok := <-ch
    
    // 发
    ch <-5
    
    // 关闭通道(一般在函数返回时)
    // 只有发送方可以关闭
    defer close(ch)
    
    if v, ok := <- ch; ok {
        
    }
    
    // for-range可以自动检测通道的关闭
    for i:= range ch {
        ...
    }
    
    // 单向通道
    var send chan<- int
    var recv <-chan int
    
  • select监听channel

    • select默认阻塞,只有监听的channel中有发送或者接受数据时才允许
    • 如果设置default则不阻塞,默认执行default
    • 多个channel准备好时,随机选一个执行
    select{
        case <-ch1:
        	...
        case <-ch2:
        	...
    }
    

猜你喜欢

转载自blog.csdn.net/winter_wu_1998/article/details/89048816