golang 即将支持泛型,我们能用泛型做些什么呢?本文探索泛型的一个使用场景,go 的 map 进行遍历是无序的,我们往往需要按照顺序对可排序类型的key进行 map 进行有序遍历
1. go的map 是无需的,我们经常需要按照key 的有序输出。
2. 并不是所有的key 都能比较,只要类型 可以进行 == 操作,就可以作为key,所以有序输出只在可比较的类型成立
使用泛型功能实现一个map有序化的函数
请大佬不吝赐教
代码语言:go复制package main
import (
"fmt"
"reflect"
)
type mapKey interface {
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64 | string
}
func sortMapWithValue[T mapKey](m map[T]any) []struct {
key T
value any
} {
var kList []T
for k := range m {
kList = append(kList, k)
}
for i := 0; i < len(kList); i {
for j := 0; j < len(kList); j {
if kList[i] < kList[j] {
kList[i], kList[j] = kList[j], kList[i]
}
}
}
var list []struct {
key T
value any
}
for _, v := range kList {
list = append(list, struct {
key T
value any
}{key: v, value: m[v]})
}
return list
}
func sortMap[T mapKey](m map[T]any) (kList []T) {
for k := range m {
kList = append(kList, k)
}
for i := 0; i < len(kList); i {
for j := 0; j < len(kList); j {
if kList[i] < kList[j] {
kList[i], kList[j] = kList[j], kList[i]
}
}
}
return
}
func main() {
intMap()
strMap()
}
func strMap() {
strMaps := []map[string]any{
{
"a": 1, "b": 2, "c": 3, "d": 4,
},
{
"a": "a", "b": "b", "c": "c", "d": "d",
},
}
for _, v := range strMaps {
dest := sortMapWithValue(v)
fmt.Println(reflect.TypeOf(dest), reflect.ValueOf(dest))
for _, v := range dest {
fmt.Println(v.key, reflect.TypeOf(v.key), v.value, reflect.TypeOf(v.value))
}
dest1 := sortMap(v)
fmt.Println(reflect.TypeOf(dest1), reflect.ValueOf(dest1))
for _, v1 := range dest1 {
fmt.Println(v1, reflect.TypeOf(v1), v[v1], reflect.TypeOf(v[v1]))
}
}
}
func intMap() {
intMaps := []map[int]any{
{
1: "a", 2: "b", 3: "c", 4: "d",
},
{
1: 1, 2: 2, 3: 3, 4: 4,
},
}
for _, v := range intMaps {
dest := sortMapWithValue(v)
fmt.Println(reflect.TypeOf(dest), reflect.ValueOf(dest))
for _, v1 := range dest {
fmt.Println(v1.key, reflect.TypeOf(v1.key), v1.value, reflect.TypeOf(v1.value))
}
dest1 := sortMap(v)
fmt.Println(reflect.TypeOf(dest1), reflect.ValueOf(dest1))
for _, v1 := range dest1 {
fmt.Println(v1, reflect.TypeOf(v1), v[v1], reflect.TypeOf(v[v1]))
}
}
}
最后,
github.com/samber/lo 这个库 有很多脚手架函数,大部分采用了泛型。可以学习学习