# 04.5.1 rune是什么？

**rune**是一个类型为`int32`的值，因此他主要用来代表一个Unicode码点。Unicode码点是一个代表Unicode字符的数值。

> **NOTE:**&#x4F60;可以认为字符串是一系列rune的集合

**rune字面量**实际上是一个用单引号括起来的字符，并且与与Unicode码点的概念相关联。

`rune.go`将分两部分阐述rune的使用，第一部分是：

> ```go
> package main
>
> import (
>    "fmt"
> )
>
> func main() {
>    const r1 = '€'
>    fmt.Println("(int32) r1:", r1)
>    fmt.Printf("(HEX) r1: %x\n", r1)
>    fmt.Printf("(as a String) r1: %s\n", r1)
>    fmt.Printf("(as a character) r1: %c\n", r1)
> ```

首先定义了一个rune字面量`r1`,然后使用不同的方式去打印，分别是int32、十六进制、字符串、字符，最终你会发现使用字符格式打印出的与定义`r1`的值相同。

第二部分：

> ```go
> fmt.Println("A string is a collection of runes:", []byte("Mihalis"))
>    aString := []byte("Mihalis")
>    for x, y := range aString {
>       fmt.Println(x, y)
>       fmt.Printf("Char: %c\n", aString[x])
>    }
>    fmt.Printf("%s\n", aString)
> }
> ```

显而易见，**字节切片**实际上就是一系列runes的集合，并且如果你使用`fmt.Println()`打印字节切片，结果很可能不会符合你的预期。`fmt.Printf()`语句结合`%c`可以将runes转换为字符输出；如果想要以字符串的形式输出字节数组，应使用`fmt.Printf()`结合`%s`。

执行runes.go得到下面的输出：

> go run runes.go
>
> ```
> (int32) r1: 8364
> (HEX) r1: 20ac
> (as a String) r1: %!s(int32=8364)
> (as a character) r1: €
> A string is a collection of runes: [77 105 104 97 108 105 115]
> 0 77
> Char: M
> 1 105
> Char: i
> 2 104
> Char: h
> 3 97
> Char: a
> 4 108
> Char: l
> 5 105
> Char: i
> 6 115
> Char: s
> Mihalis
> ```

最后，举一个产生`illegal rune literal`错误的例子：在导包的时候使用单引号。

> $ cat a.go
>
> package main
>
> import (
>
> 'fmt'
>
> )
>
> func main(){
>
> }
>
> $ go run a.go
>
> package main:a.go:4:2: illegal rune literal
