2013-03-13 59 views
2

是否有任何方式使用初始化列表可選在構造函數中初始化可選 參數?下面的示例訴諸如果(?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得到由初始化列表中再次初始化兩次,一次爲會員,然後。此外,成員初始值設定項的好處是可以是函數調用,而默認參數的默認值似乎需要常量。我希望/認識到性能影響很小。只需要一個很好的規範方法,可能用於代碼生成。

回答

1

Chris Buckett's answer是偉大的常量。 顯然有一個三元運算符在成員 初始值設定項中工作。所以,如果一個字段的初始化是昂貴的(比如 需要一個函數調用和/或對象的創建),這種方法似乎工作:

  • 不要打擾初始化類中的成員 - 喜歡 構造(S)。否則,可能會浪費精力。
  • 跳過不錯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 
    """; 
        } 
    } 
    

使用示例:

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} 
+1

雖然現在這個答案很好,但一定要檢查最新的規範。據此:https://groups.google.com/a/dartlang.org/forum/?fromgroups#!topic/misc/vlWcc43EnL4 - 「?運營商 吉拉德:我們可以擺脫它嗎? 拉爾斯:是 吉拉德:好的,完成了。「 – 2013-05-17 13:26:40

+0

謝謝。我將嘗試瞭解這一變化並更新我的方法。這個想法是簡單地初始化所有成員,甚至是昂貴的成員,只有一次。希望使用成員初始值設定項的新/更好的方法是可能的。 – user1338952 2013-05-17 13:38:18

2

可以初始化使用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); 
} 
+0

這是一個不錯的功能,遺憾的是它沒有正確初始化未傳遞的參數值設置爲0,而是空值。例如,第一個初始化爲(null,2.0)而不是(0.0,2.0)。 – user1338952 2013-03-13 22:22:37

+0

好吧,我已經改變了我的代碼示例上面。這是我已經完成的方式(注意'_x'和'_y'字段上的'final'關鍵字 - 這表示它們必須作爲構造函數初始化的一部分進行初始化或者之前 - 它不是必需的,但是該示例class「looks」like'x' and'y' is read-only) – 2013-03-14 08:24:22

+0

如果_x和_y是final的,那麼就不需要getter了,只需要讓x和y最終。這將使構造函數簽名更好。我試圖從不在構造函數中使用'this._something',因爲你正在暴露私人內部。 – 2013-03-14 15:34:34

相關問題