2013-11-20 11 views
5

使用go1.1.2 Win64,我有一個Go程序「marshal」是一個包含float64的結構。當float64的值不是整數時,例如。 1234.44,那麼它就像一個float(json.Marshal)一樣獲得「元帥」。但是,如果它是一個整數,例如。 「1234.00」它被整理爲一個整數「1234」。當我在另一端(Dart)接收到它時,Dart(30188)將整個數字視爲整數(在地圖 - JSON.decode中)。因此,當浮點(雙精度)數據的表示不包含小數點時,Dart程序將中止,並且我試圖從映射中「提取」它爲double。是否正確地將float64編碼爲JSON?

這顯然可以通過許多不同的方式解決(例如,轉換爲整數然後再轉換回浮點數),但是我想知道是否有另一種更好的方法來處理這種情況。

是否有另一種更好的方式來處理這比將float64轉換爲整數?

回答

5

就像Javascript一樣,JSON在整數和數字之間沒有區別。

如果Dart對待1234.001234不同,那麼它會對JSON specification不支持的值作出假設。

雖然圍棋確實元帥正確float64,讓周圍的問題飛鏢的假設的一種方法是通過在自己的類型實現Marshaler interface

type Number float64 

func (n Number) MarshalJSON() ([]byte, error) { 
    // There are probably better ways to do it. It is just an example 
    return []byte(fmt.Sprintf("%f", n)), nil 
} 

然後你可以使用自己的Number類型,而不是float64,你將成爲元帥的結構。通過這種方式,您可以確保您的號碼始終以小數點編組。

工作實施例上Playground

+0

感謝您的解決方案。我認爲這應該在Dart結束時解決。看起來,一個整數不能被分配給Dart中的double。這在我看來是一個異常,但我承認,至少從理論的角度來看,我是錯的(鑄造,拋棄等)。我現在的解決方案如下:「double dAcctBal =(mAcctData ['D_AcctBal'] as num)/ 1;」 (其中mAcctData是其中「D_AcctBal」可以是整數或雙精度的映射,取決於它是否是整數)。這個解決方案對我來說似乎有些破綻,但是如果一個整數不能直接分配給一個double? –

+0

是的,我同意最好在飛鏢結束時解決它。如果我知道的話,我也會很樂意給你這樣的解決方案,但是我對Dart的經驗非常有限。也許有更多知識的人可以找到更加習慣的飛鏢解決方案。 – ANisus

+0

JSON沒有指定其數字文字的語義,所以使用雙精度比整數更不正確。飛鏢有兩種數字類型。任何包含小數點或指數部分的東西都必須是double,其他所有內容都被解析爲整數,這在Dart中提供的精度比雙精度要高。這儘可能地保留了來自JSON號碼的儘可能多的信息。如果您希望所有數字都是雙打,它確實需要您手動使用.toDouble。 – lrn

1

下面似乎是(我)溶液中。整數方法toDouble()也適用於「num」(反之亦然)。在我看來,當使用可以被Dart解釋爲double或int的json和貨幣值時,有必要使用「as num」,然後使用toDouble()的內置方法。

例(GO):

type cuAcctRow struct { 
     ..... 
    D_AcctBal float64 
     ..... 
} 
    if baJsAcctDet, oOsError = json.Marshal(uAcctRow); oOsError != nil { 

例(DART):

Map mAcctData = json.parse(sResponse); 

double dAcctBal = (mAcctData['D_AcctBal'] as num).toDouble(); 

我不知道爲什麼飛鏢不允許整數翻一番的直接分配,但我肯定有一個很好的理由。

+0

一個很好的理由。 Dart中的類型註釋是可選的,它們被視爲斷言(它們在生產模式下被忽略)。這意味着一個變量沒有類型,所以如果將一個整數賦值給一個聲明爲double的變量,則無論變量聲明爲double(「double x」)還是隻聲明爲dynamic(「var x」),都必須相同。這可以防止任何隱式轉換。在檢查模式下,分配被檢查,並且因爲'int'不是'double'的子類型,所以類型斷言失敗。你必須做一個明確的n.toDouble()。 – lrn

+0

@lrn:感謝您的解釋。我「應該」研究這一點。這讓我感到困惑,但我想有幾個因素。雖然我現在已經離開了這個位置,但我認爲我的小「解決方案」是可以的。 (作爲num).toDouble()並不是非常繁重,然而,從實際的角度來看,它似乎很奇怪,一個完全兼容的double範圍內的int不能直接賦值給double。雖然這個小問題相對簡單,但還是有一些因素(包括JS,我猜可能是間接的)。 –