我正在爲Flowdock API編寫一個go客戶端。它們對消息API具有多個屬性的其中兩個是Event
和Content
如何基於類型的json.Unmarshal
當Event = message
然後Content
是一個字符串。當Event = comment
Content
是一個JSON對象。
我想推遲undemarhsalling Content
,直到它需要。爲此,我在我的結構中映射RawContent
並在Message
上定義Content()
方法以返回正確的對象。
下面是代碼來說明:
package main
import (
"fmt"
"encoding/json"
)
// Message represents a Flowdock chat message.
type Message struct {
Event *string `json:"event,omitempty"`
RawContent *json.RawMessage `json:"content,omitempty"`
}
func (m *Message) Content() (content interface{}) {
// when m.Event is a message the RawContent is a string
// real code handles unmarshaling other types (removed for this example)
return string(*m.RawContent)
}
func main() {
var message = &Message{}
rawJSON := `{"event": "message", "content": "Howdy-Doo @Jackie #awesome"}`
if err := json.Unmarshal([]byte(rawJSON), &message); err != nil {
panic(err.Error())
}
event := "message"
rawMessage := json.RawMessage("Howdy-Doo @Jackie #awesome")
want := &Message{
Event: &event,
RawContent: &rawMessage,
}
fmt.Println(message.Content(), want.Content())
}
運行此的結果是:http://play.golang.org/p/eds_AA6Aay
"Howdy-Doo @Jackie #awesome" Howdy-Doo @Jackie #awesome
注:message.Content()和want.Content()是不同的!
起初我並沒有期望引用被包含在消息中,但是由於JSON的解析方式,它是有意義的。它只是整個rawJSON
字符串的一部分。
所以我的問題是:
- 如果我只是去掉引號?
- 如果是這樣的話,最簡單的方法是去脫衣舞?也許這個:http://play.golang.org/p/kn8XKOqF0z行(6,19)?
- 這是甚至正確的方法來處理JSON,可以有不同類型的相同的屬性?
下面是一個更完整的例子展示我如何處理JSON RawContent
:http://play.golang.org/p/vrBJ5RYcql
感謝您的答案。我曾試過你的答案2之前,但問題是該字符串是無效的JSON,所以它不能被解組。這裏是一個例子http://play.golang.org/p/I5MBnMEpC5。 – Will
這是我注意* Note *的地方;您的原始'rawJSON'是正確的JSON,並且將它解組到'Message'結構中會將'RawContent'設置爲正確的JSON字符串。但是放入'rawMessage'中的非引號字符串不是JSON,因此它在Unmarshalled時會產生一個錯誤。看到這[Playground](http://play.golang.org/p/HRtN4iJnZT) – ANisus
噢!所以我感到恐慌,但認爲這是因爲某種原因不想要的信息 - 非常感謝 – Will