لماذا لا يمكنني تحويل رقم إلى مزدوج؟

1

weight هو حقل (رقم في 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();

3 الاجابة

10
افضل جواب

عند التحليل 100 من Firestore (الذي لا يدعم في الواقع "نوع الرقم" ، ولكنه يحوله ) ، سيتم تحليله بشكل قياسي إلى int .
لا يقوم Dart تلقائيًا بإلقاء هذه الأنواع "بذكاء". في الواقع ، لا يمكنك إلقاء int إلى double ، وهي المشكلة التي تواجهها. إذا كان ذلك ممكنًا ، فإن كودك سيعمل بشكل جيد.

تفسير

بدلاً من ذلك ، يمكنك تحليلها بنفسك:

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

يصب

ما يعمل أيضا ، هو تحليل JSON إلى num ثم تعيينه إلى double ، والتي ستلقى num إلى double .

double weight = json['weight'] as num;

يبدو هذا غريبًا بعض الشيء في البداية وفي الواقع فإن أداة Dart Analysis (التي تم تضمينها على سبيل المثال في المكون الإضافي Dart لـ VS Code و IntelliJ) ستميزها على أنها "طاقم عمل غير ضروري" ، وهو ليس كذلك.

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

هنا قراءة لطيفة عن "الأنواع والصب في دارت" .

تفسير

ما حدث لك هو ما يلي:

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
:مؤلف
0

يمكنك تحليل البيانات كما هو موضح أدناه:

الوثيقة هنا هي خريطة

الفتح المزدوج = double.tryParse (المستند ['open']. toString ()) ؛

:مؤلف
0

في دارت ، int و double هي أنواع منفصلة ، كلا النوعين الفرعيين من num .

لا يوجد تحويل تلقائي بين أنواع الأرقام. إذا كتبت:

num n = 100;
double d = n;

ستحصل على خطأ وقت التشغيل. يسمح نظام Dart's الثابت بالنوع غير الآمن ، لذا فإن التعيين غير الآمن لـ n إلى d (غير آمن لأنه ليس كل شيء num القيم double القيم) يعامل ضمنيا على النحو التالي:

num n = 100;
double d = n as double;

ال as double يتحقق من أن القيمة هي في الواقع double (أو null ) ، ويلقي إذا لم يكن كذلك. إذا نجح هذا الفحص ، فيمكنه تعيين القيمة بأمان d لأنه من المعروف أنه يتطابق مع نوع المتغير.

هذا ما يحدث هنا. القيمة الفعلية لل json['weight'] (محتمل مع النوع الثابت Object أو dynamic ) هل int كائن بقيمة 100. تعيين ذلك إلى int يعمل. تعيينه إلى num يعمل. تعيينه إلى double يلقي.

يقوم محلل Dart JSON بتحليل الأرقام كأعداد صحيحة إذا لم يكن لها أجزاء عشرية أو أس ( 0.0 هو ضعف ، 0e0 هو ضعف ، 0 هو عدد صحيح). هذا مناسب جدًا في معظم الحالات ، ولكن مزعجًا أحيانًا في حالات مثل حالتك حيث تريد double ، لكن الشفرة التي تنشئ JSON لم تكتبها على أنها مزدوجة.

في مثل هذه الحالات ، عليك فقط الكتابة .toDouble() على القيم عند استخراجها. هذا لا يوجد مرجع بشأن الزوجي الفعلي.

كملاحظة جانبية ، يمثل Dart المترجمة إلى JavaScript جميع الأرقام كنوع رقم JavaScript ، مما يعني أن جميع الأرقام مضاعفة. في التعليمات البرمجية المترجمة لـ JS ، يمكن تعيين جميع الأعداد الصحيحة لمضاعفة دون تحويل. التي لن تعمل عند تشغيل التعليمات البرمجية على تنفيذ غير JS، مثل الرفرفة، السهام VM / الخادم أو تجميع المقبلة من الوقت لدائرة الرقابة الداخلية، لذلك لا تعتمد على ذلك، أو التعليمات البرمجية لن تكون محمولة.

:مؤلف

أسئلة ذات صلة

فوق
قائمة طعام