符文与字符串范围内的字节

看起来当我们是range一个字符串时,我们得到的字符是rune类型,但是如果我们通过 获取它str[index],它们将是byte类型,为什么呢?



饮歌长啸
浏览 117回答 3
3回答

慕哥9229398

对于第一级,原因是因为这就是语言的定义方式。String类型告诉我们:字符串值是一个(可能为空)字节序列。字节数称为字符串的长度,并且永远不会是负数。字符串是不可变的:一旦创建,就不可能更改字符串的内容。和:字符串的字节可以通过整数索引 0 到 len(s)-1 来访问。同时,range是一个可以插入到for语句中的子句,并且规范说:“range”子句右边的表达式称为范围表达式,它可以是... [a] string ...和:对于字符串值,“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不会修改它,编译器可以优化掉副本。

慕虎7371278

只是一个快速而简单的答案,说明为什么以这种方式定义语言。想想符文是什么。Arune代表一个Unicode码点,可以由多个字节组成,根据编码的不同也有不同的表示形式。现在想想mystring[i]如果返回 arune而不是 a ,那么这样做意味着什么byte。由于如果不扫描字符串就无法知道每个符文的长度,因此该操作需要每次扫描整个字符串,从而使类似数组的访问需要 O(n) 而不是 O(1)。mystring[i]如果每次都扫描整个字符串,对于该语言的用户来说是非常违反直觉的,对于语言开发人员来说也更加复杂。这就是为什么大多数编程语言(如 Go、Rust、Python)区分 Unicode 字符和字节,有时仅支持字节索引。当从字符串的开头迭代时,一次访问一个字符串rune要简单得多,例如使用range.&nbsp;可以扫描连续的字节并将其分组在一起,直到它们形成可以作为 返回的有效 Unicode 字符rune,然后继续处理下一个字节。

芜湖不芜

只是让你知道。如果您想使用经典的 for循环迭代string并使用运算符[]来获取rune,您可以执行以下操作:{&nbsp; rstr := []rune(MyString)&nbsp; for idx := 0; idx < len(rstr); idx++ {&nbsp; &nbsp; // code before...&nbsp; &nbsp; currentRune := rstr[idx]&nbsp; &nbsp; _ = currentRune // to avoid unused error&nbsp; &nbsp; // code after...&nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go