2015-05-12 1 views
0

У меня есть этот тип с элементом значения, называемым «Url». При кодировании этого типа в json, я хочу добавить значение HOST перед Url. Каков наилучший способ достичь этого?Добавить строку в член при кодировании типа для JSON

В этом примере Println{"url":"/thisurl"} оператор печатает, я хочу, чтобы напечатать {"url":"http://myhost.com/thisurl"}

package main 

import "fmt" 
import "encoding/json" 

type Post struct { 
    Url string `json:"url"` 
} 

const (
    HOST = "http://myhost.com" 
) 

func main() { 
    post := Post{"/thisurl"} 
    marshaled, _ := json.Marshal(post) 

    fmt.Println(string(marshaled)) 
    //{"url":"/thisurl"} 
} 

Update

Я мог бы повторно назначить post.Url прямо перед json.Marshal линии

post.Url = fmt.Sprintf("%s%s", HOST, post.Url) 

Но это чувствует себя немного грязным, если я должен помнить, чтобы делать переназначение каждый раз, когда я хочу кодировать JSON.

Я не хочу изменять значение post.Url, я просто хочу изменить, как он представлен как json.

ответ

3

Если вы хотите изменить поведение маршаллинга (un), используйте специальный тип, который реализует json.Marshaler (и, возможно, json.Unmarshaler).

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Post struct { 
    URL URLString `json:"url"` 
} 

const (
    Host = "http://myhost.com" 
) 

type URLString string 

func (u URLString) MarshalJSON() ([]byte, error) { 
    return []byte(fmt.Sprintf(`"%s%s"`, Host, u)), nil 
} 

func main() { 
    post := Post{"/thisurl"} 
    marshaled, _ := json.Marshal(post) 

    fmt.Println(string(marshaled)) 
    //{"url":"http://myhost.com/thisurl"} 
} 

Playground

(также отметить, используя все заглавные буквы для констант not idiomatic и golint рекомендует URL, MyURL, HTTP, ID против Url, MyUrl или Id).

+0

Спасибо, это именно то, что я ищу – dylanjha

+0

BTW, один из незначительных недостатков этого подхода - вам, возможно, придется делать такие вещи, как 'post.URL = urlstring (strVar)' (так что вы должны, вероятно, экспортировать этот тип если поля экспортируются), если вы напрямую назначаете из непостоянного. Если это вас беспокоит, вы можете перенести метод 'MarshalJSON' до типа' Post', но тогда вам придется обрабатывать сортировку всего типа самостоятельно :(. –

Смежные вопросы