3 回答

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

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

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