简体   繁体   English

快速的非零值可选链

[英]Swift optional chaining with non-nil value

I have the following program which works fine - 我有以下运行良好的程序-

class Person {
    var pet: Pet?
}

class Pet {
    var name: String

    var favoriteToy: Toy?

    init(name: String) {
        self.name = name
    }
}

class Toy {
    var name: String

    init(name: String) {
        self.name = name
    }
}

let q = Person()
// Pet(name:"goofy")
// Toy(name:"teddy")

if let someToy = q.pet?.favoriteToy?.name {
    print("This person's pet likes \(someToy).")
} else {
    print("This person's pet does not have a favorite toy")
}

Prints: 印刷品:

This person's pet does not have a favorite toy 此人的宠物没有喜欢的玩具

How to use the above code modified to print "This person's pet likes teddy."? 如何使用上面修改过的代码打印“此人的宠物喜欢泰迪熊”?

I know I will have not be able to use if let as there will be nothing to unwrap. 我知道if let我将无法使用if let因为将没有任何东西可以打开。 So I have to write something like this instead of if let : 所以我必须写这样的东西,而不是if let

let someToy = q.pet.favoriteToy.name
print("This person's pet likes \(someToy).")

Should print "This person's pet likes the teddy." 应打印“此人的宠物喜欢泰迪熊”。

I also know I have to put non-nil value something like this: 我也知道我必须将非零值放在这样的地方:

class Person {
    var pet = Pet ()
}

Still I am having initialization problems. 我仍然有初始化问题。 How to go about it? 怎么做呢?

This should solve your immediate needs... 这应该可以解决您的即时需求...

let man = Person()
let goofy = Pet(name: "goofy")
let squeaky = Toy(name: "squeaky toy")

goofy.favoriteToy = squeaky
man.pet = goofy

But if a person is usually going to be initialized with a pet and a toy, and both of those classes are initialized with a string, then you might want to define a convenience initializer: 但是,如果通常一个人要用宠物和玩具初始化,而这两个类都用字符串初始化,那么您可能想定义一个便捷的初始化器:

class Pet {
  var name: String
  var favoriteToy: Toy?
  init(name: String) {
    self.name = name
  }
}

class Toy {
  var name: String
  init(name: String) {
    self.name = name
  }
}

class Person {
  var pet: Pet?
  convenience init(petName: String, toyName: String) {
    self.init()
    let toy = Toy(name: toyName)
    let pet = Pet(name: petName)
    pet.favoriteToy = toy
    self.pet = pet
  }
}

func test() {
  let bill = Person(petName: "goofy", toyName: "squeaky ball")
  guard let toyName = bill.pet?.favoriteToy?.name else { return }
  print(toyName)
}

test()

One more thing: optional chaining can be combined with a guard statement to great effect in Swift. 还有一件事: 可选的链接可以与保护声明结合使用,从而在Swift中产生很大的效果。

Use ? = nil 使用? = nil ? = nil in your initializer to pass in some optional parameters. ? = nil在您的初始值设定项中传递一些可选参数。

class Person {
    var pet: Pet?

    init(pet: Pet? = nil) {
        self.pet = pet
    }
}

class Pet {
    var name: String

    var favoriteToy: Toy?

    init(name: String, toy: Toy? = nil) {
        self.name = name
        self.favoriteToy = toy
    }
}

class Toy {
    var name: String

    init(name: String) {
        self.name = name
    }
}

let q = Person(pet: Pet(name: "goofy", toy: Toy(name: "teddy")))
// Pet(name:"goofy")
// Toy(name:"teddy")

if let someToy = q.pet?.favoriteToy?.name {
    print("This person's pet likes \(someToy).")
} else {
    print("This person's pet does not have a favorite toy")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM