iven98

1. byte与rune 字符串

byte 占用1个字节,8个bit,范围为0->255(uint8)
rune 占用4个字节,32个bit,范围为0-2^32(int32)(字符集大,中文必须使用这个)

func main() {
    var a byte = 'A'
    var b rune = 'B'
    fmt.Printf("a 占用 %d 个字节数\nb 占用 %d 个字节数", unsafe.Sizeof(a), unsafe.Sizeof(b))
}
//1 4

字符串
一个英文字符占1个字节,一个中文字符占3个字节

//表示 \r\n 这个字符串
//解释型表示法
var str string = "\\r\\n"
//原生型表示法(不会根据转义字符解析)
var str string = `\r\n`
//使用%q还原原生型表示法
fmt.Printf("的解释型字符串是: %q", str)

2. go指针

创建方法

  • 定义变量取内存地址
a:=1
p=&a
  • 创建指针分配内存后,再给指针指向的内存写入值
str:=new(string)
*str="test"
  • 声明指针变量,从其他变量取地址并赋值
a:=1
var b *int
b=&a

& 在普通变量中取内存地址
* 该符号在赋值操作符的右边时,表示在指针变量在取得变量值,在左边是,是指指针指向的变量
打印内存地址

fmt.Printf("%p", p)
fmt.Println(p)

指针具有类型,比如string,int,*float64
指针的零值为nil
指针和切片都是引用类型,改变一个数组的值时,有两个方法:

  • 传入数组切片(推荐使用)
func modify(nums []int) {
    nums[0] = 90
}
func main() {
    nums := [3]int{89, 90, 91}
    modify(nums[:])
}
  • 传入数组指针
func modify(nums *[3]int) {
    (*nums)[0] = 90
}

func main() {
    nums := [3]int{89, 90, 91}
    modify(&nums)
}

3. select用法

func main() {
    c1 := make(chan string, 1)
    c2 := make(chan string, 1)
    timeout := make(chan bool, 1)

    go makeTimeout(timeout, 2)

    select {
    case msg1 := <-c1:
        fmt.Println("c1 received: ", msg1)
    case msg2 := <-c2:
        fmt.Println("c2 received: ", msg2)
    case <-timeout:
        fmt.Println("Timeout, exit.")
    }
}
//一直阻塞,导致超时
  1. select 只能用于 channel 的操作(写入/读出/关闭),而 switch 则更通用一些;
  2. select 的 case 是随机的,而 switch 里的 case 是顺序执行;
  3. select 要注意避免出现死锁,同时也可以自行实现超时机制;
  4. select 里没有类似 switch 里的 fallthrough 的用法;
  5. select 不能像 switch 一样接函数或其他表达式。

4. go异常机制

触发panic

panic("crash")

recover(),捕获panic信息并打印

defer func() {
        // recover() 可以将捕获到的panic信息打印
        if err := recover(); err != nil {
            fmt.Println(err)
        }
    }()

即使 panic 会导致整个程序退出,但在退出前,若有 defer 延迟函数,还是得执行完 defer 。
defer 在多个协程之间是没有效果,在子协程里触发 panic,只能触发自己协程内的 defer,而不能调用 main 协程里的 defer 函数的。
panic:抛出异常,使程序崩溃
recover:捕获异常,恢复程序或做收尾工作

5. 结构体

结构体可以继承

type Person struct {
    Name string
}
type Man struct {
    person
    age string
}

结构体中,属性名大写为Public,小写为Private
实例化方法:

  • 正常实例化
p:=Person{name:"xxx"}
  • 使用new
p:=new(Person)
p.name="xxx"
  • 使用&
var p *Person=&Person{}
p.name="xxx"
//等同于(*p).name="xxx"

从一个结构体实例对象中获取字段的值,通常都是使用 . 这个操作符,该操作符叫做 选择器。
可以直接省去 * 取值的操作,选择器 . 会直接解引用

相关文章: