投射兼容但不同的地图切片

时间:2017-10-01 21:30:39

标签: go

我正在使用两个库,其中一个定义了一个类型:

type Attrs map[string]string

而另一个定义:

type StringMap map[string]string

第一个库中的函数返回[]Attrs,另一个函数所需的struct有一个需要设置的字段[]StringMap。尝试使用简单的作业或([]StringMap)(attrs)形式的演员表只会导致错误:

./wscmd.go:8:22: cannot convert attrs (type []mpd.Attrs) to type []StringMap

那么,如何弥合这些?

编辑:好的,显然这是一种语言限制(booo-hooo)。可以用不安全的指针放在一边吗?

1 个答案:

答案 0 :(得分:2)

你可以这样做,但它绕过了Go的类型安全,这可能会导致麻烦,具体取决于实现类型。

package main
import (
    "fmt"
    "reflect"
    "unsafe"
)

func main() {
    type Attrs map[string]string
    type StringMap map[string]string
    a := Attrs{"key1": "val1", "key2": "val2"}
    b := Attrs{"key3": "val3", "key4": "val4"}

    attrs := []Attrs{a, b}

    // This is what you're asking for, keep in mind this circumvents the type safety provided by go

    sh := *(*reflect.SliceHeader)(unsafe.Pointer(&attrs))
    unsafeStrMaps := *(*[]StringMap)(unsafe.Pointer(&sh))
    fmt.Println(unsafeStrMaps)

    // This would be the preferred way of casting the array

    strMaps := []StringMap{}
    for _, v := range attrs {
        strMaps = append(strMaps, StringMap(v))
    }

    fmt.Println(strMaps)
}

对于类型安全而言,只需迭代[]Attrs切片并附加到[]StringMap即可。