Multiple value-binding patterns in a single switch case


(Glen Huang) #1

Hi, I wonder what's the correct way to express something like this in swift:

Say I have a superclass with two subclasses:

class Animal {}
class Dog: Animal {
    let name = "Dog"
}
class Cat: Animal {
    var name: String {
        return "Cat"
    }
}

And I want to display the name with a switch:

switch animal {
case let a as Dog, let a as Cat:
    label.text = a.name
default:
    break
}

Swift currently won't allow me to use multiple value-binding patterns like this. I wonder what's the right way to express it? Must I repeat the statements?

switch animal {
case let a as Dog:
    label.text = a.name
case let a as Cat:
    label.text = a.name
default:
    break
}

I also tried fallthrough, but swift won't let me fall through to a value-binding pattern:

switch animal {
case let a as Dog:
    fallthrough // error
case let a as Cat:
    label.text = a.name
default:
    break
}

I'm at my wits end. Could someone shed some light on this? Thanks.


(Jens Persson) #2

I'm not sure what you are trying to achieve.
Why can't you just do:
label.text = animal.nam
?
Is it because not all Animals have names?
If so, you could perhaps use something like this:

class Animal {}
protocol Named {
    var name: String { get }
}
class Dog: Animal, Named {
    let name = "Dog"
}
class Cat: Animal, Named {
    var name: String {
        return "Cat"
    }
}

let animals: [Animal] = [Cat(), Dog()]

for animal in animals {
    if let namedAnimal = animal as? Named {
        print(namedAnimal.name)
    }
}

···

On Fri, Jun 9, 2017 at 12:34 PM, Glen Huang via swift-users < swift-users@swift.org> wrote:

Hi, I wonder what's the correct way to express something like this in
swift:

Say I have a superclass with two subclasses:

class Animal {}
class Dog: Animal {
    let name = "Dog"
}
class Cat: Animal {
    var name: String {
        return "Cat"
    }
}

And I want to display the name with a switch:

switch animal {
case let a as Dog, let a as Cat:
    label.text = a.name
default:
    break
}

Swift currently won't allow me to use multiple value-binding patterns like
this. I wonder what's the right way to express it? Must I repeat the
statements?

switch animal {
case let a as Dog:
    label.text = a.name
case let a as Cat:
    label.text = a.name
default:
    break
}

I also tried fallthrough, but swift won't let me fall through to a
value-binding pattern:

switch animal {
case let a as Dog:
    fallthrough // error
case let a as Cat:
    label.text = a.name
default:
    break
}

I'm at my wits end. Could someone shed some light on this? Thanks.
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Glen Huang) #3

Yes, not all animals have names.

Defining a protocol sounds reasonable.

In my case, the Animal, Dog and Cat are all subclasses of Core Data's NSManagedObject, having to define a protocol and make them conform to that is a bit involved.

But I think that seems to be the only sensible way.

Thanks.

···

On 9 Jun 2017, at 7:28 PM, Jens Persson <jens@bitcycle.com> wrote:

I'm not sure what you are trying to achieve.
Why can't you just do:
label.text = animal.nam
?
Is it because not all Animals have names?
If so, you could perhaps use something like this:

class Animal {}
protocol Named {
    var name: String { get }
}
class Dog: Animal, Named {
    let name = "Dog"
}
class Cat: Animal, Named {
    var name: String {
        return "Cat"
    }
}

let animals: [Animal] = [Cat(), Dog()]

for animal in animals {
    if let namedAnimal = animal as? Named {
        print(namedAnimal.name)
    }
}

On Fri, Jun 9, 2017 at 12:34 PM, Glen Huang via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi, I wonder what's the correct way to express something like this in swift:

Say I have a superclass with two subclasses:

class Animal {}
class Dog: Animal {
    let name = "Dog"
}
class Cat: Animal {
    var name: String {
        return "Cat"
    }
}

And I want to display the name with a switch:

switch animal {
case let a as Dog, let a as Cat:
    label.text = a.name <http://a.name/>
default:
    break
}

Swift currently won't allow me to use multiple value-binding patterns like this. I wonder what's the right way to express it? Must I repeat the statements?

switch animal {
case let a as Dog:
    label.text = a.name <http://a.name/>
case let a as Cat:
    label.text = a.name <http://a.name/>
default:
    break
}

I also tried fallthrough, but swift won't let me fall through to a value-binding pattern:

switch animal {
case let a as Dog:
    fallthrough // error
case let a as Cat:
    label.text = a.name <http://a.name/>
default:
    break
}

I'm at my wits end. Could someone shed some light on this? Thanks.
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users