围棋中的符文是什么?

我一直在谷歌,但Golang只说了一行:符文是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
    }
}

其中大部分来自http://play.golang.org/p/H6wjLZj6lW

func SwapCase(str string) string {
    return strings.Map(SwapRune, str)
}

我明白这是映射符文到字符串,以便它可以返回交换的字符串。但我不明白符文或字节在这里是如何工作的。


当前回答

其他所有人都已经介绍了与符文相关的部分,所以我不打算谈论这个。

然而,还有一个关于开关没有任何参数的问题。这只是因为在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")
}

和写这个是一样的

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

你可以在这里阅读更多。

其他回答

Rune是int32类型的别名。它表示一个单一的Unicode码位。 统一码联盟(Unicode Consortium)为超过100万个独特的字符分配数字值,称为码点。例如,65是字母A的码位,66 -> B (来源:Get Programming with Go)

程序

package main

import (
    "fmt"
)

func main() {
    words := "€25 or less"
    fmt.Println("as string slice")
    fmt.Println(words, len(words))

    runes := []rune(words)
    fmt.Println("\nas []rune slice")
    fmt.Printf("%v, len:%d\n", runes, len(runes))

    bytes := []byte(words)
    fmt.Println("\nas []byte slice")
    fmt.Printf("%v, len:%d\n", bytes, len(bytes))
}

输出

as string slice
€25 or less 13

as []rune slice
[8364 50 53 32 111 114 32 108 101 115 115], len:11

as []byte slice
[226 130 172 50 53 32 111 114 32 108 101 115 115], len:13

如您所见,欧元符号“€”由3个字节表示——226、130和172。 符文代表一个字符-任何字符,它是象形文字。一个符文的32位足以代表当今世界上所有的字符。因此,欧元符号“€”的符文表示是8364。

对于128个ASCII字符,一个字节(8位)就足够了。因此,符文和数字或字母的字节表示是相同的。例:2用50表示。

字符串的字节表示总是大于或等于其符文表示的长度,因为某些字符用超过一个字节表示,但不超过32位,这是一个符文。

https://play.golang.org/p/y93woDLs4Qe

符文是一个int32值,因此它是一种Go类型,用于表示Unicode码位。Unicode码位是通常用于表示单个Unicode字符的数值;

(感觉上面的答案仍然没有很清楚地说明字符串和[]符文之间的区别和关系,所以我会尝试用一个例子来补充另一个答案。)

正如@Strangework的回答所说,字符串和[]符文是完全不同的。

区别-字符串和[]符文:

字符串值是只读字节片。并且,字符串文字用utf-8编码。字符串中的每个字符实际占用1 ~ 3个字节,而每个符文占用4个字节 对于string, len()和index都基于字节。 对于[]符文,len()和index都基于符文(或int32)。

关系-字符串和[]符文:

当您将字符串转换为[]符文时,该字符串中的每个utf-8字符都成为一个符文。 类似地,在反向转换中,当从[]符文转换为字符串时,每个符文都变成字符串中的utf-8字符。

小贴士:

你可以在字符串和[]符文之间转换,但它们在类型和整体大小上仍然是不同的。

(我将添加一个例子来更清楚地说明这一点。)


Code

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()
}

执行:

运行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

解释:

The string hello你好 has length 11, because the first 5 chars each take 1 byte only, while the last 2 Chinese chars each take 3 bytes. Thus, total bytes = 5 * 1 + 2 * 3 = 11 Since len() on string is based on bytes, thus the first line printed len: 11 Since index on string is also based on bytes, thus the following 2 lines print values of type uint8 (since byte is an alias type of uint8, in go). When converting the string to []rune, it found 7 utf8 chars, thus 7 runes. Since len() on []rune is based on rune, thus the last line printed len: 7. If you operate []rune via index, it will access base on rune. Since each rune is from a utf8 char in the original string, thus you can also say both len() and index operation on []rune are based on utf8 chars.

其他所有人都已经介绍了与符文相关的部分,所以我不打算谈论这个。

然而,还有一个关于开关没有任何参数的问题。这只是因为在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")
}

和写这个是一样的

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

你可以在这里阅读更多。