dart 未行程的例外状况:类型“List< dynamic>”不是类型“FutureOr&lt;List&lt;Map&lt;String,String&gt;”的子类型

nle07wnf  于 2023-09-28  发布在  其他
关注(0)|答案(2)|浏览(101)

我有一个从SQL Server获取数据的函数。错误指向此函数的最后一行。当我在另一个文件中调用这个函数时,我使用的是await。为什么我得到这个错误?我需要在另一个文件中使用一个List<Map<String, String>>。我已经试过做res = json.decode(res) as List<Map<String, String>>;,但这不工作。

Future<List<Map<String, String>>> getServerList() async {
  //...

  //res is a String here
  //example of data inside res variable: [{ServerName: Server1, ServerIP: IP1, DatabaseName: DB1, PortNum: 1433, Status: null}, {ServerName: Server2, ServerIP: IP2, DatabaseName: DB2, PortNum: 1433, Status: null}]
  var res = await SqlConn.readData("declare @Status nvarchar(4000) exec spHandheldServerList @Status output"); 

  //...     

  //Changes res from a String to a List<dynamic>
  res = json.decode(res);

  return res; //ERROR POINTS HERE
}
ie3xauqp

ie3xauqp1#

json.decode解析JSON时,返回值的运行时类型将是以下类型之一,具体取决于解析的JSON字符串:

  • null
  • bool
  • int
  • double
  • String
  • List<dynamic>
  • Map<String, dynamic>

(In在后两种情况下,列表或Map中的每个项目也将是这些类型之一。
在您的例子中,它是List<dynamic>,它不能隐式转换为任何其他类型的列表。您需要调用castmap(或两者),以便将列表显式转换为所需的类型。因为您处理的是嵌套在List中的Map s,所以不仅需要转换外部的List,还需要转换内部的Map s。

final res = await SqlConn.readData(...);

final dynlist = json.decode(str) as List<dynamic>;

final listOfMaps = dynlist.map((ch) => (ch as Map<String, dynamic>).cast<String, String>());

return listOfMaps;

如果事先知道JSON的结构,则需要将任何Map解析为数据类。这为您提供了类型安全性和可靠性,这是不可能单独从Map中获得的。

class ServerMetadata {
  final String serverName;
  final String serverIP;
  final String databaseName;
  final int portNum;
  final String? status;
  
  const ServerMetadata(this.serverName, this.serverIP, this.databaseName, this.portNum, this.status);
  
  factory ServerMetadata.fromJson(Map<String, dynamic> map) {
    return ServerMetadata(
      map['ServerName'] as String,
      map['ServerIP'] as String,
      map['DatabaseName'] as String,
      map['PortNum'] as int,
      map['Status'] as String?,
    );
  }
}
final res = await SqlConn.readData(...);
final dynlist = json.decode(str) as List<dynamic>;
final servers = dynlist.map((map) => ServerMetadata.fromJson(map));
ttcibm8c

ttcibm8c2#

Future<List<Map<String, String>>> getServerList() async中删除'Future'以返回您需要的List<Map<String, String>>类型的列表。基本上,当你用await解析变量并将其转换为json(它已经返回了List<Map<String, String>>类型的列表)时,你的变量不再是'Future'类型。

相关问题