Go 语言中什么是零值?

reallyli · · 442 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

template.png

今天是《有个小问题》系列第一期,我们一起先来看看 Go 语言规范中关于零值的规定。

当通过声明或调用 make 或 new 分配内存来存储一个值时,如果没有提供显式初始化,内存会被赋予一个默认的初始化。这种值的每一个元素都被设置为其类型的零值:布尔值为 false ,整数为 0 ,浮点数为 0.0 ,字符串为 "",指针、函数、接口、切片、 Channel 和 Map 为 nil 。这种初始化是以递归方式进行的,例如,如果没有指定值,结构数组中的每个元素的字段都会被清零。

前言

对于这种总是将一个值设置为已知默认值的属性对于程序的安全性和正确性是很重要的,同时也可以使程序看起来更简单更紧凑

这就是 Go 编程者所说的 “给你的代码结构一个有用的零值”。

例子1

下面是一个使用 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()
}

例子2

另一个有用的零值类型的例子是 bytes.Buffer。可以不进行显式初始化就开始读取或写入,请注意,io.Copy 需要一个 io.Reader 作为它的第二个参数,所以我们需要传递一个指向 b 的指针。

package main

import (
    "bytes"
    "io"
    "os"
)

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

对于切片来说它们的零值是 nil。这意味着你不需要显式地创建一个切片,你可以直接声明它。

package main

import (
    "fmt"
    "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 与上面两行注释类似,但不完全相同。这两种初始化切片零值还是有区别的。下面的代码输出 false
package main

import (
    "fmt"
    "reflect"
)

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

例子3

nil 指针的零值还有一种比较实用的用法是,对具有 nil 值的类型调用方法,可以用来简单地提供默认值。

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())
}

关于

关注博客看更多《有个小问题系列》

my_wechat.png


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:reallyli

查看原文:Go 语言中什么是零值?

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

442 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传