Dart中如何为含列表与错误信息的嵌套返回列表指定类型?
解决方案
你想要的返回结构无法直接用List<List<Post>?, String?>实现——因为Dart的List是同质集合,所有元素必须属于同一泛型类型,这种写法会导致语法错误。更优的方案是使用类型安全的结构,下面提供两种常用实现方式:
方案一:使用Dart 3.0+ Record类型(简洁高效)
Dart 3.0引入的Record类型可以直接定义多类型的返回值,完美匹配你需要的“成功返回列表+null,失败返回null+错误字符串”的需求:
import 'dart:convert'; import 'package:http/http.dart' as http; Future<(List<Post>?, String?)> fetchPosts(int? limit, int? page) async { try { final http.Response response = await http.get( Uri.parse('$BACKEND_URL/posts?page=$page&limit=$limit'), ); if (response.statusCode == 200) { final List body = jsonDecode(response.body); final List<Post> posts = body.map((post) => Post.fromJson(post)).toList(); return (posts, null); } else { // 解析响应体中的错误信息,无信息则用默认提示 final String errorMsg = response.body.isNotEmpty ? jsonDecode(response.body)['message'] ?? '请求失败,状态码:${response.statusCode}' : '请求失败,状态码:${response.statusCode}'; return (null, errorMsg); } } catch (e) { // 捕获网络异常、解析错误等情况 return (null, '请求出错:${e.toString()}'); } }
使用示例:
void main() async { final (posts, error) = await fetchPosts(10, 1); if (error != null) { print('获取帖子失败:$error'); } else { print('成功加载${posts!.length}条帖子'); } }
方案二:自定义数据类(兼容所有Dart版本)
如果你的项目还在使用Dart 3.0以下版本,可以自定义一个结果类,明确区分成功/失败状态:
第一步:定义结果类
class PostResult { final List<Post>? posts; final String? error; // 成功构造函数 PostResult.success(this.posts) : error = null; // 失败构造函数 PostResult.failure(this.error) : posts = null; }
第二步:修改请求方法
import 'dart:convert'; import 'package:http/http.dart' as http; Future<PostResult> fetchPosts(int? limit, int? page) async { try { final http.Response response = await http.get( Uri.parse('$BACKEND_URL/posts?page=$page&limit=$limit'), ); if (response.statusCode == 200) { final List body = jsonDecode(response.body); final List<Post> posts = body.map((post) => Post.fromJson(post)).toList(); return PostResult.success(posts); } else { final String errorMsg = response.body.isNotEmpty ? jsonDecode(response.body)['message'] ?? '请求失败,状态码:${response.statusCode}' : '请求失败,状态码:${response.statusCode}'; return PostResult.failure(errorMsg); } } catch (e) { return PostResult.failure('请求出错:${e.toString()}'); } }
使用示例:
void main() async { final result = await fetchPosts(10, 1); if (result.error != null) { print('获取帖子失败:${result.error}'); } else { print('成功加载${result.posts!.length}条帖子'); } }
为什么不推荐用List<Object?>?
如果强行用Future<List<Object?>>返回[posts, null]或[null, error],会失去编译时类型检查的优势——你无法确保列表第一个元素一定是List<Post>?,第二个是String?,容易在后续代码中引发类型错误,因此不建议使用这种方式。
内容的提问来源于stack exchange,提问作者Dev-Siri
相关产品推荐
相关产品推荐

