2014-11-01 51 views
1

我遇到過這個問題(並感謝操場我能找到它)爲什麼具有函數的swift字典在類的外部工作而在類內部產生錯誤?

我嘗試使用一個字典,它的數字作爲鍵和函數的值。一切正常的一類精細外:

private func hello1(x: Double) { 
    println("hello1") 
} 
private func hello2(x: Double) { 
    println("hello2") 
} 

private let contacts: [Int: Double ->()] = [ 
    0 : hello1, 
    1 : hello2 
] 

contacts[1]?(1.0) // Works fine :-) 

當我把相同的代碼的類中,我得到一個編譯錯誤

「雙」不是「SomeClass的」

亞型

用同一代碼:

internal class SomeClass { 
    private func hello1(x: Double) { 
     println("hello1") 
    } 
    private func hello2(x: Double) { 
     println("hello2") 
    } 

    private let contacts: [Int: Double ->()] = [ // *** Here I get the error *** 
     0 : hello1, 
     1 : hello2 
    ] 

    internal func runIt() { 
     contacts[1]?(1.0) 
    } 
} 

let someClass = SomeClass() 
someClass.runIt() 

我試過bracke的幾種方法TS。沒有改進。

學習Swift時我錯過了什麼?我誤解或曲解了什麼?

回答

1

hello1hello2是一種實例方法。如果它們被引用爲SomeClass.hello1,則該類型將是SomeClass -> (Double) ->()。所以你可以這樣稱呼它:

var foo = SomeClass() 
SomeClass.hello1(foo)(1.0) 

這就像咖喱飯的功能。這就是爲什麼你得到錯誤'Double' is not a subtype of 'SomeClass'

如果你想要做你想做什麼,你應該這樣做:

internal class SomeClass { 
    private func hello1(x: Double) { 
     println("hello1") 
    } 
    private func hello2(x: Double) { 
     println("hello2") 
    } 

    lazy private var contacts: [Int: Double ->()] = [ 
     0 : self.hello1, 
     1 : self.hello2 
    ] 

    internal func runIt() { 
     contacts[1]?(1.0) 
    } 
} 

你必須使用lazy var,而不是let,或者你不能引用self


ADDED:

以上代碼使得強參考週期。您應該使用[unowned self]關閉。

lazy private var contacts: [Int: Double ->()] = [ 
    0 : {[unowned self] in self.hello1($0) }, 
    1 : {[unowned self] in self.hello2($0) } 
] 
+0

男人,你讓我的一天!我在SpriteKit遊戲中使用這段代碼來保持'didBeganContact()'儘可能通用。 – jboi 2014-11-01 14:31:00

+0

請看我更新的答案。 – rintaro 2014-11-01 16:01:11

相關問題