Swift 2.0:在初始化存储属性之前在方法调用中使用self

时间:2015-08-02 11:16:46

标签: swift swift2 swift-playground

本周末刚刚开始关注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
}

3 个答案:

答案 0 :(得分:9)

我可以建议的一个热门修补就是让generateRandomID成为一个类功能。所以就这样:

private class func generateRandomID() -> String {

并且这样打电话:

id = MagicCard.generateRandomID()

答案 1 :(得分:8)

generateRandomID()方法不使用或修改任何属性 实例,所以一个可能的解决方案是使它成为一个 type(class)方法:

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()方法过时。

答案 2 :(得分:3)

调用成员函数generateRandomID包含一个隐式self.,所以在对象完全初始化之前你无法做到这一点。一个简单的解决方案是首先为id分配一个临时值:

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

但要做到这一点,你必须将其改为var,然后需要付出更多努力才能将公众隐藏起来。

但是,generateRandomID()中的任何内容都不取决于对象的状态,因此它也可能是static类函数,您可以将其称为MagicCard.generateRandomID()。但是为了更进一步,从概念上讲,随机id的生成与Magic卡没有任何关系,所以你甚至可以使它成为一个全局函数或者将它分离为一个自己的类......

...一旦我们达到目标,为什么不使用现有的NSUUID类型来表示您的身份?将id的类型更改为NSUUID,并使用id = NSUUID()将其初始化为随机UUID,或将其保留为String并指定为id = NSUUID().UUIDString。 UUID已经解决了唯一ID的问题,因此您不必提出自己的生成器。 =)

这导致我们:

let id: NSUUID = NSUUID()

let id: String = NSUUID().UUIDString