23

初期化リストを利用して、コンストラクターでオプションのパラメーターをオプションで初期化する方法はありますか?次の例では、本体にif(?x)タイプのロジックを使用しています。これは、_xが渡された場合にのみ、初期化子リストに_xを設定する方法が明確でないためです。

class Point { 
    double _x = 0.0;
    double get x => _x;
    double _y = 0.0;
    double get y => _y;

    Point(
        {
        double x,
        double y
        })
    { 
        if(?x) { _x = x; }
        if(?y) { _y = y; }
    }
}

別の方法は、コンストラクターを持つことです。

Point(
      {
        double x: 0.0,
        double y: 0.0
      }) : _x = x, _y = y
{
}

しかし、あなたは自分自身を繰り返しており(0.0複数の場所)、_ xと_yが2回初期化されているように見えます。1回はメンバー用で、もう1回は初期化子リストによってです。また、メンバー初期化子の利点は、関数呼び出しである可能性があることですが、デフォルトパラメーターのデフォルト値には定数が必要なようです。パフォーマンスへの影響が小さいことを願っています。コード生成で使用される可能性が高い、優れた標準的なアプローチが必要です。

4

3 に答える 3

26

thisプレフィックスを使用してコンストラクターで変数を初期化できます。例:

class PointA { 
  double _x;
  double get x => _x;
  double _y;
  double get y => _y;

  PointA({double this._x=0.0, double this._y=0.0});
}

class PointB { 
  final double x;
  final double y;

  Point({double this.x=0.0, double this.y=0.0});
}

void main() {
  new PointA(_y:2.0); 
  new PointA(_x:3.0); 
  new PointA(_x:2.0, _y:3.0); 

  new PointB(y:2.0); 
  new PointB(x:3.0); 
  new PointB(x:2.0, y:3.0); 
}
于 2013-03-13T20:49:02.380 に答える
12

Chris Buckettの答えは、定数に最適です。どうやら、メンバー初期化子で動作する三項演算子があります。したがって、フィールドの初期化にコストがかかる場合(たとえば、関数呼び出しやオブジェクトの作成が必要な場合)、このアプローチは機能するようです。

  • クラスのメンバーをわざわざ初期化しないでください。コンストラクターを優先してください。そうしないと、無駄な労力がかかる可能性があります。
  • 素敵な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})
      : leftTbl = leftTbl ?? defaultFormats(),
        rightTbl = rightTbl ?? defaultFormats();

  @override
  String toString() {
    return """
l => $leftTbl,
r => $rightTbl
""";
  }
}

使用例:

print(new Formats());
print(new Formats(leftTbl: {"th":'solid #089', "td":'solid #089' }));
print(new Formats(leftTbl: {"th":'solid #189', "td":'solid #189'},
      rightTbl: {"th":'solid #189', "td":'solid #189'}));

出力:

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}
于 2013-03-14T23:20:00.260 に答える
6

user1338952の回答を変更すると、次のことができます。

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演算子??)の使用です。

ではthis.leftTbl = leftTbl ?? defaultFormats()leftTblがnullの場合、によって返される値defaultFormats()は単純にそれに割り当てられます。

于 2018-05-26T09:50:36.797 に答える