2016-09-03 12 views
0

私はjson文字列から特定のフィールドを解析しようとしていますが、現在次のコードスニペットがあります。Go lang - インターフェイスをカスタムタイプに変換するにはどうすればよいですか?

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 

私はstringに型アサーションを変更しようとした場合、私はpanic: interface conversion: interface is string

を得た理由の回答のこのquestionソート、基盤となるタイプのPlatformIDはコンパイルされません。tmp/sandbox325023244/main.go:26: cannot use dict["platform-id"].(string) (type string) as type PlatformID in return argument

return私はPlatformIDを取得できますか?

+1

は、なぜあなたは、あなたの 'PlatformID'のための新しいタイプを作成するのですか? – tkausl

+0

私はそのコードの部分を書いていませんでしたが、それは私に任せていれば、そのまま文字列として残しています... IDの基本型を決して使っていないC++の産業慣行から来たと言われています。 – cookieisaac

+1

マップの代わりに、正しい型のフィールドを持つ構造体に非整列化すると、コード全体が不要になります。変換するものはありません。 – hobbs

答えて

0

もう少しシンタックスを使いこなした後、タイプ変換とタイプアサーションの両方を行う必要があると思います。

だから、次の行を振り返ってみると

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

問題を解決し、私が最初に基本型stringにインターフェイスタイプをアサートする必要があり、そこから私はちょうどPlatformID

に型変換を行うことができます

PS 1:リクエスト本体で生の文字列を取得した場合、RESTレイヤーは辞書の特定のフィールドを解析し、未処理の文字列の残りをAPIレイヤーに転送して処理します。辞書の中のキーはワークロードに依存しているので、私はそれをよく定義された構造体に非マーシャルすることはできません。

1

PlatformDictStrを見てから、var dictionary map[string]stringは仕事をするべきだと思います。その場合には PlatformID(dict["platform-id"].(string))を避けることができます。ここでの作業例 https://play.golang.org/p/A5kiVm_XbP

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

関連する問題