Swift - 在struct中更改变量?

时间:2016-03-02 15:19:42

标签: swift swift2

我是Swift和静态编程的初学者。通过Big Nerd Ranch Swift书。我不明白为什么myTown人口正在改变,但不是fredTheZombie.town?这项运动要求城镇人口永远不会低于零。当人口少于10时,可能会发生这种情况。如何更改fredTheZombie.town人口变量?

struct Town {
    var population = 5422
    var numberOfStoplights = 4

    func printTownDescription() {
        print("Population: \(myTown.population), number of stoplights: \(myTown.numberOfStoplights)")
    }

    mutating func changePopulation(amount: Int) {
        population += amount
    }
}

class Monster {
    var town: Town?
    var name = "Monster"

    func terrorizeTown() {
        if town != nil {
            print("\(name) is terrorizing a town!")
        } else {
            print("\(name) hasn't found a town to terrorize yet...")
        }
    }
}

class Zombie: Monster {
    var walksWithLimp = true

    final override func terrorizeTown() {
        guard town?.population > 0 else {
            return
        }

        if town?.population > 10 {
            super.town!.changePopulation(-10)
        } else {
            super.town!.population = 0
        }

        super.terrorizeTown()
    }

    func changeName(name: String, walksWithLimp: Bool) {
        self.name = name
        self.walksWithLimp = walksWithLimp
    }
}

var myTown = Town()
myTown.changePopulation(500)
let fredTheZombie = Zombie()
fredTheZombie.town = myTown
fredTheZombie.terrorizeTown()
fredTheZombie.town?.printTownDescription()
fredTheZombie.changeName("Fred the Zombie", walksWithLimp: false)

myTown.changePopulation(-5915)
print(myTown.population)
print(fredTheZombie.town!.population)
fredTheZombie.terrorizeTown()
fredTheZombie.terrorizeTown()
fredTheZombie.town?.printTownDescription()

输出:

Monster is terrorizing a town!
Population: 5922, number of stoplights: 4
7
5912
Fred the Zombie is terrorizing a town!
Fred the Zombie is terrorizing a town!
Population: 7, number of stoplights: 4
Program ended with exit code: 0

1 个答案:

答案 0 :(得分:2)

Town是一个结构,一个值类型。将值类型分配给其他变量(例如fredTheZombie.town = myTown)时,将复制该值类型(意味着创建的新Town具有与原始Town相同的值。)< / p>

myTownfredTheZombie.town不再是同一个城镇。如果您希望它们是同一个实例,请将它们设为class(引用类型)。

查看有关Apple Swift BlogSwift Language Guide的更多信息。

我们遇到的最大问题是可选结构。展开可选结构(使用town!)的结果又是一个副本,一个新城镇。要解决这个问题,你必须:

var myTown = super.town!
myTown.changePopulation(-10)
super.town = myTown // assign back

整个例子:

struct Town {
    var population = 5422
    var numberOfStoplights = 4

    func printTownDescription() {
        // note you have to print "self" here, not "myTown"
        print("Population: \(self.population), number of stoplights: \(self.numberOfStoplights)")
    }

    mutating func changePopulation(amount: Int) {
        population += amount
    }
}

class Monster {
    var town: Town?
    var name = "Monster"

    func terrorizeTown() {
        if town != nil {
            print("\(name) is terrorizing a town!")
        } else {
            print("\(name) hasn't found a town to terrorize yet...")
        }
    }
}

class Zombie: Monster {
    var walksWithLimp = true

    final override func terrorizeTown() {
        guard super.town?.population > 0 else {
            return
        }

        var town = super.town!

        if town.population > 10 {
            town.changePopulation(-10)
        } else {
            town.population = 0
        }

        super.town = town

        super.terrorizeTown()
    }

    func changeName(name: String, walksWithLimp: Bool) {
        self.name = name
        self.walksWithLimp = walksWithLimp
    }
}

在您的情况下,town实际上不需要选项。您可以在构造函数中将其传递给Monster