weight
はフィールド(Number in Firestore )であり、100
として設定されます。
int weight = json['weight'];
double weight = json['weight'];
int weight
は正常に機能し、期待どおり100
を返しますが、double weight
を返すのではなく、Object.noSuchMethod
がクラッシュします(100.0
例外)。
ただし、以下は機能します。
num weight = json['weight'];
num.toDouble();
解析時100
Firestore(実際には「数値型」をサポートしていませんが、 変換 です)、標準ではint
に解析されます。
Dartは、これらの型を自動的に「賢く」キャストしません。実際、int
をdouble
にキャストすることはできません。これは直面している問題です。可能であれば、コードは正常に動作します。
代わりに、自分でparseできます。
double weight = json['weight'].toDouble();
また、JSONをnum
に解析し、それをdouble
に割り当てます。これにより、num
をdouble
にキャストします。
double weight = json['weight'] as num;
これは最初は少し奇妙に思えますが、実際には Dart Analysis tool (VS CodeおよびIntelliJのDartプラグインに組み込まれています)は"不要なキャスト"としてマークします、そうではありません。
double a = 100; // this will not compile
double b = 100 as num; // this will compile, but is still marked as an "unnecessary cast"
double b = 100 as num
num
はスーパークラス の double
であり、Dartは明示的なキャストがなくてもスーパータイプをサブタイプにキャストするため、コンパイルされます。
明示的なキャストは次のようになります:
double a = 100 as double; // does not compile because int is not the super class of double
double b = (100 as num) as double; // compiles, you can also omit the double cast
これはいい読みです 約 "タイプとDartでのキャスト"。
あなたに起こったことは次のとおりです:
double weight;
weight = 100; // cannot compile because 100 is considered an int
// is the same as
weight = 100 as double; // which cannot work as I explained above
// Dart adds those casts automatically
以下のようにデータを解析できます:
ここにドキュメントはMap<String,dynamic>
double opening = double.tryParse(document['opening'].toString());
あなたは一行でそれを行うことができます:
double weight = (json['weight'] as num).toDouble();
Dartでは、int
とdouble
は別々のタイプで、どちらもnum
のサブタイプです。
数値タイプ間の自動変換はありません。あなたが書く場合:
_num n = 100;
double d = n;
_
実行時エラーが発生します。 Dartの静的型システムは安全でないダウンキャストを許可しているため、n
からd
への安全でない割り当て(すべてのnum
値がdouble
値であるとは限らないため安全ではない)は暗黙的に次のように扱われます。
_num n = 100;
double d = n as double;
_
_as double
_ checks値は実際にはdouble
(またはnull
)であり、そうでない場合はスローされます。そのチェックが成功すると、変数の型と一致することがわかっているため、値をd
に安全に割り当てることができます。
それがここで起こっていることです。 _json['weight']
_(静的型Object
またはdynamic
の可能性が高い)の実際の値は、値100のint
オブジェクトです。これをint
に割り当てます動作します。 num
への割り当ては機能します。 double
throwsに割り当てます。
Dart JSONパーサーは、小数部または指数部がない場合、数値を整数として解析します(_0.0
_はdouble、_0e0
_はdouble、_0
_は整数)。これはほとんどの場合非常に便利ですが、double
が必要な場合など、場合によっては煩わしいこともありますが、JSONを作成するコードでは、それをdoubleとして記述していません。
そのような場合、値を抽出するときに、値に.toDouble()
を記述するだけです。それは実際のダブルスではノーオペレーションです。
ちなみに、JavaScriptにコンパイルされたDartは、すべての数値をJavaScriptの数値型として表します。つまり、すべての数値は2倍になります。 JSコンパイル済みコードでは、すべての整数を変換せずにdoubleに割り当てることができます。 notは、コードがJavaScript以外の実装(Flutter、Dart VM/server、iOSの事前コンパイルなど)で実行されるときに機能するので、それに依存しないでください。コードは移植できません。