Go lang - 如何将界面转换为自定义类型?

时间:2016-09-03 00:53:45

标签: go

我试图从json字符串中解析出一个特定的字段,目前我有以下代码片段。

package main

import (
    "encoding/json"
    "fmt"
)

type PlatformID string

type Map map[string]interface{}

func Str2Map(str string) (Map, error) {
    var dictionary Map
    bytes := []byte(str)
    err := json.Unmarshal(bytes, &dictionary)
    if err != nil {
        fmt.Println(err)
    }
    return dictionary, err
}

func parsePlatformID(str string) (PlatformID, error) {
    fmt.Println(str)
    dict, err := Str2Map(str)
    fmt.Println(dict)
    return dict["platform-id"].(PlatformID), err
}

func main() {
    PlatformDictStr := "{\"platform-id\":\"platform_BnjliXLEUV26\",\"platform-labels\":\"test\",\"OptimizeScheme\":\"None\"}"

    fmt.Println(PlatformDictStr)

    ID, _ := parsePlatformID(PlatformDictStr)
    fmt.Println(ID)
}

当我尝试运行它时,它会给我以下错误

{"platform-id":"platform_BnjliXLEUV26","platform-labels":"test","OptimizeScheme":"None"}
{"platform-id":"platform_BnjliXLEUV26","platform-labels":"test","OptimizeScheme":"None"}
map[platform-id:platform_BnjliXLEUV26 platform-labels:test OptimizeScheme:None]
panic: interface conversion: interface is string, not main.PlatformID

goroutine 1 [running]:
panic(0x126aa0, 0x10532300)
    /usr/local/go/src/runtime/panic.go:500 +0x720
main.parsePlatformID(0x13e6fe, 0x58, 0x0, 0x0, 0x0, 0x0)
    /tmp/sandbox256874711/main.go:26 +0x220
main.main()
    /tmp/sandbox256874711/main.go:34 +0x100

question种答案为什么我得到了panic: interface conversion: interface is string

如果我尝试将类型断言更改为string(PlatformID的基础类型),它甚至不会编译tmp/sandbox325023244/main.go:26: cannot use dict["platform-id"].(string) (type string) as type PlatformID in return argument

那么我应该如何修改return行以便我可以检索PlatformID?

3 个答案:

答案 0 :(得分:1)

在查看PlatformDictStr之后,我认为var dictionary map[string]string应该完成这项工作。 在这种情况下可以避免PlatformID(dict["platform-id"].(string))。这里的工作示例 https://play.golang.org/p/A5kiVm_XbP

答案 1 :(得分:0)

在更多地学习语法之后,我想我需要进行类型转换和类型断言。

以下一行解决了问题

return PlatformID(dict["platform-id"].(string)), err

回想起来,我需要首先将接口类型断言为基类型string,然后我可以将类型转换为PlatformID

PS 1:用例是我在请求体中获得了原始字符串,REST层将解析字典中的某些字段,然后将剩余的未解析字符串转发到API层以进行进一步处理。字典中的键取决于工作量,因此我无法将其解组为明确定义的结构。

答案 2 :(得分:0)

您是否有任何特定原因为字符串和地图创建了类型?如果没有,我认为你过度设计了一个简单的用例。以下工作正常:

package main

import (
    "encoding/json"
    "fmt"
)

func Str2Map(str string) (map[string]interface{}, error) {
    var dictionary map[string]interface{}
    bytes := []byte(str)
    err := json.Unmarshal(bytes, &dictionary)
    if err != nil {
        fmt.Println(err)
    }
    return dictionary, err
}

func parsePlatformID(str string) (string, error) {
    fmt.Println(str)
    dict, err := Str2Map(str)
    fmt.Println(dict)
    return dict["platform-id"].(string), err
}

func main() {
    PlatformDictStr := "{\"platform-id\":\"platform_BnjliXLEUV26\",\"platform-labels\":\"test\",\"OptimizeScheme\":\"None\"}"

    fmt.Println(PlatformDictStr)

    ID, _ := parsePlatformID(PlatformDictStr)
    fmt.Println(ID)
}

工作游乐场示例:https://play.golang.org/p/mpPpDmiz7x