2015-06-15 17 views
6

Hiện tại, tôi đang ánh xạ đầu ra của một dịch vụ, cho phép trao đổi tự do 0 và sai (và 1 và đúng) cho các kiểu boolean của nó. Có cách nào để sử dụng một trình phân tích cú pháp dễ dãi hơn cho hàm mã hóa/hàm json không hợp nhất được xây dựng không? Tôi đã thử thêm, chuỗi vào các thẻ json không có kết quả.Làm thế nào để hủy hợp nhất cả 0 và sai dưới dạng bool từ JSON

Một ví dụ về những gì tôi muốn:

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

sau đó, được đưa ra json đầu vào:

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

struct kết quả sẽ là:

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

tôi không quan trọng rằng dịch vụ/phần mềm chính nó là tự do về 0/sai và 1/đúng, nếu nó ra JSON với "1" s cho các giá trị nó biết là boolean, sau đó nó được sản xuất bị thay đổi JSON . Boolean và Number là các kiểu khác nhau trong JOSN, và nó là một marshaller không xử lý chính xác điều đó, nó không có quyền mong đợi de-marshaller. –

+1

i có nghĩa là, tôi đồng ý rằng đầu ra là xấu, đây không phải là một chân không mặc dù và tôi thực sự phải xử lý đầu ra này và không có kiểm soát sửa chữa nó –

+0

Bạn có thể thực hiện phương pháp UnMarshalJson cho loại của bạn, không chắc chắn những gì bạn muốn kết quả cuối cùng. Trong ví dụ của bạn, boolean và int có các tên trường khác nhau, giống như chúng là những thứ khác nhau. Tôi không nghĩ rằng xem nó như là "API trao đổi các loại" là chính xác. Nếu nó luôn là cùng một tên trường, thì đó có thể là trường hợp. Dù bằng cách nào, bạn luôn có thể sử dụng phương pháp đơn giản, thất bại, sạch sẽ để có các loại khác nhau và kết thúc của bạn và cố gắng để so sánh chúng từng cái một cho đến khi bạn đạt được thành công. Các mô hình thường được sử dụng cho các phản ứng có thể có dữ liệu hoặc lỗi. – evanmcdonnal

Trả lời

6

Đã kết thúc bằng một loại "boolean" đặc biệt và nơi tôi đang sử dụng bool bình thường, đổi chỗ cho điều này:

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

Mẹo nhỏ: Quy ước kiểu Go là sử dụng các tên biến 'mixedCaps' (https://golang.org/doc/effective_go.html#mixed-caps), vì vậy' as_string' phải là 'asString' (hoặc chỉ' s' nếu đó là một chức năng nhỏ). – elithrar

+3

Ngoài ra một mẹo nhỏ: có một phương pháp ['fmt.Errorf()'] (https://golang.org/pkg/fmt/#Errorf), do đó bạn không cần 'errors.New()' và ' fmt.Sprintf() '. (Btw 'fmt.Error()' thực hiện chính xác như vậy dưới mui xe.) – icza

+0

Điều này không hiệu quả, tôi nghĩ chúng ta cần một con trỏ tới ConvertibleBoolean. Xem câu trả lời dưới đây –

4

Cảm ơn bạn Charzuck cho câu trả lời, tuy nhiên, nó không hoạt động cho tôi trừ khi tôi đã sử dụng bộ thu nhận phương thức con trỏ và đặt giá trị của con trỏ trong thân hàm.

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

hoạt động tốt. chỉ thay đổi asString để thay thế "\" "asString: = strings.Replace (strings.ToLower (strings.TrimSpace (chuỗi (dữ liệu)))," \ "", "", -1) – kadalamittai

Các vấn đề liên quan