首页 > 解决方案 > 使用非 UTF-8 编码的字符串作为映射键

问题描述

我想使用可变长度的字节数组作为地图中的键。

myMap := make(map[[]byte]int)

由于切片和可变长度字节数组在 go 中不是有效的键类型,因此上面的代码无效。

然后我读到字符串只是一组 8 位字节,通常但不一定代表 UTF-8 编码的文本。

使用这种非 UTF-8 编码的字符串作为关于散列的映射键有什么问题吗?

以下代码演示了我如何将[]byte转换为字符串并再次转换回[]byte

package main

import (
"bytes"
"fmt"
)

func main() {

// src is a byte array with all available byte values
src := make([]byte, 256)
for i := 0; i < len(src); i++ {
    src[i] = byte(i)
}
fmt.Println("src:", src)

// convert byte array to string for key usage within a map
mapKey := string(src[:]) // <- can this be used for key in map[string]int?
//fmt.Println(mapKey) // <- this destroys the print function!
fmt.Printf("len(mapKey): %d\n", len(mapKey)) // <- that actually works

// convert string back to dst for binary usage
dst := []byte(mapKey)
fmt.Println("dst:", dst)

if bytes.Compare(src, dst) != 0 {
    panic("Ups... something went wrong!")
}
}

标签: arraysstringdictionarygo

解决方案


string在字符串不是有效的 UTF-8 的映射中使用 as 键没有问题。

Go 博客:Go 中的字符串、字节、符文和字符:

在 Go 中,字符串实际上是只读的字节片。

规范:比较运算符:

字符串值是可比较的和有序的,词法字节。

重要的是有什么字节string,它可能是有效的还是无效的 UTF-8 序列。如果 2 个string值具有相同的无效 UTF-8 字节序列,则它们相等,如果不相等,则它们不相等。

测试无效和有效序列("\xff""\x00"):

m := map[string]byte{}
m["\xff"] = 1
m["\x00"] = 2
fmt.Println(m["\xff"], m["\x00"])

输出是(在Go Playground上试试):

1 2

推荐阅读