为什么我不能将数字转换为双精度数?

时间:2018-07-15 04:45:16

标签: dart google-cloud-firestore flutter

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

5 个答案:

答案 0 :(得分:9)

从Firestore(实际上不支持“数字类型”,但支持converts it)解析100时,通常会将其解析为 int
Dart 不会自动“智能”转换这些类型。实际上,您不能将int强制转换为double,这是您面临的问题。如果可能的话,您的代码就可以正常工作。

解析

相反,您可以自己解析

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 is the super class中的double和Dart即使没有显式转换也将super转换为子类型。
明确的演员表将是以下人:

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

Here is a nice read关于“ 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

答案 1 :(得分:6)

您可以一行完成:

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

答案 2 :(得分:0)

在Dart中,intdouble是单独的类型,都是num的子类型。

数字类型之间没有自动转换。如果您写:

num n = 100;
double d = n;

您将收到运行时错误。 Dart的静态类型系统允许进行不安全的向下转换,因此将nd的不安全分配(不安全,因为并非所有num的值都是double的值)被隐式地视为:

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

as double 检查该值实际上是一个double(或null),如果不是,则抛出该值。如果该检查成功,则可以安全地将值分配给d,因为已知该值与变量的类型匹配。

这就是这里发生的事情。 json['weight']的实际值(可能是静态类型Objectdynamic)是值为{100的int对象。将其分配给int即可。将其分配给num即可。将其分配给double引发。

如果Dart JSON解析器没有小数或指数部分(0.0是双精度,0e0是双精度,0是整数),则数字解析为整数。在大多数情况下,这很方便,但是在您想要double这样的情况下,有时会很烦人,但是创建JSON的代码并未将其写为double。

在这种情况下,提取值时只需在值上写.toDouble()。在实际的双打比赛中没有机会。

请注意,编译为JavaScript的Dart会将所有数字表示为JavaScript Number类型,这意味着所有数字均为双精度。在JS编译的代码中,所有整数都可以分配为double而不进行转换。当代码在非JS实现(例如Flutter,Dart VM /服务器或iOS的提前编译)上运行时,不起作用,因此请不要依赖它,或者您的代码将不可移植。

答案 3 :(得分:0)

您可以解析数据,如下所示:

此处文档是地图

双开= double.tryParse(document ['opening']。toString());

答案 4 :(得分:-1)

像这样简单地将int转换为double

int a = 10;
double b = a + 0.0;