成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go 將增加內(nèi)置的零值標(biāo)識符 zero!

開發(fā) 前端
雖然在使用上,做了一定的使用場景的切分,也就是只有數(shù)組和結(jié)構(gòu)體類型使用 zero 標(biāo)識符。但對于寫 Go 用戶而言,認(rèn)知上是會(huì)存在明確混淆的。以后你給其他同學(xué)解釋零值,解釋起得區(qū)分兩種場景來介紹。我感覺還不如 zero 標(biāo)識符一統(tǒng)零值天下。但很可惜,本次提案暫時(shí)并沒有這個(gè)計(jì)劃。

大家好,我是煎魚。

大家學(xué)習(xí)和使用 Go 語言時(shí),有一個(gè)神奇的概念:零值(zero-values)。零值這個(gè)名字是具體誰起的,又是從哪里先開始喊起的,已經(jīng)難以考究了。

每次有新同學(xué)剛開始轉(zhuǎn)語言,工程上總會(huì)提到這個(gè),想要試圖改變零值。又或是沒考慮到,一旦程序用了 0 作為 default 值,又要兼容零值的問題。

今天給大家分享一個(gè)關(guān)于零值的新提案,目測已經(jīng)八九不離十了(在發(fā)布此文時(shí),該提案已被正式 accepted)。

圖片圖片

快速復(fù)習(xí)零值

基礎(chǔ)類型的例子如下:

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

輸出結(jié)果:

0 0 false ""

復(fù)合類型的例子如下:

type Person struct {
 Name   string
 Age    int
 Weight float64
}

func main() {
 var p Person
 var m map[int]string
 var s []string

 fmt.Printf("%#v\n%#v\n%#v\n", p, m, s)
}

輸出結(jié)果:

main.Person{Name:"", Age:0, Weight:0}
map[int]string(nil)
[]string(nil)

類型和零值的映射表格如下:

數(shù)據(jù)類型

零值

int, int8, int16, int32, int64

0


uint, uint8, uint16, uint32, uint64

0

uintptr

0

float32, float64

0

byte

0

rune

0

string

"" (empty string)

complex64, complex128

(0,0i)

arrays of non-nillable types

array of zero-values

arrays of nillable types

array of nil-values

新提案:預(yù)聲明標(biāo)識符 zero

背景

事情的起因是:@Nathan Cormier 在社區(qū)提了吐槽和提案《proposal: builtin: zero function[1]》:

圖片圖片

他表示:Go 語言目前提供了幾種獲取類型零值的方法,如果能有一種統(tǒng)一的方法來實(shí)現(xiàn)這一點(diǎn),代碼的可讀性會(huì)更高。

有同學(xué)深思,哪來的幾種?其實(shí)可以:

var z MyType
return z

還可以:

return *new(MyType)

初始化結(jié)構(gòu)體后出來的都是零值。

緊接著就會(huì)遇到開頭提到的問題,你怎么知道這是零值,還是缺省值?難以直接判別。

更重要的是,這不太符合 Go 的設(shè)計(jì)哲學(xué),又是多種途徑,還和缺省值產(chǎn)生混淆。顯然和主打工程的 Go 的發(fā)展路子不合。

解決方案

新增 zero 標(biāo)識符

這次經(jīng)過一番撕扯,最終是由 Go 核心團(tuán)隊(duì)負(fù)責(zé)人 @Russ Cox 出來主持大局,提出了新提案并一路向前。

圖片圖片

Go 將會(huì)增加一個(gè)新的預(yù)定義標(biāo)識符 zero,它是一個(gè)無類型的零值,適用于數(shù)組和結(jié)構(gòu)體類型。

以下是 zero 的類型簽名:

// zero is a predeclared identifier representing the zero value
// for array and struct types.
var zero Type

他不會(huì)像 nil 一樣。我們可以對照看看 nil 的類型簽名:

// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type

Nil 受限于 chan、func、interface、map、slice、pointer 等類型。

zero 可賦值性規(guī)則

zero 的可賦值性規(guī)則如下:

  • 絕大部分場景下,zero 可以分配給任何類型 T 的任何變量。(T 指的是結(jié)構(gòu)體)
  • 不可以的場景,已經(jīng)具有短零(指的是:0、“”、nil)的變量,不可以分配。
  • 泛型場景下,即使 T 是帶有 any 約束條件的類型參數(shù),也是可以分配的。
  • 上述提到的可賦值性,包含函數(shù)參數(shù)和返回值,例如:f(zero) 和 return zero, err 也是正常有效的,也能夠用于值比較。

可能會(huì)有的同學(xué)擔(dān)心,zero 和短零(0, "", or nil)產(chǎn)生沖突。對此可以放心。在設(shè)計(jì)的規(guī)則上:zero 在短零有效的任何地方都無效,所以在使用上不會(huì)產(chǎn)生混淆。

解決了什么問題

實(shí)際問題上,解決了以下幾點(diǎn):

  • 在通用代碼中需要引用零值,發(fā)現(xiàn)大家經(jīng)常建議使用 *new(T) 來做初始化。導(dǎo)致經(jīng)常要向新用戶解釋這一點(diǎn)非常麻煩。Go 需要更簡潔的方法。
  • 在泛型代碼中便于與零值比較,在 cmp: add Or[2] 中出現(xiàn)了這一實(shí)際編碼訴求。
  • 縮短錯(cuò)誤返回,新的 return zero, err 會(huì)比原有的 return time.Time{}, err 更好。

通用概念來講:

  • 零值是 Go 中的一個(gè)重要概念。但某些類型對此還沒有具體的名稱,現(xiàn)在可以叫他 zero。
  • Go 需要一個(gè)機(jī)制來將其值和零值進(jìn)行比較,來解決前文提到的缺省值和零值無法很好識別的問題。

一些問題和爭論

會(huì)有同學(xué)認(rèn)為,現(xiàn)有的 return _, _, err 會(huì)比 return zero, zero, err 更短并且感覺更好。(但在清晰程度上會(huì)不如 zero 和 nil)

也有同學(xué)會(huì)認(rèn)為自己寫一個(gè)這個(gè)實(shí)現(xiàn)也很簡單,是否有必要為此專門增加一個(gè) zero 預(yù)定義值?

可以用泛型如下實(shí)現(xiàn):

func Zero[T any]() T {
    var v T
    return v
}

對此在很多提案上,都很容易陷入怪圈。有了泛型后,照實(shí)現(xiàn)來講,什么都可以自己寫一份。

也會(huì)有一派認(rèn)為以后判斷錯(cuò)誤類型要變成:

if err != zero {
  ...
}

會(huì)非常奇怪。以后可能會(huì)出現(xiàn) if err != nil 和 if err != zero 的奇怪代碼場景。

注:這個(gè)場景是假定 zero 標(biāo)識符能適用于所有的數(shù)據(jù)類型下才會(huì)出現(xiàn)。本次并不存在。

總結(jié)

目前的社區(qū)討論比較發(fā)散,認(rèn)為 zero 標(biāo)識符未來也可以取代所有的零值。但從提案內(nèi)容和提交的 SPEC CL 來看,@Russ Cox 一直針對的是數(shù)組和結(jié)構(gòu)體的零值場景去使用 zero 標(biāo)識符。

這個(gè)提案已經(jīng)進(jìn)入到最終階段,已經(jīng)被正式接受,基本跑不了了。

圖片圖片

以后我們在不同類型下對零值判斷,可以基于:

數(shù)據(jù)類型

使用什么作為零值

int 等數(shù)字類型

使用 0

string 字符串類型

使用 ”“(空字符串)

slice, map, function, pointer, channel, and interface 等類型

使用 nil

array 和 struct 類型

可使用 zero 標(biāo)識符

雖然在使用上,做了一定的使用場景的切分,也就是只有數(shù)組和結(jié)構(gòu)體類型使用 zero 標(biāo)識符。但對于寫 Go 用戶而言,認(rèn)知上是會(huì)存在明確混淆的。

以后你給其他同學(xué)解釋零值,解釋起得區(qū)分兩種場景來介紹。我感覺還不如 zero 標(biāo)識符一統(tǒng)零值天下。但很可惜,本次提案暫時(shí)并沒有這個(gè)計(jì)劃。

參考資料

[1]proposal: builtin: zero function: https://github.com/golang/go/issues/60695

[2]cmp: add Or: https://github.com/golang/go/issues/60204#issuecomment-1550369151

責(zé)任編輯:武曉燕 來源: 腦子進(jìn)煎魚了
相關(guān)推薦

2025-01-26 10:35:42

Go語言類型

2009-09-23 10:41:10

對象標(biāo)識符Hibernate

2012-02-08 14:01:18

HibernateJava

2009-08-26 14:01:18

C#標(biāo)識符

2024-06-05 08:47:20

Go語言方式

2022-07-17 06:57:02

時(shí)間戳唯一標(biāo)識符

2009-10-27 14:20:37

VB.NET動(dòng)態(tài)標(biāo)識符

2017-04-21 12:30:45

AndroidAndroid O設(shè)備標(biāo)識符

2009-07-21 12:59:25

Scala標(biāo)識符

2011-03-14 10:17:40

JavaScript

2023-05-28 00:09:21

2010-01-15 18:17:39

VB.NET動(dòng)態(tài)標(biāo)識

2009-12-08 19:29:10

PHP生成唯一標(biāo)識符

2009-06-26 18:07:12

JSF客戶端標(biāo)識符

2023-09-26 07:28:47

2021-09-18 10:24:08

DjangoRedis緩存后端

2024-05-09 08:00:00

2024-04-07 00:00:02

Android設(shè)備標(biāo)識符

2009-07-09 17:02:04

JDK學(xué)習(xí)筆記數(shù)據(jù)類型

2023-03-13 10:01:27

Java注釋
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲狠狠 | 四虎影视免费在线 | 一级片免费在线观看 | 亚洲天堂男人的天堂 | 国产日韩在线观看一区 | 日韩在线视频免费观看 | 欧美aⅴ片 | 在线小视频 | 一区精品视频在线观看 | 九九热在线免费视频 | 91精品国产综合久久久久蜜臀 | 国产精品日日夜夜 | 91免费在线看 | 中文视频在线 | 欧美精品久久久久 | 国产精品区二区三区日本 | 欧美激情一区二区三区 | 国产盗摄视频 | 性一爱一乱一交一视频 | 亚洲激情专区 | 中国大陆高清aⅴ毛片 | 综合久久一区 | 久久久久久中文字幕 | 成人免费观看男女羞羞视频 | 黄色片亚洲 | 荷兰欧美一级毛片 | 精品香蕉一区二区三区 | 色精品| 日本xx视频免费观看 | 国产国产精品 | 很很干很很日 | 亚洲视频一区在线 | 综合另类 | 一区二视频 | 午夜精品久久久久久久久久久久久 | 日日摸夜夜爽人人添av | 亚洲综合色视频在线观看 | 午夜综合 | 亚洲精品在线看 | 日韩欧美国产精品 | 欧美精品一区二区三区蜜桃视频 |