27
Sep

GO语言学习笔记

【基础知识】

1.不能在一个目录里声明多个包

2.在同一行用,间隔声明多个变量或用var()在多行声明变量

3.用const声明常量,采用iota常量计数器

4.一般用int表示整型宽度,在32位系统下就是32位,64位系统下就是64位



【容器类型】

5.直接使用...让编译器计算数组长度声明:  arr := [...]int{1,2,3,4,5}


6.切片是引用类型,相当于没有长度的数组,除了短声明还可以可以用make声明:make([]Type, size, cap)

7.从数组中切片slice := arr[1:3]

8.追加切片数据slice = append(slice, []slice{}...),获得切片容量:cap()


9.创建Map短声明还可以可以用make函数:  m := make(map[keyType]ValueType),Map是引用类型

10.删除Map中的元素:  delete(m, key)

11.判断Map键值是否存在:  value, ok := m[key]

12.获得数组、切片、Map长度:  len()



【指针、结构体】

13.用new为所有类型创建指针(分配内存)并初始化:  p := new(string)


14.结构体的定义:  type name struct{}

15.匿名结构体:  s := struct{}{}

16.结构体的匿名字段可以用字段类型访问

17.结构体的比较可以直接用 == 或用反射: if reflect.DeepEqual(s1, s2) {}

18.结构体方法的定义: func (接收者 结构体类型) 方法名(参数列表) 返回值列表{}



【函数、包、流程控制、方法、接口】

19.可变参数的函数:  func f(args ...string)int{}  如果有其他参数,可变参数一定在最后

20.不同类型可变参数的函数:  func f(args ...interface)int{}

21.匿名函数常用于协程,首字母大写可见性为Public


22.使用package命名包,使用import导入包

23.包被导入时初始化函数优先执行:  init(){} 可以有多个,但初始化一次

24.包的匿名导入:  import _ 包名  仅执行包的init()


25.分支判断:  else if

26.选择语句: switch ... case ... default ;  并列case用,间隔;  使用fallthrough执行下一case;  

27.循环语句for不接表达式可以通过break跳出;  用continue跳过本次循环

28.用defer进行延迟调用函数和方法,并不影响变量赋值; defer栈是后进先出的

29.跳转执行:  goto label  ...  label:     ;  goto语句与标签之间不能有变量声明


30.不同结构体可以定义同名方法,但函数不可以同名

31.指针接收器对调用者可见,值接收器对调用者不可见

32.非结构体也可以定义方法,即类型上定义方法,方法的接收器类型定义和方法的定义应该在同一个包中


33.定义接口 type name interface{}

34.利用接口实现不同功能的方法就是多态

35.接口可以看成是type和value的组合,type是接口底层的具体类型,value是具体类型的值

36.空接口interface{}可以承载各种类型

37.接口类型断言可以使用.(type)

38.类型可以实现多个接口;接口也可以嵌套



【协程、通道、select】

39.启用协程:  go f()

40.休眠:  time.sleep(1 * time.Second)


41.定义通道:  var name chan type 或 name:=make(chan type, num) ; 

42.发送数据:  name <- data  ;   接收数据:  v := <- name  ;发送和接收数据是阻塞的

43.关闭通道:  close(name)  ;  判断通道是否关闭: v, ok := <-name

44.获取通道的长度和容量分别是len()、 cap()

45.只读通道:  <- chan  ;  只写通道  chan <-  ;先定义双向通道,然后再使用只读或只写通道

46.可以使用for range遍历通道

47.无缓冲通道必须准备好接收通道数据才不会造成死锁


48.等待一组任务结束再执行其他业务可以使用WaitGroup: var wg sync.WaitGroup

49.传入子协程数量:  wg.Add(3)  ; 阻塞:  wg.Wait()  ;  协程计数器-1操作  :  defer wg.Done()


50.在多个发送/接收通道操作中进行选择:  select ... case ... default  其中case表达式只能对通道进行写入或读取操作

51.利用select可以处理超时执行



【线程同步】

52.互斥锁在结构体中定义字段:  Mutex sync.Mutex  方法中在临界区使用  Mutex.Lock()  和  defer Mutex.Unlock() 进行加锁和解锁

53.读写锁:  rwMutex sync.RWMutex  写锁仍是Lock()和Unlock()  读锁使用RLock()和RUnlock()

54.创建条件变量:  var m sync.Mutex  cond := sync.NewCond(&m)

55.条件变量使用:  cond.L.Lock()  cond.Wait()  cond.Broadcast()  cond.L.Unlock()



【错误、异常】

56.实现Error() string方法的类型都可以当作一个错误类型; 利用errors.New()返回一个自定义错误

57.使用fmt.Errorf()返回格式化错误


58.错误指的是可能出现问题的地方出现了问题;而异常指的是不应该出现问题的地方出现了问题

59.程序执行没有意义的时候,可以触发异常:  panic()

60.当函数发生 panic 时,它会终止运行,在执行完所有的延迟函数后,程序返回到该函数的调用方。这样的过程会一直持续下去,直到当前协程的所有函数都返回退出,然后程序会打印出 panic 信息,接着打印出堆栈跟踪,最后程序终止。

61.可以捕获到 panic 信息:  err := recover()  recover用于重新获得 panic 协程的控制,必须在 defer 函数中才能生效

62.只有在相同的协程中调用 recover 才管用, recover 不能恢复一个不同协程的 panic



【函数类型、闭包】

63.可以给变量赋值函数  f := func(){}  该变量就是函数类型

64.函数参数和返回值都可以是函数类型,即函数可以被当作参数传递给其他函数,也可以作为另一个函数的返回值


65.当一个匿名函数所访问的变量定义在函数体外部时,就称这样的匿名函数为闭包



【静态类型、动态类型、反射、结构体中的Tag标签】

66.静态类型是变量声明时候的类型;动态类型声明:  var in interface{} 

67.每个接口变量实际上是由一pair对(type 和 data)组成,其中记录了实际变量的值和类型


68.使用reflect.TypeOf()获得interface{}具体的类型

69.使用reflect.ValueOf()获得interface{}具体的值

70.使用reflect.TypeOf().Kind()获得interface{}的种类,例如,判断是否是结构体:  if reflect.ValueOf(x).Kind() == reflect.Struct {

71.使用reflect.TypeOf(struct).NumField()获得结构体中字段的数量

72.使用reflect.TypeOf(struct).Field(i)获得结构体中字段的reflect.Value

73.反射可以将“接口类型变量”转换为“反射类型变量”:   使用reflect.TypeOf 或 使用reflect.ValueOf

74.反射可以将“反射类型变量”转换为“接口类型对象”:  v.Interface()  , 或进一步:  v.Interface().(float64)

75.修改“反射类型对象”:  reflect.TypeOf().SetFloat()  

76.如果要修改“反射类型对象”其值必须是可写的。检查是否可写:  reflect.TypeOf().CanSet()  

77.设置“反射类型对象”可写:  reflect.TypeOf(&c).Elem()  


78.在结构体字段最后增加 `json:"name"` ,可以使用omitempty忽略处理空值,即:  `json:"name, omitempty"`

79.获得json数据:  json.Marshal()

80.利用反射获得field:  reflect.TypeOf(obj).FieldByName("Name")

81.利用反射获得field:  reflect.ValueOf(obj).Type().Field(i)

82.利用反射获得field:  reflect.ValueOf(&obj).Elem.Type().Field(i)

83.获得Tag:  tag := field.Tag

84.获得键值对:  labelValue := tag.Get("label")

85.获得键值对:  labelValue, ok := tag.Lookup("label")


About Me

Nothing is impossible!

Friends
倩倩的网站儿子的网站丽丽
CATEGORIES
Tags
四舍五入GOBeatles想像冰雪奇缘北京编程SSL证书认知障碍Docker春天行政区域名列表域名体系nginxopen_basedir思维指令编程语言程序URL网站上线域名FTP云服务器搜索引擎JSCSS网页超链接聚合内容列表元素网页构成网站的构成网站的分类网站单标签HTML第一个网页简单网页博域科技2018香山春游AJAX字体PHP
Copyright©2022 王阳 版权所有  京ICP备14005672号-6