寻求 Python 字典作为 return 类型到 Dart 的安全翻译
Seeking a safe translation of a Python dict as a return type to Dart
有时我们都需要从一个函数中快速 return 多个值,并寻找一种动态创建新类型的方法。
在Python中我可以return一个元组
def get_trio1():
return (True, 23, "no")
(_, first1, second1) = get_trio1()
print(first1)
print(second1)
忽略其中一个值,并在一个作业中即时检索另外两个值。
我同样可以return一个数组。
def get_trio2():
return [True, 23, "no"]
[_, first2, second2] = get_trio2()
print(first2)
print(second2)
但这两者都很脆弱。如果我编辑代码以添加一个值,特别是如果它在已经定义的三个值之内,修改后的代码可能会无提示地失败。
这就是为什么最好的解决方案是即时创建 dict
。
def get_trio3():
return {"b": True, "i": 23, "s": "no"}
r = get_trio3()
print(r["i"])
print(r["s"])
命名成员的使用意味着维护代码更加安全。
要在 Dart 中获得相同的安全性,我能做的最接近的事情是什么?是否需要为 return 类型定义 class?
以防万一,当return未来时,上下文正在避免List<List<dynamic>>
。
Future<List<dynamic>> loadAsset() async =>
return await Future.wait([
rootBundle.loadString('assets/file1.txt'),
rootBundle.loadString('assets/file2.txt'),
]);
更新
将 Stephen 的答案用于未来会引入一个问题。 Future.wait
硬连线使用 array Iterable.
Future<Map<String, dynamic>> loadAsset() async =>
return await Future.wait({
"first": rootBundle.loadString('assets/file1.txt'),
"second": rootBundle.loadString('assets/file2.txt'),
});
使用地图。
Map<String, dynamic> foo() => {'A': 'a', 'B': 'b', 'C': false }
var result = foo();
print result['B']; // prints b;
您的 loadAsset
函数 return 是 Future<List<dynamic>>
因为您就是这样声明它的。您可以将其声明为 return a Future<List<String>>
。
Future.wait
is hardwired to use an array.
特别是由于 Dart 是一种静态类型的语言,您不能真的期望它同时采用 List
和一些 Map
以及您的自定义语义。您可以编写自己的版本:
Future<Map<String, T>> myFutureWait<T>(Map<String, Future<T>> futuresMap) async {
var keys = futuresMap.keys.toList();
var values = futuresMap.values.toList();
var results = await Future.wait<T>(values);
return Map.fromIterables(keys, results);
}
有时我们都需要从一个函数中快速 return 多个值,并寻找一种动态创建新类型的方法。
在Python中我可以return一个元组
def get_trio1():
return (True, 23, "no")
(_, first1, second1) = get_trio1()
print(first1)
print(second1)
忽略其中一个值,并在一个作业中即时检索另外两个值。
我同样可以return一个数组。
def get_trio2():
return [True, 23, "no"]
[_, first2, second2] = get_trio2()
print(first2)
print(second2)
但这两者都很脆弱。如果我编辑代码以添加一个值,特别是如果它在已经定义的三个值之内,修改后的代码可能会无提示地失败。
这就是为什么最好的解决方案是即时创建 dict
。
def get_trio3():
return {"b": True, "i": 23, "s": "no"}
r = get_trio3()
print(r["i"])
print(r["s"])
命名成员的使用意味着维护代码更加安全。
要在 Dart 中获得相同的安全性,我能做的最接近的事情是什么?是否需要为 return 类型定义 class?
以防万一,当return未来时,上下文正在避免List<List<dynamic>>
。
Future<List<dynamic>> loadAsset() async =>
return await Future.wait([
rootBundle.loadString('assets/file1.txt'),
rootBundle.loadString('assets/file2.txt'),
]);
更新
将 Stephen 的答案用于未来会引入一个问题。 Future.wait
硬连线使用 array Iterable.
Future<Map<String, dynamic>> loadAsset() async =>
return await Future.wait({
"first": rootBundle.loadString('assets/file1.txt'),
"second": rootBundle.loadString('assets/file2.txt'),
});
使用地图。
Map<String, dynamic> foo() => {'A': 'a', 'B': 'b', 'C': false }
var result = foo();
print result['B']; // prints b;
您的 loadAsset
函数 return 是 Future<List<dynamic>>
因为您就是这样声明它的。您可以将其声明为 return a Future<List<String>>
。
Future.wait
is hardwired to use an array.
特别是由于 Dart 是一种静态类型的语言,您不能真的期望它同时采用 List
和一些 Map
以及您的自定义语义。您可以编写自己的版本:
Future<Map<String, T>> myFutureWait<T>(Map<String, Future<T>> futuresMap) async {
var keys = futuresMap.keys.toList();
var values = futuresMap.values.toList();
var results = await Future.wait<T>(values);
return Map.fromIterables(keys, results);
}