在Dart中类型安全对象上使用扩散算子

but5z9lq  于 2023-01-03  发布在  其他
关注(0)|答案(2)|浏览(136)

我想在键-值-数据上使用Spread操作符(...),并保证类型安全。在TypeScript中,我可以通过接口实现这一点,但在dart中,我找不到这样做的方法。

**方法1失败:**使用类

class Foo {
  int aNumber;
  String aString;
}

Foo a = Foo();
Foo b = { ...a, 'aString': 'ipsum' }; // This literal must be either a map or a set.

**方法2失败:**使用Map

Map<String, dynamic> a = { 'aNumber': 2, 'aString': 'lorem' };
Map<String, dynamic> b = { ...a, 'aString': 'ipsum' }; // No error, but also no type safety.

注:在这些方法中,B不应是一个列表。

TypeScript所需内容的示例

interface Foo {
  aNumber: number;
  aString: string;
}
const a: Foo = { aNumber: 2, aString: 'lorem' };
const b: Foo = { ...a, aString: 'ipsum' }; // Has all the props of 'a' and overrides 'aString' to 'ipsum'.
inn6fuwd

inn6fuwd1#

您可以使用第一种方法来实现它,但是这个代码片段有两个问题:
首先检查spread操作符是在iterable中实现的,因此Foo a = Foo();行应该替换为某个iterable,例如列表。
第二个问题,Foo b = { ...a };上的编译错误是因为Dart对集合和Map都使用{},所以必须通过在<>中添加一个或两个类型参数来指定类型。
检查以下示例:

var a = <Foo>[];
  var b = <String>[];  
  var c = <Foo>{...a}; // works, a is Foo list
  var d = <Foo>{...b}; // compile time error, 'String' can't be assigned to the set type 'Foo'.

因为我们在var d = <Foo>{...b};中只使用了一个参数,dart知道我们需要一个集合。
更新:
在这种情况下,你不能使用spread运算符。spread运算符的引入是为了简化集合的工作,集合的类型由泛型参数给出。所以如果你的类没有实现Iterable,你就不能在一个给定的示例上调用......。你会得到一个编译时错误:

Spread elements in list or set literals must implement 'Iterable'

另一方面,正如你提到的第二种方法"没有给你"类型安全,因为你使用的是dynamic.并且ONLY编译,因为你声明的是Map<String, dynamic> a = { 'aNumber': 2, 'aString': 'lorem' };,它是一个map并且实现Iterable(你可以使用... a)。
对于您当前的问题,您需要找到一个不同的解决方案,可能是Foo类上的一个自定义函数,它返回一个Map并处理类型,然后在该Map上使用spread运算符。
希望能有所帮助!

5hcedyr0

5hcedyr02#

只是加一点盐当我错误地使用智能引号作为我的Map键时(在macOS上使用“而不是“- options+maj+quote),我得到了这个错误。

相关问题