2014-09-19 78 views
3

似乎有幾種情況下Swift類函數上的required關鍵字會非常有用,特別是由於類函數返回Self的能力。爲什麼`required`不是Swift中類函數的有效關鍵字?

當從class func返回Self,也有不幸的是兩個限制,使執行所述功能非常困難/抑制作用:

  1. 不能使用Self作爲函數裏面執行類型檢查,即:

    class Donut { 
        class func gimmeOne() -> Self { 
         // Compiler error, 'Self' is only available in a protocol or as the result of a class method 
         return Donut() as Self 
        } 
    } 
    
  2. 您不能返回的實際類型的類本身,即:

    class Donut { 
        class func gimmeOne() -> Self { 
         // Compiler error, 'Donut' is not convertible to 'Self' 
         return Donut() 
        } 
    } 
    

原因對於這些編譯器錯誤是有效的。如果您有一個GlazedDonut子類不會覆蓋此類功能,則有可能撥打GlazedDonut.gimmeOne()將返回Donut,其中不是 a Self

看來這種情況可以通過允許類用required指定這些函數來緩解。這將確保任何子類都會覆蓋該方法並引發他們自己的一輪類型檢查,確保GlazedDonut在任何情況下都會自行返回,從而消除了Donut回來的可能性。

有沒有技術,權威爲什麼這還沒有被添加?我想建議它作爲對Swift團隊的改進,但要確保它沒有明顯的原因,爲什麼它被省略或無法完成。

的理念,爲這個問題來源於此:

https://stackoverflow.com/a/25924224/88111

回答

1

required一般只在初始化使用「必要」的方法,因爲初始化並不總是在Swift中繼承。因此,爲了讓您在變量類(即元類類型的值,如Foo.Type)上調用初始化程序,您需要知道該類Foo和所有可能的子類都具有此初始化程序。

但是,方法(實例方法和類方法)總是被繼承。因此,required是沒有必要的。

順便說一句,你斷言「你不能返回類的實際類型」是不正確的。 (事實上​​,錯誤「Self」僅在協議中提供或者作爲類方法的結果「本身說你可以返回類的類型本身。)類似於Objective-C,你可以這樣做:

class Donut { 
    required init() { } 
    class func gimmeOne() -> Self { 
    return self() 
    } 
} 
+0

這是完美的。使用'self()'作爲構造函數效果很好。此外,這還允許子類重寫類函數,同時調用它們自己新添加的「必需」初始值設定項。這意味着''GlazedDonut''可以調用'self()',或者它可以調用'self(glazeAmout:「這麼多,太多了?」)'並且爲'GlazedDonut'和所有的子類創建初始值'required' *那*特別的甜甜圈類型。謝謝 - 這個問題一直困擾着我好幾天。 – 2014-09-20 13:32:47

1

你可以使用一個協議,使

protocol IDonut{ 
    class func gimmeOne()->Donut; 
} 

class Donut:IDonut { 
    class func gimmeOne() -> Donut { 
     return Donut(); 
    } 
} 

class GlazedDonut: Donut, IDonut{ 
    override class func gimmeOne()->Donut{ 
     return GlazedDonut(); 
    } 
} 
+0

這不太合適,因爲該方法不再返回「Self」。目標是'GlazedDonut.gimmeOne()'返回'GlazedDonut'。 – 2014-09-19 14:08:46

相關問題