網(wǎng)上有很多關(guān)于pos機(jī)錯(cuò)誤代碼5,Go 的不可尋址值了解下的知識(shí),也有很多人為大家解答關(guān)于pos機(jī)錯(cuò)誤代碼5的問題,今天pos機(jī)之家(www.dsth100338.com)為大家整理了關(guān)于這方面的知識(shí),讓我們一起來看下吧!
本文目錄一覽:
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í),希望能夠幫助到大家!
