JSON

2015-06-15 24 views
6

'dan bool olarak hem 0'ı hem de false olarak nasıl unshashall olacağı, şu anda boolean türleri için 0 ve false (ve 1 ve true) değişimini sağlayan bir hizmetin çıktısını eşleştiriyor. Yerleşik kodlama/json unmarshal işlevi için daha izin verici ayrıştırıcı kullanmanın bir yolu var mı? Eklemeyi denedim, json etiketlerine boşuna boşver.JSON

Ben isterdim ne bir örnek: sonra

type MyType struct { 
    AsBoolean bool `json:"field1"` 
    AlsoBoolean bool `json:"field2"` 
} 

, verilen giriş json:

{ 
    "field1" : true, 
    "field2" : 1 
} 

çıkan yapı olacaktır:

obj := MyType{} 
json_err := json.Unmarshal([]byte(input_json), &obj) 
fmt.Printf("%v\n", obj.AsBoolean) //"true" 
fmt.Printf("%v\n", obj.AlsoBoolean) //"true" 
+3

Ben o zaman hatalı biçimlendirilmiş JSON üretiyor, bu boole bilir değerleri için "1" ler ile JSON çıktılar hizmet/yazılım kendisi 0/yanlış ve 1 doğru/yaklaşık liberal olduğunu fark etmez . Boole ve Number, JOSN'taki farklı türlerdir ve bir mareşal, bununla doğru bir şekilde ilgilenmez, de-mareşalistin beklemesine hakkı yoktur. –

+1

Yani, ben çıktı kötü olduğunu kabul ediyorum, bu bir vakum değil ve gerçekten bu çıktıyı işlemek ve –

+0

sabitleme üzerinde herhangi bir kontrole sahip değilsiniz Ne tür bir şeyden emin değilseniz, türünüz için UnMarshalJson yöntemini uygulayabilirsiniz son sonuç olması. Örneğinizde, boole ve int farklı alan adları gibi farklı alan adlarına sahiptir. Bunu "türleri birbiriyle değiştiren API" olarak görmeyi düşünmüyorum. Her zaman aynı alan adıysa, o zaman böyle olabilir. Her iki durumda da, her zaman farklı tiplere sahip olmanın ve sonuna kadar temiz, başarısız, başarısızlık yöntemini kullanabilir ve başarı elde edinceye kadar tek tek onlar için tek parçalanmaya çalışabilirsiniz. Paradigma genellikle veri veya hataya sahip olabilecek cevaplar için kullanılır. – evanmcdonnal

cevap

6

bir kullanarak sona erdi özel "boolean" türü ve normal bir boole kullandığım yer burası için değiştirildi:

type ConvertibleBoolean bool 

func (bit ConvertibleBoolean) UnmarshalJSON(data []byte) error { 
    asString := string(data) 
    if asString == "1" || asString == "true" { 
     bit = true 
    } else if asString == "0" || asString == "false" { 
     bit = false 
    } else { 
     return errors.New(fmt.Sprintf("Boolean unmarshal error: invalid input %s", asString)) 
    } 
    return nil 
} 
+2

Küçük ipucu: Stil kuralı 'mixedCaps' (https://golang.org/doc/effective_go.html#mixed-caps) değişken adlarını kullanmaktır, bu yüzden' as_string' 'asString' olmalıdır (veya sadece' s' eğer küçük bir işlev ise). – elithrar

+3

Ayrıca başka bir küçük ipucu: ['fmt.Errorf()'] yöntemi (https://golang.org/pkg/fmt/#Errorf) var, bu yüzden hatalara ihtiyacınız yok.Yeni() 've' fmt.Sprintf() '. (Btw 'fmt.Error()' tam olarak kaputun altında aynısını yapar.) – icza

+0

Bu işe yaramadı, bence ConvertibleBoolean'a bir işaretçiye ihtiyacımız var. –

4

Cevabınız için teşekkür ederiz Will Charzuck, ancak bir işaretçi yöntem alıcısı kullanmadıkça ve işlev gövdesinde işaretçinin değerini ayarlamadıkça benim için çalışmadı.

type ConvertibleBoolean bool 

func (bit *ConvertibleBoolean) UnmarshalJSON(data []byte) error { 
    asString := string(data) 
    if asString == "1" || asString == "true" { 
     *bit = true 
    } else if asString == "0" || asString == "false" { 
     *bit = false 
    } else { 
     return errors.New(fmt.Sprintf("Boolean unmarshal error: invalid input %s", asString)) 
    } 
    return nil 
} 
+0

iyi çalıştı. sadece "\" "asString: = strings.Replace (strings.ToLower (string.TrimSpace (string (data)))," \ "", "", -1) değiştirmek için asString değiştirildi – kadalamittai