欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Go语言随笔(一些需要注意的小细节)

程序员文章站 2024-02-28 13:12:52
...

Go语言随笔(一些需要注意的小细节)

int类型是一个特殊的类型,在64位电脑上占8个字节,在32位电脑上占4个字节

基本数据类型

布尔类型

  1. 布尔类型数据与整型数据不能进行交换
  2. 声明的布尔类型默认为false

浮点型

  1. 浮点数字面量被自动类型推断为float64类型
  2. 两个浮点数之间不应该使用==或!=进行比较操作,应该使用math标准库

复数类型

  1. 复数类型有两种:complex64和complex128,复数在计算机中由两个浮点数表示,一个实部一个虚部
    1. complex64:两个float32组成
    2. complex128:两个float64构成
  2. 三个内置函数:
    1. complex():构造一个复数
    2. real():返回一个复数实部
    3. image():返回复数虚部

字符串

  1. 字符串是常量,可以直接通过索引访问其字节单位,但是不能修改
  2. 字符串尾部不包含NULL字符
  3. 基于字符串创建的切片和原字符串指向相同的底层字符数组,一样不能修改,对字符串的切片操作返回的子串仍是string,而非slice
    Go语言随笔(一些需要注意的小细节)

rune类型

  1. Go内置两种字符类型:
    1. 一种是byte的字节类类型(byte是uint的别名)
    2. 一种是Unicode编码的字符rune(rune是int32的别名,占用四个字节)
  2. Go语言默认的字符编码就是UTF-8类型的,如果需要特殊的编码转换,则使用Unicode/UTF-8标准包

指针

  1. Go语言支持多级指针**T
  2. Go不支持指针运算
  3. 函数中允许返回局部变量的地址
    • Go编译器使用栈逃逸机制将这种局部变量的空间分配在堆上
      func sum(a,b int) *int{
          sum := a + b
          return &sum //sum将分配在堆上
      }
      

切片

Go语言随笔(一些需要注意的小细节)

  • 切片支持的操作

    • 内置函数len()返回切片长度
    • 内置函数cap()返回切片底层数组容量
    • 内置函数append()对切片追加元素
    • 内置函数copy()用于复制一个切片
  • 切片:

    为什么用切片:

      1. 数组的容量固定,不能自动拓展。
    
      2. 值传递。 数组作为函数参数时,将整个数组值拷贝一份给形参。
    
      在Go语言当,我们几乎可以在所有的场景中,使用 切片替换数组使用。
    

    切片的本质:

      不是一个数组的指针,是一种数据结构体,用来操作数组内部元素。	runtime/slice.go	type slice struct {		
      										*p 
      										len
    

    切片的使用: cap
    }
    数组和切片定义区别:

      	创建数组时 [ ] 指定数组长度。
    
      	创建切片时, [] 为空,或者 ... 
    
      切片名称 [ low : high : max ]
    
      low: 起始下标位置
    
      high:结束下标位置	len = high - low
    
      容量:cap = max - low
    
      截取数组,初始化 切片时,没有指定切片容量时, 切片容量跟随原数组(切片)。
    
      	s[:high:max] : 从 0 开始,到 high结束。(不包含)
    
      	s[low:] :	从low 开始,到 末尾
    
      	s[: high]:	从 0 开始,到 high结束。容量跟随原先容量。【常用】
    

    切片创建:

      1. 自动推导类型创建 切片。slice := []int {1, 2, 4, 6}
    
      2. slice := make([]int, 长度,容量)
    
      3. slice := make([]int, 长度)		创建切片时,没有指定容量, 容量== 长度。【常用】	
    

    切片做函数参数 —— 传引用。(传地址)

    append:在切片末尾追加元素

      append(切片对象, 待追加元素)
    
      向切片增加元素时,切片的容量会自动增长。1024 以下时,一两倍方式增长。
    

    copy:

      copy(目标位置切片, 源切片)
    
      拷贝过程中,直接对应位置拷贝。
    
  • map:

    字典、映射 key —— value key: 唯一、无序。 不能是引用类型数据。

      	map 不能使用 cap()
    

    创建方式:
    1. var m1 map[int]string — 不能存储数据

      2. m2 := map[int]string{}		---能存储数据
    
      3. m3 := make(map[int]string)		---默认len = 0
    
      4. m4 := make(map[int]string, 10)
    

    初始化:

      1. var m map[int]string = map[int]string{ 1: "aaa", 2:"bbb"}	保证key彼此不重复。
    
      2. m := map[int]string{ 1: "aaa", 2:"bbb"}
    

    赋值:

      赋值过程中,如果新map元素的key与原map元素key 相同 	——> 覆盖(替换)
    
      赋值过程中,如果新map元素的key与原map元素key 不同	——> 添加
    

    map的使用:

      遍历map:
    
      	for  key值, value值 := range map {
    
      	} 
    
      	for  key值 := range map {
    
      	}	
    
      判断map中key是否存在。
    
      	 map[下标] 运算:返回两个值, 第一个表 value 的值,如果value不存在。 nil
      			
      				第二个表 key是否存在的bool类型。存在 true, 不存在false
    

    删除map:

      delete()函数: 	参1: 待删除元素的map	参2: key值
    
      delete(map, key)	删除一个不存在的key , 不会报错。
    
      map 做函数参数和返回值,传引用。
    

Switch

  • 在switch中加入了一个fallthough关键字,强制执行下一个case语句,不在判断下一个case子句的条件是否成立
  • switch后面可以加入一个初始化语句,用分号隔开
    switch i := "y"; i{
        case "y": ···
    }
    

函数

  1. 首字母大小写决定该函数在其他包是否可见:大写时其他包可见,小写时只有相同包可以访问
  2. 不支持默认值参数
  3. 不支持函数重载
  4. 不支持函数嵌套(除匿名函数外)

延迟调用函数—defer

  1. defer后面必须是函数或方法的调用
  2. defer函数的实参在注册时通过值拷贝传递进去
  3. defer函数的调用先进后出

panic和recover

  1. panic用来主动抛出错误,recover用来捕获panic抛出的错误
    panic(i interface{})
    recover() interface{}
  1. panic的参数是一个空接口类型interface{},所以任意类型的变量都可以传递给panic
  2. 发生panic后,程序就会从调用panic的函数位置或者发生panic的地方立即返回,逐层向上执行函数的defer语句,然后逐层打印函数调用堆栈,直到recover捕获或运行到最外层函数而退出
  3. recover()用来捕获panic,阻止panic继续向上传递。
  4. recover和defer一起使用,但是recover只有在defer后面的函数体内才能被直接调用才能捕获panic终止异常,否则返回nil,异常继续向外传递
    //这个会捕获失败
    defer recover()
    //这个才能调用成功
    defer func(){
        recover()
    }
  1. 包中init函数引发的panic只能在init函数中捕获,在main函数中无法被捕获,原因是init函数先于main函数执行