我需要解组一些数据,在一种情况下,经过编组的数据代表一个以字节数组为键的映射。
不允许将切片用作映射键,但可以使用数组。但是这里的问题是,据我所知,无法以非恒定大小创建数组。
示例:
package main
import (
"fmt"
"reflect"
)
func getHashable(value interface{}) interface{} {
rfl := reflect.ValueOf(value)
if rfl.Kind() == reflect.Slice && rfl.Type().Elem().Kind() == reflect.Uint8 {
slice, ok := value.([]uint8)
if !ok {
panic(fmt.Errorf("Could not coerce to []uint8"))
}
var arr [len(slice)]uint8 // This fails
copy(arr, slice)
value = arr
}
return value
}
func unmarshalMap(serialized []byte) map[interface{}]interface{} {
result := make(map[interface{}]interface{})
for len(serialized) > 0 {
var value interface{}
key, bytesConsumed := deserializeValue(serialized)
serialized = serialized[bytesConsumed:]
value, bytesConsumed = deserializeValue(serialized)
serialized = serialized[bytesConsumed:]
result[getHashable(key)] = value
}
}
如果deserializeValue()返回一个[] byte,则不能将其作为键存储在结果图中。数组可以工作,但是我无法创建数组,因为我不知道在运行时需要什么大小,并且它只允许编译时间常数。
简化版本https://play.golang.org/p/wkYGs3S-uSD失败,并显示错误消息
./prog.go:15:12: non-constant array bound len(slice)
在Go语言中,如何使用已解组的字节数组作为键?
答案 0 :(得分:3)
使用string
而不是固定大小的字节数组。字符串可以包含任意字节序列。
func getHashable(value interface{}) interface{} {
rfl := reflect.ValueOf(value)
if rfl.Kind() == reflect.Slice && rfl.Type().Elem().Kind() == reflect.Uint8 {
value = string(rfl.Bytes())
}
return value
}
如果只需要处理[]byte
而不为[]byte
命名,请使用类型断言而不是反射:
func getHashable(value interface{}) interface{} {
switch value := value.(type) {
case []byte:
return string(value)
default:
return value
}
}
如果地图的用户需要将字符串键与从[] byte创建的键中区分出来,请定义一个字符串类型以区分这些值:
type convertedSlice string
在上面的代码中用string()
代替convertedSlice()
的转换。
应用程序可以使用以下方法检查转换后的密钥:
_, ok := key.(convertedSlice) // ok is true if key is converted slice.
并使用以下命令将密钥转换回[] byte:
cv, ok := key.(convertedSice)
if ok {
key = []byte(cv)
}
答案 1 :(得分:3)
虽然使用string
显然是更好的方法,但是如果您不控制的代码使用字节数组作为键,则可以通过以下方法使用反射将字节片转换为数组作为接口。
varr := reflect.New(reflect.ArrayOf(len(slice), reflect.TypeOf(uint8(0))))
reflect.Copy(varr.Elem(), reflect.ValueOf(slice))
return varr.Elem().Interface()
在使用此功能之前,请考虑其他选项。