Gobyte教程展示了如何在Golang中使用字节。
Go中的byte
是一个无符号的8位整数。它的类型为uint8
。byte
的数值范围限制为0∼255。它可以表示一个ASCII字符。
Go使用类型为int32
的rune
来处理多字节字符。
bytes
包实现了操作字节片的函数。它类似于strings
包。
$ go version go version go1.18.1 linux/amd64
我们使用Go版本1.18。
Go字节示例
在下一个示例中,我们使用简单的字节。
package main import "fmt" func main() { var a1 byte = 97 var a2 byte = 98 var a3 byte = 99 fmt.Println(a1) fmt.Println(a2) fmt.Println(a3) fmt.Printf("%c\n", a1) fmt.Printf("%c\n", a2) fmt.Printf("%c\n", a3) }
我们有三个字节。
var a1 byte = 97 var a2 byte = 98 var a3 byte = 99
字节是用byte
数据类型定义的。
fmt.Printf("%c\n", a1) fmt.Printf("%c\n", a2) fmt.Printf("%c\n", a3)
使用%c
格式动词,我们打印字节的字符表示。
$ go run first.go 97 98 99 a b c
我们必须显式地将一个变量设置为byte
类型;否则,我们会得到不同的类型。
package main import ( "fmt" "reflect" ) func main() { var a byte = 97 var b = 98 c := 'c' fmt.Println(a) fmt.Println(b) fmt.Println(c) fmt.Println("-------------------------") fmt.Printf("%c\n", a) fmt.Printf("%c\n", b) fmt.Printf("%c\n", c) fmt.Println("-------------------------") fmt.Println(reflect.TypeOf(a)) fmt.Println(reflect.TypeOf(b)) fmt.Println(reflect.TypeOf(c)) }
在代码示例中,我们有三个变量。
var a byte = 97
a
变量具有byte
数据类型。
var b = 98
因为我们没有显式设置数据类型,Go设置了一个默认的int
类型。
c := 'c'
字符文字设置为rune
类型(int32)。
$ go run types.go 97 98 99 ------------------------- a b c ------------------------- uint8 int int32
将字符串转为字节
在下面的示例中,我们将字符串转换为字节。
package main import ( "fmt" ) func main() { fmt.Println([]byte("falcon")) fmt.Println([]byte("ÄereÅ¡Åa")) }
我们使用[]byte()
类型转换将两个字符串转换为字节。
$ go run str2bytes.go [102 97 108 99 111 110] [196 141 101 114 101 197 161 197 136 97]
将字节转为字符串
在下面的示例中,我们将字节转换为字符串。
package main import "fmt" func main() { data := []byte{102, 97, 108, 99, 111, 110} fmt.Println(data) fmt.Println(string(data)) }
我们使用string
函数将一段字节转换为字符串。
$ go run bytes2str.go [102 97 108 99 111 110] falcon
去计算字节数
我们使用len
函数计算字节数。为了计算符文,我们使用utf8.RuneCountInString
函数。
package main import ( "fmt" "unicode/utf8" ) func main() { msg := "one ð" n1 := len(msg) n2 := utf8.RuneCountInString(msg) fmt.Println(n1) fmt.Println(n2) }
我们计算msg
字符串的字节数和符文数。
$ go run counting.go 8 5
有五个符文和八个字符。这意味着我们有一个包含四个字节的符文。
去字节读取文件
Go中的许多内置I/O函数返回一段字节。
falcon sky cup oak water
我们阅读了这个文本文件。
package main import ( "fmt" "io/ioutil" "log" ) func main() { content, err := ioutil.ReadFile("words.txt") if err != nil { log.Fatal(err) } fmt.Println(content) fmt.Println("-------------") fmt.Println(string(content)) }
ioutil.ReadFile
读取指定文件并将其内容作为字节片返回。
$ go run read_file.go [102 97 108 99 111 110 10 115 107 121 10 99 117 112 10 111 97 107 10 119 97 116 101 114] ------------- falcon sky cup oak water
去字节读取二进制文件
在下面的例子中,我们读取一个二进制文件并以十六进制的形式输出它。
package main import ( "bufio" "encoding/hex" "fmt" "io" "log" "os" ) func main() { f, err := os.Open("favicon.ico") if err != nil { log.Fatal(err) } defer f.Close() reader := bufio.NewReader(f) buf := make([]byte, 256) for { _, err := reader.Read(buf) if err != nil { if err != io.EOF { fmt.Println(err) } break } fmt.Printf("%s", hex.Dump(buf)) } }
hex.Dump
函数返回一个字符串,其中包含给定数据的十六进制转储。十六进制转储的格式与hexdump-C
Unix命令的输出相匹配。
$ go run read_binary.go 00000000 00 00 01 00 01 00 10 10 00 00 00 00 00 00 68 05 |..............h.| 00000010 00 00 16 00 00 00 28 00 00 00 10 00 00 00 20 00 |......(....... .| 00000020 00 00 01 00 08 00 00 00 00 00 00 01 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 |................| 00000040 00 00 ff ff ff 00 4d 45 3d 00 00 00 00 00 00 00 |......ME=.......| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ...
转义字节
任意字符值可以使用反斜杠转义进行编码,并使用字符串或符文文字。Go支持一种通用格式,其中一个字节表示为\x
后跟两个十六进制值。
package main import ( "fmt" ) func main() { fmt.Println("\xF0\x9F\x92\xBF") fmt.Println("\xF0\x9F\x8E\xB2") fmt.Println("\xF0\x9F\x90\xA8") fmt.Println("\xF0\x9F\x90\xA7") fmt.Println("\xF0\x9F\x90\xAB") fmt.Println("\xF0\x9F\x90\xAC") }
在代码示例中,我们打印了六个表情符号字符。这些表情符号被指定为转义字节。
$ go run escaped_bytes.go ð¿ ð² ð¨ ð§ ð« ð¬
Go字节函数
bytes
包包含用于操作字节片的函数。
package main import ( "bytes" "fmt" ) func main() { data1 := []byte{102, 97, 108, 99, 111, 110} // falcon data2 := []byte{111, 110} // on if bytes.Contains(data1, data2) { fmt.Println("contains") } else { fmt.Println("does not contain") } if bytes.Equal([]byte("falcon"), []byte("owl")) { fmt.Println("equal") } else { fmt.Println("not equal") } data3 := []byte{111, 119, 108, 9, 99, 97, 116, 32, 32, 32, 32, 100, 111, 103, 32, 112, 105, 103, 32, 32, 32, 32, 98, 101, 97, 114} fields := bytes.Fields(data3) fmt.Println(fields) for _, e := range fields { fmt.Printf("%s ", string(e)) } fmt.Println() }
在代码示例中,我们使用了Contains
、Equal
和Fields
函数。
if bytes.Contains(data1, data2) { fmt.Println("contains") } else { fmt.Println("does not contain") }
使用Contains
,我们检查data2
切片是否是data1
的子切片。
if bytes.Equal([]byte("falcon"), []byte("owl")) { fmt.Println("equal") } else { fmt.Println("not equal") }
使用Equal
,我们检查两个切片是否具有相同的长度并包含相同的字节。
fields := bytes.Fields(data3)
Fields
函数将字节切片拆分为子切片,删除任意空格字符,包括换行符。
$ go run byte_funs.go contains not equal [[111 119 108] [99 97 116] [100 111 103] [112 105 103] [98 101 97 114]] owl cat dog pig bear
在下一个例子中,我们使用另外三个函数。
package main import ( "bytes" "fmt" ) func main() { data := [][]byte{[]byte("an"), []byte("old"), []byte("wolf")} joined := bytes.Join(data, []byte(" ")) fmt.Println(data) fmt.Println(joined) fmt.Println(string(joined)) fmt.Println("--------------------------") data2 := []byte{102, 97, 108, 99, 111, 110, 32} data3 := bytes.Repeat(data2, 3) fmt.Println(data3) fmt.Println(string(data3)) fmt.Println("--------------------------") data4 := []byte{32, 32, 102, 97, 108, 99, 111, 110, 32, 32, 32} data5 := bytes.Trim(data4, " ") fmt.Println(data5) fmt.Println(string(data5)) }
该示例使用Join
连接字节切片,使用Repeat
重复字节切片,并使用Trim
修剪指定字节的字节切片。
$ go run byte_funs2.go [[97 110] [111 108 100] [119 111 108 102]] [97 110 32 111 108 100 32 119 111 108 102] an old wolf -------------------------- [102 97 108 99 111 110 32 102 97 108 99 111 110 32 102 97 108 99 111 110 32] falcon falcon falcon -------------------------- [102 97 108 99 111 110] falcon
转到bytes.Buffer
bytes.Buffer
是一个可变大小的字节缓冲区,具有Read和Write方法。
package main import ( "bytes" "fmt" ) func main() { var buf bytes.Buffer buf.Write([]byte("a old")) buf.WriteByte(32) buf.WriteString("cactus") buf.WriteByte(32) buf.WriteByte(32) buf.WriteRune('ðµ') fmt.Println(buf) fmt.Println(buf.String()) }
我们用Write
、WriteByte
、WriteString
、WriteByte
构建一个bytes.Buffer
code>和WriteRune
方法。
$ go run buffer.go {[97 32 111 108 100 32 99 97 99 116 117 115 32 32 240 159 140 181] 0 0} a old cactus ðµ
在本教程中,我们使用了Golang中的字节。
列出所有Go教程。