2013-11-20 4 views
5

go1.1.2 Win64를 사용하여, "marshal"이 float64를 포함하는 구조체 인 Go 프로그램을 가지고 있습니다. float64의 값이 정수가 아닌 경우 예. 1234.44, 그러면 "마샬링"이 부동 (json.Marshal)으로 처리됩니다. 그러나 그것은 예를 들어 정수입니다. "1234.00"은 정수 "1234"로 마샬링됩니다. Dart (30188)는 다른 끝 (Dart)에서 이것을 받으면 정수를 정수로 처리합니다 (JSON.decode). 결과적으로 Dart 프로그램은 float (double) 데이터의 표현에 소수점이 포함되지 않은 경우 중단되고지도에서 double로 추출하려고 시도합니다.float64를 JSON으로 올바르게 마샬링 하시겠습니까?

이것은 분명히 여러 가지 방법으로 해결할 수 있습니다 (예 : 정수로 변환 한 다음 다시 float으로 변환). 그러나이 상황을 처리하는 또 다른 (더 나은) 방법이 있는지 궁금해했습니다.

float64를 정수로 변환하는 것보다 더 좋은 방법이 있습니까?

답변

5

JSON은 자바 스크립트와 마찬가지로 정수와 숫자가 다릅니다.

다트가 1234.001234과 다르게 처리하는 경우 JSON specification에서 지원하지 않는 값에 대한 가정을합니다. 대신,

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 않지만

, 다트의 가정에 문제를 피할 수있는 한 가지 방법은 자신의 유형에 Marshaler interface을 구현하는 것입니다 float64, 마샬링 할 구조체. 이 방법을 사용하면 숫자가 항상 소수점으로 정렬되도록 할 수 있습니다.

작동 예는 Playground

+0

고맙습니다. 나는 이것이 Dart 끝에서 해결되어야한다고 생각한다. Dart에서는 정수를 double에 할당 할 수 없습니다. 이것은 나에게 이례적으로 보입니다. 그러나 나는 이론적 관점 (캐스트 업, 캐스트 다운 등)에서 나는 틀렸다는 것을 인정합니다. 내가 현재 가지고있는 솔루션은 다음과 같습니다 : "double dAcctBal = (mAcctData [ 'D_AcctBal'] num)/1;" (여기서 mAcctData는 "D_AcctBal"이 정수인지 아니면 정수인지 여부에 따라 두 배가 될 수있는 맵입니다). 이 솔루션은 나에게 약간의 해킹이 표시되지만, 정수를 double에 직접 할당 할 수 없다면? –

+0

예, 다트 측에서 해결하는 것이 가장 좋음에 동의합니다. 내가 아는 한 기꺼이 그런 해결책을 줄 수도 있지만 다트에 대한 나의 경험은 매우 제한적입니다. 좀 더 많은 지식을 가진 사람이라면 더 관용적 인 다트 솔루션을 찾을 수 있습니다. – ANisus

+0

JSON은 숫자 리터럴의 의미를 지정하지 않으므로 정수보다 double을 사용하는 것이 정확하지 않습니다. 다트에는 두 가지 숫자 유형이 있습니다.소수점이나 지수 부분을 포함하는 것은 모두 double이어야하며 그 외 모든 것은 정수로 파싱되어야합니다.이 경우 Dart에서는 double보다 정밀도가 좋습니다. 이렇게하면 가능한 JSON 번호에서 많은 정보가 보존됩니다. 모든 숫자를 두 배로 만들려면 .toDouble을 수동으로 사용해야합니다. – lrn

1

에 다음은 솔루션 (나에게)로 나타납니다. 정수 메소드 toDouble()은 "num"(또는 그 반대)에서도 작동합니다. Dart가 double 또는 int로 해석 할 수있는 json 및 통화 값을 사용하여 작업 할 때 "as num"을 사용하고 내장 메서드 toDouble()을 사용할 필요가 있다는 것을 알았습니다.

예 (이동) :

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

예 (다트) :

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를 추측합니다 - 간접적으로). –

관련 문제