web-dev-qa-db-ja.com

数値をdoubleに変換できないのはなぜですか?

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();
4
kenwen

解析時100 Firestore(実際には「数値型」をサポートしていませんが、 変換 です)、標準ではintに解析されます。
Dartは、これらの型を自動的に「賢く」キャストしません。実際、intdoubleにキャストすることはできません。これは直面している問題です。可能であれば、コードは正常に動作します。

解析中

代わりに、自分でparseできます。

double weight = json['weight'].toDouble();

鋳造

また、JSONをnumに解析し、それをdoubleに割り当てます。これにより、numdoubleにキャストします。

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 numnumはスーパークラス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());
1
Dishant Mahajan

あなたは一行でそれを行うことができます:

 double weight = (json['weight'] as num).toDouble();
1
Michael Berger

Dartでは、intdoubleは別々のタイプで、どちらも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の事前コンパイルなど)で実行されるときに機能するので、それに依存しないでください。コードは移植できません。

0
lrn