2

当我运行下面的程序时,它会产生分段错误。你能帮我弄清楚为什么吗?谢谢

class Animal:NSObject{
    var  name:String!
    var age:UInt!

    weak var spouse:Animal?
    init(name:String,age:UInt){
        self.name=name
        self.age=age
    }

    func description() ->String{ //to become printable
        return "name= \(name) and age=\(age) spouse=\(spouse)"
    }
}


let dog=Animal(name:"Lucky",age:3)
let cat=Animal(name:"Branson",age:4)
dog.spouse=cat
cat.spouse=dog //It doesnt crash if I comment this line out
println(dog)
4

2 回答 2

4

问题是打印中的无限递归。一旦你设置了完整的循环,打印一个动物,你打印它的配偶,它打印它的配偶,它打印它的配偶等等,直到你用完堆栈空间并崩溃。

您需要通过打印出动物的配偶而不调用该动物的完整打印来打破这一点,如下所示:

class Animal: NSObject {
    // you should avoid using implicitly unwrapped optionals
    // unless you absolutely have to for a specific reason that
    // doesn’t appear to apply here (so remove the !s)
    var name: String
    var age: UInt
    weak var spouse: Animal?

    init(name: String, age: UInt) {
        self.name = name
        self.age = age
    }
}

// to make something printable, you need to conform
// to the Printable protocol
extension Animal: Printable {
    // And make description is a var rather than a function
    override var description: String {
        let spousal_status = spouse?.name ?? "None"
        return "name=\(name) and age=\(age), spouse=\(spousal_status)"
    }
}


let dog = Animal(name: "Lucky", age: 3)
let cat = Animal(name: "Branson", age: 4)
dog.spouse = cat
dog.description
cat.spouse = dog
println(dog)  // Prints name=Lucky and age=3, spouse=Branson

请注意,您必须Printable使用协议和 var 完全实现以避免此问题,否则您将获得默认实现,但仍会遇到此问题。

=顺便说一句,Swift 风格约定是在, ->, before等之间放置空格{(事实上,如果不这样做,有时会导致编译问题)。虽然我发现后者有点难以阅读,但陪审团仍然在a: b反对。a:b

于 2015-01-03T13:05:01.820 回答
0

您的代码触发堆栈溢出。该description方法包含描述,这将在一个永无止境的循环spouse中依次触发对其的描述,依此类推。spouse试试这个:

func description() -> String {
  return "name= \(name) and age=\(age) spouse=\(spouse?.name)"
}
于 2015-01-03T13:04:22.533 回答