下面的代碼
const s = "golang.go"
var a byte = 1 << len(s) / 128
的結果a是4。然而,改變后const s,以var s如下
var s = "golang.go"
var a byte = 1 << len(s) / 128
現在的結果a是0。
還有其他測驗代碼如下
const s = "golang.go"
var a byte = 1 << len(s) / 128 // the result of a is 4
var b byte = 1 << len(s[:]) / 128 // the result of b is 0
var ss = "golang.go"
var aa byte = 1 << len(ss) / 128 // the result of aa is 0
var bb byte = 1 << len(ss[:]) / 128 // the result of bb is 0
奇怪的b是,在評估長度時為 0s[:]
我試著按照golang 規范來理解它
如果 s 是字串常量,則運算式 len(s) 是常量。如果 s 的型別是陣列或指向陣列的指標,并且運算式 s 不包含通道接收或(非常量)函式呼叫,則運算式 len(s) 和 cap(s) 是常量
但我失敗了。有人可以向我解釋得更清楚嗎?
uj5u.com熱心網友回復:
不同的是whens是constant,運算式作為常量運算式被解釋和執行,使用無型別整數型別并產生int型別。當s是變數時,運算式被解釋和執行為非常量運算式,使用byte型別。
規格: 操作員:
移位運算式中的右運算元必須具有整數型別或者是可由 type 值表示的無型別常量
uint。如果非常量移位運算式的左運算元是無型別常量,則首先將其隱式轉換為如果移位運算式僅被其左運算元替換時所假定的型別。
當s是變數時,參考部分適用。該運算式是一個非常量移位運算式 ( 1 << len(s)) 因為s是一個變數(所以len(s)是非常量),并且左運算元是一個無型別常量 ( 1)。So1被轉換為如果移位運算式被單獨的左運算元替換它會假設的型別:
var a byte = 1 << len(s) / 128
替換為
var a byte = 1 / 128
在此變數宣告byte中將使用型別,因為該型別用于變數a。所以回到原來:byte(1)左移9將是0,除以它128也將是0。
而 whens是常量,int會被使用,因為Spec: Constant 運算式:
如果常量移位運算式的左運算元是無型別常量,則結果為整型常量;否則它是一個與左運算元相同型別的常量,它必須是整數型別。
這里1不會轉換為byte但1 << len(s)=>1 << 9將是512,除以128將是4。
uj5u.com熱心網友回復:
在 Go 中 Constant 的行為與您預期的不同。它們是“任意精度和 _un_typed”。
用const consts = "golang.go"表達1 << len(consts) / 128為常量運算式和評價為以任意精度導致的常量運算式無型別整數4,其可以被分配到產生一個位元組a == 4。
與var vars = "golang.go"表達1 << len(vars) / 128不再是常數的表達,但必須被評價為一些型別化的中間體 如何在https://go.dev/ref/spec#Operators 中定義
移位運算式中的右運算元必須是整數型別或者是可由 uint 型別的值表示的無型別常量。如果非常量移位運算式的左運算元是無型別常量,則首先將其隱式轉換為如果移位運算式僅被其左運算元替換時所假定的型別。
第二句話適用于您的問題。將1被轉換為“它將[讀取將]假定型別”。拼出byte(1) << len(vars)這是 0。
https://go.dev/blog/constants
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/369724.html
