簡體   English   中英

Swift 2.0:在初始化存儲屬性之前在方法調用中使用self

[英]Swift 2.0: use of self in method call before stored properties are initialised

剛開始看這個周末的Swift。 我正在為我的班級創建一個id來快速比較對象。 我想要一個不可變的id,所以應該使用let。

使用var和初始化id為“”將修復“在初始化存儲屬性之前在方法調用中使用self”,但當然它是可變的。 我見過的所有其他問題都與超級/調用super.init有關,我沒有。 這非常令人沮喪,我不知道為什么它不直接。

class MagicCard {

    let id:String
    let name: String
    let manaCost: Int
    let description: String
    let attack: Int
    let defence: Int

    init (name: String, manaCost: Int, description: String, attack: Int, defence: Int) {
        self.name = name
        self.manaCost = manaCost
        self.description = description
        self.attack = attack
        self.defence = defence
        id = generateRandomID()
    }

    private func generateRandomID() -> String {
        let charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        let charSetArray = Array(charSet.characters)
        var id:String = ""
        for _ in (0..<10) {
            id.append(charSetArray[Int(arc4random()) % charSetArray.count])
        }
        return id
    }
}

func == (lhs: MagicCard, rhs: MagicCard) -> Bool {
    return lhs.id == rhs.id
}

我可以建議的一個熱門修復是使generateRandomID成為類func。 所以就這樣:

private class func generateRandomID() -> String {

並且這樣打電話:

id = MagicCard.generateRandomID()

generateRandomID()方法不使用或修改實例的任何屬性,因此一種可能的解決方案是使其成為類型(類)方法:

private class func generateRandomID() -> String {
    // ...
    return id
}

並使用它

id = MagicCard.generateRandomID()

(在我寫這篇文章時也寫在另一個答案中)。

您也可以刪除該方法並使用“立即評估的閉包”:

id = { () -> String in
    // ...
    return id
}()

但是如果id屬性的意圖是使對象Equatable那么根本不需要它 類是引用類型,實例可以與“相同”運算符進行比較:

func == (lhs: MagicCard, rhs: MagicCard) -> Bool {
    return lhs === rhs
}

這使得idgenerateRandomID()方法過時了。

調用成員函數generateRandomID包括隱式self. ,所以在對象完全初始化之前你無法做到這一點。 一個簡單的解決方案是首先為id分配一個臨時值:

id = ""
id = generateRandomID() // NOT THE SUGGESTED SOLUTION, see below.

但要做到這一點,你必須將它改為var ,然后需要更多的努力來隱藏公眾的設置者。

但是, generateRandomID()沒有任何內容取決於對象的狀態,因此它也可能是一個static類函數,然后您將其稱為MagicCard.generateRandomID() 但是為了更進一步,從概念上講,隨機id的生成與Magic卡沒有任何關系,所以你甚至可以將它作為一個全局函數或將它隔離到它自己的類......

...一旦我們NSUUID那么遠,為什么不使用現有的NSUUID類型來表示你的身份? id的類型更改為NSUUID並使用id = NSUUID()為隨機UUID初始化它,或者將其保留為String並指定為id = NSUUID().UUIDString UUID已經解決了唯一ID的問題,因此您不必提出自己的生成器。 =)

這導致我們:

let id: NSUUID = NSUUID()

要么

let id: String = NSUUID().UUIDString

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM