[swift-evolution] [Proposal] Type Narrowing
Jay Abbott
jay at abbott.me.uk
Thu Nov 10 15:42:56 CST 2016
Consider this code:
struct Pet {
let name: String
weak var owner: Person?
init(name: String, owner: Person?) {
self.name = name
self.owner = owner
owner?.pet = self
}
mutating func transferOwnership(to newOwner: Person) {
let previousOwner = owner
owner = newOwner
newOwner.pet = self
if(previousOwner != nil) {
previousOwner!.pet = nil
}
}
func feed() {
}
}
class Person {
let name: String
var pet: Pet?
init(name: String) {
self.name = name
}
func givePetAway(to someone: Person) {
if pet != nil {
pet!.transferOwnership(to: someone)
//pet!.feed()
}
}
}
let bert = Person(name: "Bert")let ernie = Person(name: "Ernie")var
elmo = Pet(name: "Elmo", owner: nil)
elmo.transferOwnership(to: bert)print("Bert's pet is \(bert.pet) -
Ernie's pet is \(ernie.pet)")
bert.givePetAway(to: ernie)print("Bert's pet is \(bert.pet) - Ernie's
pet is \(ernie.pet)")
This works as expected, but if you uncomment pet!.feed() in givePetAway(to:)
it will crash, because the mutating function modifies the two-way
relationship between pet and owner.
In the code I use if pet != nil to demonstrate, in your proposal for unwrap,
if I used it to unwrap pet (a value-type, but accessed through self so it
can be modified after unwrapping because it’s not nil at the moment) the
compiler would assume I could use it and pet.feed() would crash, just as
pet!.feed() does now. In your proposal for type narrowing, it would be the
same problem. This is like your foo.value example from the proposal.
I don’t think you can get around the fact that the compiler can’t guarantee
a type-narrowed or even unwrapped mutable value, which is why if let works
as it does with an immutable snapshot.
However, type narrowing for immutable values would still be good.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161110/b768721a/attachment.html>
More information about the swift-evolution
mailing list