什么是符文?

161 go rune

什么是runeGo?

我一直在谷歌搜索,但Golang只用一行说:rune是别名int32.

但是整个周围如何使用整数来交换案例?

以下是函数交换大小写.什么是<=-

为什么没有switch任何争论呢?

&&应该是说,但什么是r <= 'z'

func SwapRune(r rune) rune {
    switch {
    case 'a' <= r && r <= 'z':
        return r - 'a' + 'A'
    case 'A' <= r && r <= 'Z':
        return r - 'A' + 'a'
    default:
        return r
    }
}
Run Code Online (Sandbox Code Playgroud)

其中大多数来自http://play.golang.org/p/H6wjLZj6lW

func SwapCase(str string) string {
    return strings.Map(SwapRune, str)
}
Run Code Online (Sandbox Code Playgroud)

我理解这是映射runestring它可以返回交换的字符串.但我不明白这里到底有多精确runebyte有效.

top*_*kip 132

符文文字只是32位整数值(但它们是无类型常量,因此它们的类型可以更改).它们代表unicode代码点.例如,符文文字'a'实际上是数字97.

因此,您的程序几乎相当于:

package main

import "fmt"

func SwapRune(r rune) rune {
    switch {
    case 97 <= r && r <= 122:
        return r - 32
    case 65 <= r && r <= 90:
        return r + 32
    default:
        return r
    }
}

func main() {
    fmt.Println(SwapRune('a'))
}
Run Code Online (Sandbox Code Playgroud)

很明显,如果你要查看Unicode映射,它与该范围内的ASCII相同.此外,32实际上是字符的大写和小写代码点之间的偏移.因此,通过添加32'A',你'a',反之亦然.

  • 符文是int32值.这就是整个答案.它们不是_"映射"_. (21认同)
  • 这显然只适用于ASCII字符,而不适用于'ä'等加入字符,更不用说像'ı'(U + 0131)这样的更复杂的情况.Go具有映射到小写的特殊功能,例如`unicode.ToLower(r rune)符文`. (12认同)
  • 那么,符文类似于C字符? (3认同)
  • 并使用适用于所有代码点而不仅仅是az的SwapCase函数添加@topskip的正确答案:`func SwapRune(r rune)符文{if unicode.IsUpper(r){r = unicode.ToLower(r)} else { r = unicode.ToUpper(r)}; return r}` (2认同)

fab*_*ioM 42

来自Go lang发行说明:http://golang.org/doc/go1#rune

符文是一种类型.它占用32位,用于表示Unicode CodePoint.作为类比,以'ASCII'编码的英文字符集具有128个代码点.因此能够适合一个字节(8bit).从这个(错误的)假设C处理的字符为'字节' char,'字符串'作为'字符序列' char*.

但猜猜怎么了.除了'abcde ..'符号之外,人类还发明了许多其他符号.还有很多我们需要32位来编码它们.

在golang然后a string是一系列的bytes.但是,由于多个字节可以表示符文代码点,因此字符串值也可以包含符文.因此,它可以转换为a []rune,反之亦然.

unicode软件包http://golang.org/pkg/unicode/可以体验挑战的丰富性.

  • 使用最近的Unicode 6.3,定义了超过110,000个符号.这需要每个代码点至少21位表示,因此`rune`就像`int32`并且有很多位. (5认同)
  • 你说“一个`string`是一个`rune`s的序列”——我认为这不是真的?[Go blog](https://blog.golang.org/strings):“一个字符串就是一堆字节”;[Go lang spec](https://golang.org/ref/spec#String_types):“字符串值是一个(可能为空的)字节序列” (2认同)
  • @prvn但是,你不能说“不是字节”。然后,你可能会说:“字符串是由符文组成的,符文是由字节组成的”之类的。然后又。这并不完全正确。 (2认同)

Str*_*ork 25

我没有足够的声誉对fabrizioM的回答发表评论,所以我将不得不在此发布.

法布里奇奥的回答在很大程度上是正确的,他当然抓住了问题的本质 - 尽管必须要有区别.

字符串是不是一定符文的序列.它是"切片字节"的包装器,切片是Go数组的包装器.这有什么不同?

符文类型必须是32位值,这意味着符文类型的值序列必然具有一定数量的位x*32.字符串是一个字节序列,而是长度为x*8位.如果所有字符串实际上都是Unicode,则这种差异不会产生任何影响.但是,由于字符串是字节切片,因此Go可以使用ASCII或任何其他任意字节编码.

但是,字符串文字需要写入以UTF-8编码的源代码中.

信息来源:http://blog.golang.org/strings

  • 好点子 !每个 rune 需要 4 个字节,但是 string 中的每个字符都是用 utf8 编码的,因此最多只有 1~3 个字节。 (2认同)

Suh*_*pta 23

我试图保持我的语言简单,以便外行人理解rune.

符文是一个角色.而已.

这是一个单一的角色.它是来自世界任何地方的任何语言的任何字母表中的字符.

获取我们使用的字符串

double-quotes ""
Run Code Online (Sandbox Code Playgroud)

要么

back-ticks ``
Run Code Online (Sandbox Code Playgroud)

字符串不同于符文.在符文中我们使用

single-quotes ''
Run Code Online (Sandbox Code Playgroud)

现在一个符文也是...的别名int32呃什么?

符文是别名的原因int32是因为我们看到编码方案如下所示 在此输入图像描述

每个字符映射到一些数字,因此它是我们存储的数字.例如,一个映射到97,当我们存储数它只是数量,所以这方法的符文是INT32的别名.但不只是任何数字.它是一个32'零和1'或'4'字节的数字.(注意:UTF-8是一个4字节的编码方案)

符文如何与字符串相关?

字符串是符文的集合.在以下代码中:

    package main

    import (
        "fmt"
    )

    func main() {
        fmt.Println([]byte("Hello"))
    }
Run Code Online (Sandbox Code Playgroud)

我们尝试将字符串转换为字节流.输出是:

[72 101 108 108 111]
Run Code Online (Sandbox Code Playgroud)

我们可以看到构成该字符串的每个字节都是符文.

  • “字符串不是符文的集合”严格来说,这是不正确的。相反,字符串是一个字节切片,使用utf8编码。字符串中的每个字符实际上占用1〜3个字节,而每个符文则占用4个字节。您可以在字符串和[]符文之间转换,但是它们是不同的。 (2认同)
  • 符文不是字符,符文代表Unicode代码点。一个代码点不一定指向一个字符。 (2认同)

Eri*_*ang 9

(有一种感觉,上面的答案依然没有状态之间的区别和关系string,并[]rune很清楚,所以我会尝试添加与例如另一个答案。)

@Strangework答案所说,string[]rune静不同。

差异- string[]rune

  • string value是只读字节片。并且,字符串文字以utf-8编码。string实际上,每个字符占用1〜3个字节,而每个字符rune占用4个字节
  • 对于stringlen()和索引均基于字节。
  • 对于[]runelen()和索引都基于符文(或int32)。

关系- string[]rune

  • 当您从转换string[]rune,每个UTF-8字符在该字符串变成一个rune
  • 类似地,在逆变换,从转换时[]runestring,每个rune变成UTF-8字符的string

提示:

  • 您可以在string和之间进行转换[]rune,但是在类型和整体大小上它们仍是不同的。

(我将添加一个示例来更清楚地显示这一点。)


string_rune_compare.go:

// string & rune compare,
package main

import "fmt"

// string & rune compare,
func stringAndRuneCompare() {
    // string,
    s := "hello??"

    fmt.Printf("%s, type: %T, len: %d\n", s, s, len(s))
    fmt.Printf("s[%d]: %v, type: %T\n", 0, s[0], s[0])
    li := len(s) - 1 // last index,
    fmt.Printf("s[%d]: %v, type: %T\n\n", li, s[li], s[li])

    // []rune
    rs := []rune(s)
    fmt.Printf("%v, type: %T, len: %d\n", rs, rs, len(rs))
}

func main() {
    stringAndRuneCompare()
}
Run Code Online (Sandbox Code Playgroud)

执行:

去运行string_rune_compare.go

输出:

hello??, type: string, len: 11
s[0]: 104, type: uint8
s[10]: 189, type: uint8

[104 101 108 108 111 20320 22909], type: []int32, len: 7
Run Code Online (Sandbox Code Playgroud)

说明:

  • 字符串的hello??长度为11,因为前5个字符每个仅占用1个字节,而后2个中文字符每个占用3个字节。

    • 从而, total bytes = 5 * 1 + 2 * 3 = 11
    • 由于len()on字符串基于字节,因此打印的第一行len: 11
    • 由于字符串的索引也是基于字节的,因此以下两行将打印类型的值uint8(因为go中byte是别名类型uint8,)。
  • 当转换string[]rune,它发现7个UTF8字符,因此7个符文。

    • 由于len()on []rune基于符文,因此最后一行被打印len: 7
    • 如果[]rune通过索引操作,它将基于符文访问。
      由于每个符文都来自原始字符串中的utf8字符,因此,您也可以说len()和的索引操作[]rune都基于utf8字符。


小智 7

其他人都覆盖了与符文相关的部分,所以我不打算谈论这个问题.

但是,还有一个问题与switch没有任何论据有关.这只是因为在Golang中,switch没有表达式是表达if/else逻辑的另一种方式.例如,写这个:

t := time.Now()
switch {
case t.Hour() < 12:
    fmt.Println("It's before noon")
default:
    fmt.Println("It's after noon")
}
Run Code Online (Sandbox Code Playgroud)

写这个是一样的:

t := time.Now()
if t.Hour() < 12 {
    fmt.Println("It's before noon")
} else {
    fmt.Println("It's after noon")
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里阅读更多.