开放的编程资料库

当前位置:我爱分享网 > Go教程 > 正文

在Golang中使用字节

Gobyte教程展示了如何在Golang中使用字节。

Go中的byte是一个无符号的8位整数。它的类型为uint8byte的数值范围限制为0∼255。它可以表示一个ASCII字符。

Go使用类型为int32rune来处理多字节字符。

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-CUnix命令的输出相匹配。

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

在代码示例中,我们使用了ContainsEqualFields函数。

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

我们用WriteWriteByteWriteStringWriteByte构建一个bytes.Buffercode>和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教程。

未经允许不得转载:我爱分享网 » 在Golang中使用字节

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏