dtpfia3334
2017-10-01 21:30 阅读 43
已采纳

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

I'm working with two libraries, and one defines a type:

type Attrs map[string]string

while the other defines:

type StringMap map[string]string

A function from the first library returns an []Attrs, and struct required by the other has a field as []StringMap which needs to be set. Attempting to either use a simple assignment, or a cast in the form of ([]StringMap)(attrs), just results in an error:

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

So, how can those be bridged?

Edit: Ok, apparently this is a language limitation (booo-hooo). Can it be stepped aside with unsafe pointers?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    dongsi3826 dongsi3826 2017-10-01 22:07

    You can do this, but it circumvents Go's type safety, which can lead to trouble depending on implementation type.

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

    It is much better for type safety to just iterate the []Attrs slice and append to a []StringMap.

    点赞 评论 复制链接分享

相关推荐