亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

符文與字符串范圍內的字節

符文與字符串范圍內的字節

Go
飲歌長嘯 2023-07-31 16:37:57
看起來當我們是range一個字符串時,我們得到的字符是rune類型,但是如果我們通過 獲取它str[index],它們將是byte類型,為什么呢?
查看完整描述

3 回答

?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

對于第一級,原因是因為這就是語言的定義方式。String類型告訴我們:

字符串值是一個(可能為空)字節序列。字節數稱為字符串的長度,并且永遠不會是負數。字符串是不可變的:一旦創建,就不可能更改字符串的內容。

和:

字符串的字節可以通過整數索引 0 到 len(s)-1 來訪問。

同時,range是一個可以插入到for語句中的子句,并且規范說:

“range”子句右邊的表達式稱為范圍表達式,它可以是... [a] string ...

和:

  1. 對于字符串值,“range”子句從字節索引 0 開始迭代字符串中的 Unicode 代碼點。在連續迭代中,索引值將是連續 UTF-8 編碼代碼點的第一個字節的索引字符串和類型為 的第二個值rune將是相應代碼點的值。如果迭代遇到無效的 UTF-8 序列,則第二個值將為0xFFFDUnicode 替換字符,并且下一次迭代將在字符串中前進一個字節。

如果你想知道為什么語言是這樣定義的,你真的必須問定義者本身。但是,請注意,如果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不會修改它,編譯器可以優化掉副本。



查看完整回答
反對 回復 2023-07-31
?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

只是一個快速而簡單的答案,說明為什么以這種方式定義語言。

想想符文是什么。Arune代表一個Unicode碼點,可以由多個字節組成,根據編碼的不同也有不同的表示形式。

現在想想mystring[i]如果返回 arune而不是 a ,那么這樣做意味著什么byte。由于如果不掃描字符串就無法知道每個符文的長度,因此該操作需要每次掃描整個字符串,從而使類似數組的訪問需要 O(n) 而不是 O(1)。

mystring[i]如果每次都掃描整個字符串,對于該語言的用戶來說是非常違反直覺的,對于語言開發人員來說也更加復雜。這就是為什么大多數編程語言(如 Go、Rust、Python)區分 Unicode 字符和字節,有時僅支持字節索引。

當從字符串的開頭迭代時,一次訪問一個字符串rune要簡單得多,例如使用range. 可以掃描連續的字節并將其分組在一起,直到它們形成可以作為 返回的有效 Unicode 字符rune,然后繼續處理下一個字節。


查看完整回答
反對 回復 2023-07-31
?
蕪湖不蕪

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...

  }

}


查看完整回答
反對 回復 2023-07-31
  • 3 回答
  • 0 關注
  • 162 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號