pos機(jī)錯(cuò)誤代碼5,Go 的不可尋址值了解下

 新聞資訊  |   2023-05-17 09:19  |  投稿人:pos機(jī)之家

網(wǎng)上有很多關(guān)于pos機(jī)錯(cuò)誤代碼5,Go 的不可尋址值了解下的知識(shí),也有很多人為大家解答關(guān)于pos機(jī)錯(cuò)誤代碼5的問題,今天pos機(jī)之家(www.dsth100338.com)為大家整理了關(guān)于這方面的知識(shí),讓我們一起來看下吧!

本文目錄一覽:

1、pos機(jī)錯(cuò)誤代碼5

pos機(jī)錯(cuò)誤代碼5

Dave Cheney 在 Twitter 上發(fā)布過一個(gè) Go 的小測驗(yàn),和往常一樣,我從中學(xué)到了一些有趣的東西。讓我們從他的推文開始:

#golang 小測驗(yàn):該程序打印什么?

package mainimport (    "crypto/sha1"    "fmt")func main() {    input := []byte("Hello, playground")    hash := sha1.Sum(input)[:5]    fmt.Println(hash)}

令我驚訝的是,答案是:

./test.go:10:28: invalid operation sha1.Sum(input)[:5] (slice of unaddressable value)

我們收到此錯(cuò)誤有三個(gè)原因。首先,`sha1.Sum()`[1] 的返回值不尋常。大多數(shù)方法返回切片,而此代碼對(duì)切片不會(huì)報(bào)錯(cuò)。但是 sha1.Sum() 返回的值很奇怪,它是一個(gè)固定大小的數(shù)組(具體來說是 [20]byte ),由于 Go 是返回?cái)?shù)值的,這意味著它確實(shí)向 main() 返回了 20 字節(jié)的數(shù)組,而不是指向它的指針。

這就涉及到了不可尋址值的概念,與可尋址值相反。詳細(xì)的介紹在 Go 編程語言規(guī)范的 地址運(yùn)算符[2] 中。簡單來說,大多數(shù)匿名值都不可尋址( 復(fù)合字面值[3] 是一個(gè)大大的例外)。在上面的代碼中,sha1.Sum() 的返回值是匿名的,因?yàn)槲覀兞⒓磳?duì)其進(jìn)行了切片操作。如果我們將它存在變量中,并因此使其變?yōu)榉悄涿瑒t該代碼不會(huì)報(bào)錯(cuò):

tmp := sha1.Sum(input)hash := tmp[:5]

最后一個(gè)問題是為什么切片操作是錯(cuò)誤的。這是因?yàn)閷?duì)數(shù)組進(jìn)行切片操作要求該數(shù)組是可尋址的(在 Go 編程語言規(guī)范的 Slice 表達(dá)式[4] 的末尾介紹)。sha1.Sum() 返回的匿名數(shù)組是不可尋址的,因此對(duì)其進(jìn)行切片會(huì)被編譯器拒絕。

(將返回值存儲(chǔ)到我們的 tmp 變量中使其變成了可尋址。sha1.Sum() 的返回值在復(fù)制到 tmp后就消失了。)

雖然我不能完全理解為什么 Go 的設(shè)計(jì)師限制了哪些值是可尋址的,但是我可以想到幾條原因。例如,如果在這里允許切片操作,那么 Go 會(huì)默默地實(shí)現(xiàn)堆存儲(chǔ)以容納 sha1.Sum() 的返回值(然后將該值復(fù)制到另一個(gè)值),該返回值將一直存在直到那個(gè)切片被回收。

(如 x86-64 上的 Go 低級(jí)調(diào)用慣例[5] 中所述,由于 Go 返回了棧中的所有值,因此需要將數(shù)據(jù)進(jìn)行拷貝。對(duì)于 sha1.Sum() 的 20 字節(jié)的返回值來說,這并不是什么大事。我很確定人們經(jīng)常使用更大的結(jié)構(gòu)體作為返回值。)

PS:Go 語言規(guī)范中的許多內(nèi)容要求或僅對(duì)可尋址的值適用。例如,大多數(shù) 賦值[6] 操作需要可尋址性。

補(bǔ)充:方法調(diào)用和可尋址性

假設(shè)有一個(gè)類型 T,并且在 *T 上定義了一些方法,例如 *T.Op()。就像 Go 允許在不取消引用指針的情況下進(jìn)行字段引用一樣,你可以在非指針值上調(diào)用指針方法:

var x Tx.Op()

這是 (&x).Op() 的簡便寫法(在 Go 編程語言規(guī)范文中靠后的 調(diào)用[7] 部分進(jìn)行了介紹)。但是,由于此簡便寫法需要獲取地址,因此需要可尋址性。因此,以下操作會(huì)報(bào)錯(cuò):

// afunc() 返回一個(gè) Tafunc().Op()// 但是這個(gè)可以運(yùn)行:var x T = afunc()x.Op()

之前我已經(jīng)看到人們?cè)谟懻?Go 在方法調(diào)用上的怪癖,但是當(dāng)時(shí)我還不完全了解發(fā)生了什么,以及由于什么原因使方法調(diào)用無法正常工作。

(請(qǐng)注意,這種簡寫轉(zhuǎn)換與 *T 具有所有 T 方法是根本不同的,這在我 之前的一篇文章[8] 中提到過)

via: https://utcc.utoronto.ca/~cks/space/blog/programming/GoUnaddressableSlice

作者:Chris wSiebenmann[9]譯者:zhiyu-tracy-yang[10]校對(duì):polaris1119[11]

本文由 GCTT[12] 原創(chuàng)編譯,Go 中文網(wǎng)[13] 榮譽(yù)推出

參考資料

[1]

sha1.Sum(): https://golang.org/pkg/crypto/sha1/#Sum

[2]

地址運(yùn)算符: https://golang.org/ref/spec#Address_operators

[3]

復(fù)合字面值: https://golang.org/ref/spec#Composite_literals

[4]

Slice 表達(dá)式: https://golang.org/ref/spec#Slice_expressions

[5]

x86-64 上的 Go 低級(jí)調(diào)用慣例: https://science.raphael.poss.name/go-calling-convention-x86-64.html#arguments-and-return-value

[6]

賦值: https://golang.org/ref/spec#Assignments

[7]

調(diào)用: https://golang.org/ref/spec#Calls

[8]

之前的一篇文章: https://utcc.utoronto.ca/~cks/space/blog/programming/GoInterfacesAutogenFuncs

[9]

Chris wSiebenmann: https://utcc.utoronto.ca/~cks/space/People/ChrisSiebenmann

[10]

zhiyu-tracy-yang: https://github.com/zhiyu-tracy-yang

[11]

polaris1119: https://github.com/polaris1119

[12]

GCTT: https://github.com/studygolang/GCTT

[13]

Go 中文網(wǎng): https://studygolang.com/

私聊小編,領(lǐng)全套Go資料,每天學(xué)習(xí) Go 語言!

以上就是關(guān)于pos機(jī)錯(cuò)誤代碼5,Go 的不可尋址值了解下的知識(shí),后面我們會(huì)繼續(xù)為大家整理關(guān)于pos機(jī)錯(cuò)誤代碼5的知識(shí),希望能夠幫助到大家!

轉(zhuǎn)發(fā)請(qǐng)帶上網(wǎng)址:http://www.dsth100338.com/news/42780.html

你可能會(huì)喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 babsan@163.com 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。