Go的内置函数与递归函数

Go的内置函数

  • close 主要用来关闭channle
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    func main() {
    // 定义一个channel 长度为10 也可以不定义长度 make(chan int)
    ch := make(chan int, 10)
    ch <- 1
    ch <- 2
    /*
    有关 channel 的关闭,你需要注意以下事项:
    关闭一个未初始化(nil) 的 channel 会产生 panic
    重复关闭同一个 channel 会产生 panic
    向一个已关闭的 channel 中发送消息会产生 panic
    从已关闭的 channel 读取消息不会产生 panic,且能读出 channel 中还未被读取的消息,若消息均已读出,则会读到类型的零值。从一个已关闭的 channel 中读取消息永远不会阻塞,并且会返回一个为 false 的 ok-idiom,可以用它来判断 channel 是否关闭
    关闭 channel 会产生一个广播机制,所有向 channel 读取消息的 goroutine 都会收到消息
    */
    // 关闭了channel
    close(ch)
    for v := range ch {
    fmt.Println(v)
    }

    // 消息被读完 这里读到0值
    x, ok := <-ch
    fmt.Println(x, ok)
    }
  • len:用来求长度,比如:string、array、slice、map、channel
  • new:用来分配内存,主要用来分配值类型,比如:int、struct,返回的是指针
  • make:用来分配内存,主要用来分配引用类型,比如:chan、map、slice
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    func main() {
    // new 主要用来分配值类型 返回的是指针 如果创建slice等引用类型 并不会初始化
    s1 := new([]int)
    // make 用来分配引用类型
    s2 := make([]int, 10)

    s3 := new(int)

    s4 := new(chan int)

    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println(*s3)
    fmt.Println(*s4)
    fmt.Println("----------")

    // 这里s1并没有被初始化
    // (*s1)[0] = 1 如果不初始化 直接赋值会报错 error
    *s1 = make([]int, 10)
    (*s1)[0] = 1
    fmt.Println(s1)
    s2[0] = 1
    fmt.Println(s2)
    }
  • append:用来追加元素到数组、slice中
  • panic和recover:用来做错误处理
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    func initConfig() error {
    // 返回一个自定义error
    return errors.New("init config error")
    }

    func test() {
    // defer的触发时机:
    // 1. 包裹defer的函数返回时
    // 2. 包裹defer的函数执行到末尾时
    // 3. 包裹defer的函数发生panic时
    defer func() {
    // 捕获panic
    if err := recover(); err != nil {
    fmt.Println(err)
    }
    }()

    err := initConfig()
    if err != nil {
    panic(err)
    }
    }

    func main() {
    test()
    }

    递归函数

  • 阶乘
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    func calc(n int) int {
    fmt.Println(n)
    if n == 1 {
    return 1
    }

    return calc(n-1) * n
    }
    func main() {
    fmt.Println(calc(5))
    }
    图例:
    示例代码执行流程
  • 斐波那契数列
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    func fab(n int) int {
    if n <= 1 {
    return 1
    }

    return fab(n-1) + fab(n-2)
    }

    func main() {
    for i := 0; i < 6; i++ {
    fmt.Printf("%d,", fab(i))
    }
    }