【问题标题】:type 'int' is not a subtype of type 'double' -- Dart/Flutter Error“int”类型不是“double”类型的子类型——Dart/Flutter 错误
【发布时间】:2020-08-07 10:15:04
【问题描述】:

所以我设置了一个 API,它在调用时会在特定端点上返回以下输出:

{
    "total_user_currency": 0.1652169792,
    "total_sats": 2184,
    "total_btc": 0.00002184,
    "outputArray": [
        {
            "txid": "642fd534cb3a670a31f4d59e70452b133b0b461d871db44fcc91d32bb6b6f0cc",
            "vout": 2,
            "status": {
                "confirmed": true,
                "block_height": 625673,
                "block_hash": "0000000000000000000310649c075b9e2fed9b10df2b9f0831efc4291abcb7fb",
                "block_time": 1586732907
            },
            "value": 546
        },

    ]
}

我正在使用以下 dart 类将该 JSON 解码为我可以与之交互的对象:

class UtxoData {
  final dynamic totalUserCurrency;
  final int satoshiBalance;
  final dynamic bitcoinBalance;
  List<UtxoObject> unspentOutputArray;

  UtxoData({this.totalUserCurrency, this.satoshiBalance, this.bitcoinBalance, this.unspentOutputArray});

  factory UtxoData.fromJson(Map<String, dynamic> json) {
    var outputList = json['outputArray'] as List;
    List<UtxoObject> utxoList = outputList.map((output) => UtxoObject.fromJson(output)).toList(); 

    return UtxoData(
      totalUserCurrency: json['total_user_currency'],
      satoshiBalance: json['total_sats'],
      bitcoinBalance: json['total_btc'],
      unspentOutputArray: utxoList
    );
  }
}

class UtxoObject {
  final String txid;
  final int vout;
  final Status status;
  final int value;

  UtxoObject({this.txid, this.vout, this.status, this.value});

  factory UtxoObject.fromJson(Map<String, dynamic> json) {
    return UtxoObject(
      txid: json['txid'],
      vout: json['vout'],
      status: Status.fromJson(json['status']),
      value: json['value']
    );
  }
}

class Status {
  final bool confirmed;
  final String blockHash;
  final int blockHeight;
  final int blockTime;

  Status({this.confirmed, this.blockHash, this.blockHeight, this.blockTime});

  factory Status.fromJson(Map<String, dynamic> json) {
    return Status(
      confirmed: json['confirmed'],
      blockHash: json['block_hash'],
      blockHeight: json['block_height'],
      blockTime: json['block_time']
    );
  }

}

下面是代码中实际调用API的函数:

Future<UtxoData> fetchUtxoData() async {
    final requestBody = {
      "currency": "USD",
      "receivingAddresses": ["bc1q5jf6r77vhdd4t54xmzgls823g80pz9d9k73d2r"],
      "internalAndChangeAddressArray": ["bc1q5jf6r77vhdd4t54xmzgls823g80pz9d9k73d2r"]
    };

    final response = await http.post('https://thisisanexmapleapiurl.com', body: jsonEncode(requestBody), headers: {'Content-Type': 'application/json'} );

    if (response.statusCode == 200 || response.statusCode == 201) {
      notifyListeners();
      print(response.body);
      return UtxoData.fromJson(json.decode(response.body));
    } else {
      throw Exception('Something happened: ' + response.statusCode.toString() + response.body );
    }
  }

但是,当我运行该函数时,我的编辑器中出现以下错误:

Exception has occurred.
_TypeError (type 'int' is not a subtype of type 'double')

我在 UtxoData 类的工厂方法中的 return UtxoData 语句中得到它,如下所示:

return UtxoData(
      totalUserCurrency: json['total_user_currency'],
      satoshiBalance: json['total_sats'],                    <<<<============= The exception pops up right there for some reason
      bitcoinBalance: json['total_btc'],
      unspentOutputArray: utxoList
    );

这很奇怪,因为我知道 API 在那里返回一个 int。 totalUserCurrency 和 bitcoinBalance 必须是动态的,因为它们可以是 0(整数)或任意数字,例如 12942.3232(双精度数)。

为什么会出现此错误,如何更正此错误?非常感谢

【问题讨论】:

  • 我把它放在变量 j 中,除了你的 json 末尾的“,”。我替换了 UtxoData.fromJson(json.decode(response.body));使用 UtxoData.fromJson(json.decode(j));它奏效了。是不是可以得到一个双精度值而不是一个整数?
  • 我不知道为什么它不起作用。我也是这么想的。您介意分享您尝试过的有效代码的要点或粘贴箱吗?
  • 当然。另外,请以 JSON 格式显示当时的响应数据。

标签: json flutter dart


【解决方案1】:

我有一个类似的问题,我从 API 获得的金额介于 0 到几千之间,包括小数。我尝试了以下方法:

this.balanceAmount = double.parse(json['total_balance']??'0.0'.toString());

这不适用于我的数据集。因此,我将其增强为以下适用于我的数据集的所有情况。您可能需要稍作改进。

double parseAmount(dynamic dAmount){

    double returnAmount = 0.00;
    String strAmount;

    try {

      if (dAmount == null || dAmount == 0) return 0.0;

      strAmount = dAmount.toString();

      if (strAmount.contains('.')) {
        returnAmount = double.parse(strAmount);
      }  // Didn't need else since the input was either 0, an integer or a double
    } catch (e) {
      return 0.000;
    }

    return returnAmount;
  }

【讨论】:

  • 如果你遵循这个逻辑,当你收到一个整数时,你会返回 0.00。我看不出 parse 方法和可选的 onError 属性的区别
  • 没错。这是因为,在我的情况下,A. 构造函数需要一个双精度数,但 B. 服务器自动将 2122.0 舍入到 2122。这造成了一个问题。我认为它是用 Php 制作的,这可能就是 Php 的工作方式。这就是原因,我会指定 contains('.') 的具体条件
【解决方案2】:

如果您正在解析数据,并且不确定它是Int 还是double,则有多种解决方案。

如果您需要Int,请使用parsedData.truncate(),这适用于Intdouble,它通过丢弃小数解析为Int。同样,如果您希望小数对结果产生影响,也可以使用 cail()floor()

所以,在你的情况下,你只需要这样做:

satoshiBalance: json['total_sats'].truncate(),

我希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2021-05-16
    • 1970-01-01
    • 2020-03-18
    • 2020-03-19
    • 2022-11-24
    • 2022-10-13
    • 2021-05-10
    • 2020-04-23
    • 2021-08-12
    相关资源
    最近更新 更多