Dart抽象可选参数
如何抽象出一个方法具有可选参数Dart抽象可选参数,dart,Dart,如何抽象出一个方法具有可选参数 抽象类CopyWith{ T copyWith({});//错误:应为标识符。 } 如果我添加一个标识符,比如{test},它会工作,子类可以有额外的参数 我想要实现什么? 我有一个复杂的状态管理器,我做了一些抽象,下面的代码是一个最小的代码,显示我的问题 导入“dart:collection”; 抽象类CopyWith{ T copyWith(可选的命名参数); } 抽象类管理器{ final_map=HashMap(); 添加(K键,V值){ _映射[键]=
抽象类CopyWith{
T copyWith({});//错误:应为标识符。
}
如果我添加一个标识符
,比如{test}
,它会工作,子类可以有额外的参数
我想要实现什么?
我有一个复杂的状态管理器,我做了一些抽象,下面的代码是一个最小的代码,显示我的问题
导入“dart:collection”;
抽象类CopyWith{
T copyWith(可选的命名参数);
}
抽象类管理器{
final_map=HashMap();
添加(K键,V值){
_映射[键]=值;
}
void copyWith(K键,可选参数){
断言(key!=null);
如果(_map.containsKey(键)){
_map[key].copyWith(可选的参数);
}
}
}
类用户实现CopyWith{
最终int id;
最后的字符串名;
用户({this.id,this.name});
用户copyWith({int-id,String-name}){
返回用户(
id:id??这个,
name:name??this.name,
);
}
}
类UserManager扩展管理器{}
void main(){
final userManager=userManager();
add(1,User(1,'test');
copyWith(1,{test:'test2'})
}
作为在我的库中遇到过这个问题的人,我想说的唯一方法是不要在基类中放置copyWith
为什么??因为只有当存在共享调用约定和行为时,才应该使函数具有多态性。在您的示例中,这两个类执行copyWith
的方式完全不同。将名称
发送到管理器.copyWith
是错误的,而且应该是错误的,因为管理器
没有名称
。如果在管理器.copyWith
中遇到名称,则表示代码中存在严重错误
此外,如果您作为一名负责任的程序员实际尝试调用copyWith
,您可能会检查是否允许传递名称,即
if(someObj是用户){
someObj.copyWith(键,名称:name);
}否则如果(someObj是经理){
抛出IllegalStateError('你不应该把名字传给经理!我现在该怎么处理这个名字?');
}
在这里,您已经完成了类型检查,因此无需将copyWith
设置为多态
然而,一些常见的行为可以是多态的,比如updateKey
。您可以将Keyable
作为一个接口,将Keyable updateKey(Key)
作为一个抽象方法,并将其委托给每个子类内部的非多态copyWith
。您的基类不接受任何命名参数(实际上根本没有参数)。它可以是T copyWith()代码>。如果我设置为copyWith()
,我在其他代码中有错误,例如copyWith c
是我在方法中的参数,我想调用并传递参数c.copyWith(x:'y')
@jamesdlin我添加了一些代码您无法将参数(可选或非可选)传递给未声明接受它们的方法或函数。也就是说,如果c
被声明为Foo
类型,则不能使用Foo.copyWith
未声明接受的参数调用c.copyWith
。无论您是否有0个参数或1个参数,无论它们是可选的还是命名的。这就是静态类型检查的工作原理。如果您知道c
属于派生类型,则必须首先将其强制转换为该类型。或者,您可以禁用静态类型检查:(c为动态).copyWith(x:'y')
,并假设调用的c.copyWith
的任何实现都采用命名的x
参数。(当然,如果没有,它会抛出一个错误。)你能给我举个例子吗?我这里的例子非常简单,假设抽象类中的copyWith
有许多公共逻辑,我必须在子类中复制这些逻辑,比如if(_map.containsKey(key))
有一些很好的Dart代码生成器,可以为类生成copyWith
,以及其他函数<例如,VSCode上的code>Dart数据类
。如果您真的对这种方式不满意,可以让copyWith
将Map
作为参数,并按名称提取参数。但是Object
将取消任何类型安全并破坏性能,这是使copyWith
共享的成本。此外,一个好的代码生成器还可以为您生成操作符==
,hashCode
,toJson
,toMap
,如果您试图在基类中实现它们,这简直是疯了。在我看来,copyWith
与那些方法是一样的。我不只是考虑copyWith
,我想让一个父类保留所有公共逻辑,我不想在子类中重复主题。在这种情况下,您应该分解这些行为,只提取最大的公共共享行为作为基类中的实用程序方法。这是OOP设计领域中的一种,只能在个案的基础上进行。但不要对样板太紧张,飞镖和颤振从来都不是为了简洁而设计的。