关于go:Go-的零值有什么用看看这-4-个场景

3次阅读

共计 1852 个字符,预计需要花费 5 分钟才能阅读完成。

大家好,我是煎鱼。

前文给大家分享了《10+ 条 Go 官网谚语,你晓得几条?》,明天进一步讲讲第 5 条谚语 Make the zero value useful(让零值变得有用),看看外面想的是什么意思。

背景

Go 语言中有一个有些非凡的概念,叫做零值。许多转语言的同学常常会弄混同,一开始会不适应。

代码如下:

func main() {
    var i int
    var f float64
    var b bool
    var s string
    fmt.Printf("%v %v %v %q\n", i, f, b, s)
}

输入后果:

0 0 false ""

这会导致大家在定义各种数据库字段时比拟纠结,又会说 Go 这零值,例如:整形的零值 0,跟数据库里的 0 枚举值抵触。又或是做入参判断时怎么区别开?

一时半会想不明确,为什么 Go 要定义这个零值来减少复杂度?

有什么用

官网诠释

Go 外围团队的 @Dave Cheney 在《What is the zero value, and why is it useful?》中对零值进行了具体的阐释。

将一个值设置为已知默认值的个性,对于程序的安全性和正确性十分重要。能够使你的 Go 程序更加简略和紧凑。这就是 Go 程序员常说的 “ 给你的构造一个有用的零值 ”。

官网案例

以下是 Go 官网给出的几个零值的例子,十分具备代表性。别离是:

  • sync.Mutex。
  • byte.Buffer。
  • nil func。

Sync.Mutex

sync.Mutex 被设计为 无需显式初始化就能够应用,能够实现这个性能的起因是 sync.Mutex 包 含两个未导出的整数字段。

用大白话讲,就是因为零值的存在,只有申明了 sync.Mutex,这些字段就会被设置为 0(值会被初始化)。

因而能够无需显式初始化就能够 开箱即用

如下代码:

package main

import "sync"

type MyInt struct {
        mu sync.Mutex
        val int
}

func main() {
        var i MyInt

        // i.mu is usable without explicit initialisation.
        i.mu.Lock()
        i.val++
        i.mu.Unlock()}

Byte.Buffer

因为有零值的存在,bytes.Buffer 在进行写入或读取的操作时,都不须要人为的进行明确的初始化。也能做到很好的开箱即用。

如下代码:

package main

import "bytes"
import "io"
import "os"

func main() {
        var b bytes.Buffer
        b.Write([]byte("Hello world"))
        io.Copy(os.Stdout, &b)
}

注:io.Copy 须要一个 io.Reader 作为它的第二个参数,所以咱们须要传递一个指向 b 的指针。

Slices

在 slices 的定义中,它的零值是 nil。这意味着你不须要显式定义一个 slices,只须要间接申明它,就能够应用了。

如下

package main

import "fmt"
import "strings"

func main() {// s := make([]string, 0)
        // s := []string{}
        var s []string

        s = append(s, "Hello")
        s = append(s, "world")
        fmt.Println(strings.Join(s, " "))
}

Nil func

你能够在有 nil 值的类型上调用办法,这也是零值作为缺省值的作用之一。

这个场景,甚至一度让许多 Go 程序员认为是 BUG,我还专门写过文章。这是可行,其实都是零值的延长进去的用法。

如下代码:

package main

import "fmt"

type Config struct {path string}

func (c *Config) Path() string {
        if c == nil {return "/usr/home"}
        return c.path
}

func main() {
        var c1 *Config
        var c2 = &Config{path: "/export",}
        fmt.Println(c1.Path(), c2.Path())
}

总结

零值,在 Go 里尽管是一个缺省值。但你它实质上不仅仅是一个缺省,它还为此在许多程序里的利用场景提供了不少的便捷个性,甚至是费解的性能。

心愿对你对零值的了解有进一步的帮忙!

Go 图书系列

  • Go 语言入门系列:初探 Go 我的项目实战
  • Go 语言编程之旅:深刻用 Go 做我的项目
  • Go 语言设计哲学:理解 Go 的为什么和设计思考
  • Go 语言进阶之旅:进一步深刻 Go 源码

更多浏览

  • Go 想要加个箭头语法,这下更像 PHP 了!
  • Go 错误处理新思路?用左侧函数和表达式
正文完
 0