教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 编程书说的“Go程序员应该让聚合类型的零值也具有意义”是在讲什么

编程书说的“Go程序员应该让聚合类型的零值也具有意义”是在讲什么

发布时间:2021-05-08   编辑:jiaochengji.com
教程集为您提供编程书说的“Go程序员应该让聚合类型的零值也具有意义”是在讲什么等资源,欢迎您收藏本站,我们将为您提供最新的编程书说的“Go程序员应该让聚合类型的零值也具有意义”是在讲什么资源

在《Go语言编程》这本书和很多其他Go 编程教程中很多都提到过“Go程序员应该让一些聚合类型的零值也具有意义”的概念,我们这篇文章主要说一下有意义的零值这个话题。

在 Go 中声明变量时如果初始化表达式被省略:

var 变量名字 类型 = 表达式

那么将用零值初始化变量。

以下是 Go 官方的语言参考对零值初始化机制的解释:

When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for numeric types, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.

当通过变量声明、调用new函数或者是通过符合字面量([]string{}, structType{}等形式)、调用 make 函数创建新值并且未显式的提供初始化时,变量或者值将被赋予默认值。变量或者值的每个元素将被赋予其类型的零值:布尔值为false,数字类型为0,字符串为“”,指针,函数,接口,切片,通道和映射为nil。该初始化是递归完成的,因此,例如,未指定任何值,一个结构体数组的每个元素的字段都将设置为字段类型的零值。

Go始终将值设置为已知默认值的特性对于程序的安全性和正确性很重要,也使Go程序更简单,更紧凑。这就是Go程序员在说“给你的结构体一个有用的零值”时谈论的内容。

下面是一个使用sync.Mutex的示例,该示例设计为无需显式初始化即可使用。 sync.Mutex包含两个未导出的整数字段:

type Mutex struct {
    state int32
    sema  uint32
}

由于零值机制的存在,每当声明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()
}

有用的零值的类型的另一个示例是bytes.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)
}

切片类型的零值为nil。这意味着你无需显式创建切片,只需声明它即可。

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, " "))
}

注意:var s [] string与它上面的两条注释行相似,但是不相同。可以通过程序检测出nil切片值与具有零长度的切片值之间的差别。以下代码将输出false。

package main

import "fmt"
import "reflect"

func main() {
        var s1 = []string{}
        var s2 []string
        fmt.Println(reflect.DeepEqual(s1, s2))
}

对于 nil 指针来说,你可以让你的程序允许在具有nil值的类型上调用方法。这可以用来简单地为方法提供有意义的默认返回值。比如下面的程序在 nil 指针上调用 Path方法是返回了/usr/home ,示例为了好理解只是简单输出了一下调用结果,但是在很多比示例更复杂的功能方法来说这比直接返回 string 的零值空字符对程序更有意义。

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程序员应该让聚合类型的零值也具有意义”是在讲什么”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
编程书说的“Go程序员应该让聚合类型的零值也具有意义”是在讲什么
Go 零基础编程入门教程
基于类型系统的面向对象编程语言Go
Go 语言到底适合干什么?
新手学python看哪本书
学习Python却没看过这几本书,你就OUT了
兄弟连golang神技(1)-关于 Go 语言的介绍
Go 语言十年而立,Go2 蓄势待发
[GO语言基础] 一.为什么我要学习Golang以及GO语言入门普及
go 函数末尾缺少返回值_王垠:Go语言野心勃勃,实际情况又如何

[关闭]
~ ~