Dart 使用默认值初始化成员的最优雅方式
是否有任何方法可以使用初始值设定项列表来选择性地初始化可选值 构造函数中的参数?以下示例采用if(?x)类型 正文中的逻辑,因为不清楚如何仅在初始值设定项列表中设置\u x 如果它通过了Dart 使用默认值初始化成员的最优雅方式,dart,Dart,是否有任何方法可以使用初始值设定项列表来选择性地初始化可选值 构造函数中的参数?以下示例采用if(?x)类型 正文中的逻辑,因为不清楚如何仅在初始值设定项列表中设置\u x 如果它通过了 类点{ double x=0.0; double get x=>\ux; 双y=0.0; double get y=>\u y; 点( { 双x, 双y }) { 如果(?x){ux=x;} 如果(?y){uy=y;} } } 另一种方法是让构造函数: 点( { 双x:0.0, 双y:0.0 }):x=x,
类点{
double x=0.0;
double get x=>\ux;
双y=0.0;
double get y=>\u y;
点(
{
双x,
双y
})
{
如果(?x){ux=x;}
如果(?y){uy=y;}
}
}
另一种方法是让构造函数:
点(
{
双x:0.0,
双y:0.0
}):x=x,y=y
{
}
但是当你重复你自己(0.0多个地方)时,它看起来像是x和y被初始化了两次,一次是为成员初始化,然后又被初始化列表初始化。此外,成员初始值设定项的一个好处是它可以是函数调用,而默认参数的默认值似乎需要常量。我希望/意识到对性能的影响很小。只需要一种很好的规范化方法,可能用于代码生成。您可以使用
这个
前缀在构造函数中初始化变量,例如:
class PointA{
双x;
double get x=>\ux;
双y;
double get y=>\u y;
点A({加倍这个。x=0.0,加倍这个。y=0.0});
}
类PointB{
最后的双x;
最后双y;
点({double this.x=0.0,double this.y=0.0});
}
void main(){
新的PointA(_y:2.0);
新的PointA(x:3.0);
新的PointA(x:2.0,y:3.0);
新的B点(y:2.0);
新的B点(x:3.0);
新的b点(x:2.0,y:3.0);
}
非常适合常量。
显然有一个三元运算符在成员中起作用
初始化器。因此,如果字段的初始化很昂贵(例如
需要函数调用和/或创建对象),此方法似乎有效:
- 不要麻烦初始化类中的成员-更喜欢 建造师。否则,可能会浪费精力
- 跳过nice this.member参数语法。而是使用成员名称和 使会员符合此条件。在作业中
- 在成员初始值设定项中使用带三元运算符的parm。下面是一个假设为成员创建默认值代价高昂的示例
输出:class Formats { static Map<String,dynamic> defaultFormats() { print("Expensive call - avoid if possible"); return { "th" : 'default th', "td" : 'default td' }; } Map<String,dynamic> leftTbl; Map<String,dynamic> rightTbl; Formats( { Map<String,dynamic> leftTbl, Map<String,dynamic> rightTbl }) : this.leftTbl = ?leftTbl? leftTbl : defaultFormats(), this.rightTbl = ?rightTbl? rightTbl : defaultFormats() { } String toString() { return """ l => $leftTbl, r => $rightTbl """; } }
作为对的修改,您可以执行以下操作:Expensive call - avoid if possible Expensive call - avoid if possible l => {th: default th, td: default td}, r => {th: default th, td: default td} Expensive call - avoid if possible l => {th: solid #089, td: solid #089}, r => {th: default th, td: default td} l => {th: solid #189, td: solid #189}, r => {th: solid #189, td: solid #189}
class Formats { static Map<String,dynamic> defaultFormats() { print("Expensive call - avoid if possible"); return { "th" : 'default th', "td" : 'default td' }; } Map<String,dynamic> leftTbl; Map<String,dynamic> rightTbl; Formats( { Map<String,dynamic> leftTbl, Map<String,dynamic> rightTbl }) : this.leftTbl = leftTbl ?? defaultFormats(), this.rightTbl = rightTbl?? defaultFormats() { } String toString() { return """ l => $leftTbl, r => $rightTbl """; } }
核心区别在于使用了if null运算符(类格式{ 静态映射defaultFormats(){ 打印(“昂贵的呼叫-尽可能避免”); 返回{ “th”:“默认th”, “td”:“默认td” }; } 映射左TBL; 地图右侧TBL; 格式( { 映射左TBL, 右图 }):this.leftTbl=leftTbl??defaultFormats(), this.rightTbl=rightTbl??defaultFormats() { } 字符串toString(){ 返回“” l=>$leftTbl, r=>$rightTbl """; } }
)?
在
,如果this.leftTbl=leftTbl??defaultFormats()
为空,则只将leftTbl
返回的值赋值给它。这是一个不错的特性,不幸的是,它没有正确地将未传递的参数值初始化为0,而是将其初始化为空。例如,第一个初始化为(null,2.0)而不是(0.0,2.0)。这是我的方法(注意defaultFormats()
和\ux
字段上的\uy
关键字-这表示它们必须作为构造函数初始化的一部分或之前进行初始化-这不是强制性的,但示例类“看起来”像final
和x
是只读的)如果x和y是final,那么就不需要获得者了,只需要进行x和y决赛。这也会使构造函数签名更好。我尽量不在构造函数中使用y
这个。因为你正在公开私有内部。虽然这个答案现在很好,但一定要检查最新的规范。根据这个:-“?操作员吉拉德:我们能摆脱它吗?拉尔斯:是的。吉拉德:好的,完成。”谢谢。我将努力理解这一变化并更新我的方法。其思想是只对所有成员(即使是昂贵的成员)进行一次干净的初始化。希望使用成员初始值设定项的新的/更好的方法是可能的。
class Formats { static Map<String,dynamic> defaultFormats() { print("Expensive call - avoid if possible"); return { "th" : 'default th', "td" : 'default td' }; } Map<String,dynamic> leftTbl; Map<String,dynamic> rightTbl; Formats( { Map<String,dynamic> leftTbl, Map<String,dynamic> rightTbl }) : this.leftTbl = leftTbl ?? defaultFormats(), this.rightTbl = rightTbl?? defaultFormats() { } String toString() { return """ l => $leftTbl, r => $rightTbl """; } }