3 回答

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超6個贊
對于第一級,原因是因?yàn)檫@就是語言的定義方式。String類型告訴我們:
字符串值是一個(可能為空)字節(jié)序列。字節(jié)數(shù)稱為字符串的長度,并且永遠(yuǎn)不會是負(fù)數(shù)。字符串是不可變的:一旦創(chuàng)建,就不可能更改字符串的內(nèi)容。
和:
字符串的字節(jié)可以通過整數(shù)索引 0 到 len(s)-1 來訪問。
同時,range
是一個可以插入到for
語句中的子句,并且規(guī)范說:
“range”子句右邊的表達(dá)式稱為范圍表達(dá)式,它可以是... [a] string ...
和:
對于字符串值,“range”子句從字節(jié)索引 0 開始迭代字符串中的 Unicode 代碼點(diǎn)。在連續(xù)迭代中,索引值將是連續(xù) UTF-8 編碼代碼點(diǎn)的第一個字節(jié)的索引字符串和類型為 的第二個值
rune
將是相應(yīng)代碼點(diǎn)的值。如果迭代遇到無效的 UTF-8 序列,則第二個值將為0xFFFD
Unicode 替換字符,并且下一次迭代將在字符串中前進(jìn)一個字節(jié)。
如果你想知道為什么語言是這樣定義的,你真的必須問定義者本身。但是,請注意,如果for
僅在字節(jié)范圍內(nèi)進(jìn)行調(diào)整,則您需要構(gòu)建自己的更高級的循環(huán)來在符文范圍內(nèi)進(jìn)行調(diào)整。鑒于這for ... range
?確實(shí)可以通過符文進(jìn)行操作,如果您想通過字符串中的字節(jié)進(jìn)行操作s
,您可以編寫:
for?i?:=?0;?i?<?len(s);?i++?{ ????... }
并輕松訪問s[i]
循環(huán)內(nèi)部。你也可以寫:
for?i,?b?:=?range?[]byte(s)?{ }
并在循環(huán)內(nèi)訪問索引i
和字節(jié)。b
(從 string 到 的轉(zhuǎn)換[]byte
,反之亦然,可能需要一個副本,因?yàn)?code>[]byte可以修改。但在這種情況下,range
不會修改它,編譯器可以優(yōu)化掉副本。

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超4個贊
只是一個快速而簡單的答案,說明為什么以這種方式定義語言。
想想符文是什么。Arune
代表一個Unicode碼點(diǎn),可以由多個字節(jié)組成,根據(jù)編碼的不同也有不同的表示形式。
現(xiàn)在想想mystring[i]
如果返回 arune
而不是 a ,那么這樣做意味著什么byte
。由于如果不掃描字符串就無法知道每個符文的長度,因此該操作需要每次掃描整個字符串,從而使類似數(shù)組的訪問需要 O(n) 而不是 O(1)。
mystring[i]
如果每次都掃描整個字符串,對于該語言的用戶來說是非常違反直覺的,對于語言開發(fā)人員來說也更加復(fù)雜。這就是為什么大多數(shù)編程語言(如 Go、Rust、Python)區(qū)分 Unicode 字符和字節(jié),有時僅支持字節(jié)索引。
當(dāng)從字符串的開頭迭代時,一次訪問一個字符串rune
要簡單得多,例如使用range
. 可以掃描連續(xù)的字節(jié)并將其分組在一起,直到它們形成可以作為 返回的有效 Unicode 字符rune
,然后繼續(xù)處理下一個字節(jié)。

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超7個贊
只是讓你知道。如果您想使用經(jīng)典的 for循環(huán)迭代string并使用運(yùn)算符[]來獲取rune,您可以執(zhí)行以下操作:
{
rstr := []rune(MyString)
for idx := 0; idx < len(rstr); idx++ {
// code before...
currentRune := rstr[idx]
_ = currentRune // to avoid unused error
// code after...
}
}
- 3 回答
- 0 關(guān)注
- 180 瀏覽
添加回答
舉報(bào)