Switch based on let


(Nate Birkholz) #1

This looks like it doesn't work (swift 2.x), but wanted to be sure it's not
supported:

class Superclass {}
class Subclass1 : Superclass {}
class Subclass2 : Superclass {}
class Subclass3 : Superclass {}

let sc1 = Subclass1()
let sc2 = Subclass2()
let sc3 = Subclass3()

let objects : [Superclass] = [sc1, sc2, sc3]

for subclassObject in objects {
    switch subclassObject {
    case let object = subclassObject as? Subclass1:
        doSomethingWith(object)
    case let object = subclassObject as? Subclass2:
        doSomethingWith(object)
    case let object = subclassObject as? Subclass3:
        doSomethingWith(object)
    default:
        return
    }
}
This gives an error, expecting a colon (:slight_smile: after object on every case.

I wanted to be sure I wasn't missing something in my syntax (nor some
obvious-to-others reason this isn't supported) before going to swift
evolution.

···

--
Nate Birkholz


(Dan Loewenherz) #2

To my knowledge, you can’t do exactly what you’re trying to do, but this is
close:

for subclassObject in objects {

    switch subclassObject.self {

    case is Subclass1:

        doSomethingWith(subclassObject as! Subclass1)

    case is Subclass2:

        doSomethingWith(subclassObject as! Subclass2)

    case is Subclass3:

        doSomethingWith(subclassObject as! Subclass3)

    default:

        break

    }

}

···

On Fri, Jul 8, 2016 at 10:11 AM, Nate Birkholz via swift-users < swift-users@swift.org> wrote:

This looks like it doesn't work (swift 2.x), but wanted to be sure it's
not supported:

class Superclass {}
class Subclass1 : Superclass {}
class Subclass2 : Superclass {}
class Subclass3 : Superclass {}

let sc1 = Subclass1()
let sc2 = Subclass2()
let sc3 = Subclass3()

let objects : [Superclass] = [sc1, sc2, sc3]

for subclassObject in objects {
    switch subclassObject {
    case let object = subclassObject as? Subclass1:
        doSomethingWith(object)
    case let object = subclassObject as? Subclass2:
        doSomethingWith(object)
    case let object = subclassObject as? Subclass3:
        doSomethingWith(object)
    default:
        return
    }
}
This gives an error, expecting a colon (:slight_smile: after object on every case.

I wanted to be sure I wasn't missing something in my syntax (nor some
obvious-to-others reason this isn't supported) before going to swift
evolution.

--
Nate Birkholz

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Roth Michaels) #3

This gives an error, expecting a colon (:slight_smile: after object on every case.

I wanted to be sure I wasn't missing something in my syntax (nor some
obvious-to-others reason this isn't supported) before going to swift
evolution.

There is a bug filed to improve this error message:
https://bugs.swift.org/browse/SR-2022

To my knowledge, you can’t do exactly what you’re trying to do

Here is how:


for object in objects {
    switch object {
    case let object as Subclass1:
        doSomethingWith(object)
    case let object as Subclass2:
        doSomethingWith(object)
    case let object as Subclass3:
        doSomethingWith(object)
    default:
        break
    }
}

···

On Fri, Jul 08 2016 at 11:11:04 AM, Nate Birkholz via swift-users <swift-users@swift.org> wrote:
On Fri, Jul 08 2016 at 11:15:48 AM, Dan Loewenherz via swift-users <swift-users@swift.org> wrote:

--
Roth Michaels
roth@rothmichaels.us


(Nate Birkholz) #4

Thanks, I never seem to know when to use .self.

···

On Fri, Jul 8, 2016 at 8:15 AM, Dan Loewenherz <dan@lionheartsw.com> wrote:

To my knowledge, you can’t do exactly what you’re trying to do, but this
is close:

for subclassObject in objects {

    switch subclassObject.self {

    case is Subclass1:

        doSomethingWith(subclassObject as! Subclass1)

    case is Subclass2:

        doSomethingWith(subclassObject as! Subclass2)

    case is Subclass3:

        doSomethingWith(subclassObject as! Subclass3)

    default:

        break

    }

}

On Fri, Jul 8, 2016 at 10:11 AM, Nate Birkholz via swift-users < > swift-users@swift.org> wrote:

This looks like it doesn't work (swift 2.x), but wanted to be sure it's
not supported:

class Superclass {}
class Subclass1 : Superclass {}
class Subclass2 : Superclass {}
class Subclass3 : Superclass {}

let sc1 = Subclass1()
let sc2 = Subclass2()
let sc3 = Subclass3()

let objects : [Superclass] = [sc1, sc2, sc3]

for subclassObject in objects {
    switch subclassObject {
    case let object = subclassObject as? Subclass1:
        doSomethingWith(object)
    case let object = subclassObject as? Subclass2:
        doSomethingWith(object)
    case let object = subclassObject as? Subclass3:
        doSomethingWith(object)
    default:
        return
    }
}
This gives an error, expecting a colon (:slight_smile: after object on every case.

I wanted to be sure I wasn't missing something in my syntax (nor some
obvious-to-others reason this isn't supported) before going to swift
evolution.

--
Nate Birkholz

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

--
Nate Birkholz


(Rick M) #5

I just saw a question which brought up something I didn't know about. Apparently sometimes you have to call object.self in a place that looks like you should just use "object." What does this usage mean?

for subclassObject in objects {
    switch subclassObject.self { <--- Here, why not "subclassObject" alone?
    case is Subclass1:
        doSomethingWith(subclassObject as! Subclass1)

    case is Subclass2:
        doSomethingWith(subclassObject as! Subclass2)

    case is Subclass3:
        doSomethingWith(subclassObject as! Subclass3)

    default:
        break
    }
}

Thanks,
Rick

···

On Jul 8, 2016, at 08:15 , Dan Loewenherz via swift-users <swift-users@swift.org> wrote:

To my knowledge, you can’t do exactly what you’re trying to do, but this is close:

for subclassObject in objects {
    switch subclassObject.self {
    case is Subclass1:
        doSomethingWith(subclassObject as! Subclass1)

    case is Subclass2:
        doSomethingWith(subclassObject as! Subclass2)

    case is Subclass3:
        doSomethingWith(subclassObject as! Subclass3)

    default:
        break
    }
}

On Fri, Jul 8, 2016 at 10:11 AM, Nate Birkholz via swift-users <swift-users@swift.org> wrote:
This looks like it doesn't work (swift 2.x), but wanted to be sure it's not supported:
class Superclass {}
class Subclass1 : Superclass {}
class Subclass2 : Superclass {}
class Subclass3 : Superclass {}

let sc1 = Subclass1()
let sc2 = Subclass2()
let sc3 = Subclass3()

let objects : [Superclass] = [sc1, sc2, sc3]

for subclassObject in objects {
    switch subclassObject {
    case let object = subclassObject as? Subclass1:
        doSomethingWith(object)
    case let object = subclassObject as? Subclass2:
        doSomethingWith(object)
    case let object = subclassObject as? Subclass3:
        doSomethingWith(object)
    default:
        return
    }
}

This gives an error, expecting a colon (:slight_smile: after object on every case.

I wanted to be sure I wasn't missing something in my syntax (nor some obvious-to-others reason this isn't supported) before going to swift evolution.

--
Nate Birkholz

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

--
Rick Mann
rmann@latencyzero.com


(Austin Zheng) #6

Hi Rick,

If you have a type (let's call it "T"), you can use it two ways:

* As a type, or part of a type, like such: "let x : T = blah()"
* As a value, just like any other variable, function argument, property,
etc.

In the second case (type-as-value), you need to append ".self" to the type
name according to the grammar:

"let x : Any.Type = T.self"

There was a "bug" in Swift 2.x where you could sometimes use just "T",
without the ".self", in certain cases (in particular, when you were passing
in a type-as-value to a function with one unlabeled argument). That bug has
since been fixed.

As for types-as-values: Swift allows you to treat a type as a normal value,
which means you can do whatever you want with it: pass it to functions and
return it from functions, store it in properties or variables, etc. If you
have one of these types-as-values (called 'metatypes'), you can do certain
things like call static methods or initializers on them, use them to
parameterize generic functions, etc.

However, to get back to your original question, the `.self` in that switch
statement actually isn't necessary and you should really just be switching
on the value of subclassObject itself, not the value of its type.

Best,
Austin

···

On Fri, Jul 8, 2016 at 9:38 AM, Rick Mann via swift-users < swift-users@swift.org> wrote:

I just saw a question which brought up something I didn't know about.
Apparently sometimes you have to call object.self in a place that looks
like you should just use "object." What does this usage mean?

for subclassObject in objects {
    switch subclassObject.self { <--- Here, why not
"subclassObject" alone?
    case is Subclass1:
        doSomethingWith(subclassObject as! Subclass1)

    case is Subclass2:
        doSomethingWith(subclassObject as! Subclass2)

    case is Subclass3:
        doSomethingWith(subclassObject as! Subclass3)

    default:
        break
    }
}

Thanks,
Rick

> On Jul 8, 2016, at 08:15 , Dan Loewenherz via swift-users < > swift-users@swift.org> wrote:
>
> To my knowledge, you can’t do exactly what you’re trying to do, but this
is close:
>
> for subclassObject in objects {
> switch subclassObject.self {
> case is Subclass1:
> doSomethingWith(subclassObject as! Subclass1)
>
> case is Subclass2:
> doSomethingWith(subclassObject as! Subclass2)
>
> case is Subclass3:
> doSomethingWith(subclassObject as! Subclass3)
>
> default:
> break
> }
> }
>
> On Fri, Jul 8, 2016 at 10:11 AM, Nate Birkholz via swift-users < > swift-users@swift.org> wrote:
> This looks like it doesn't work (swift 2.x), but wanted to be sure it's
not supported:
> class Superclass {}
> class Subclass1 : Superclass {}
> class Subclass2 : Superclass {}
> class Subclass3 : Superclass {}
>
> let sc1 = Subclass1()
> let sc2 = Subclass2()
> let sc3 = Subclass3()
>
> let objects : [Superclass] = [sc1, sc2, sc3]
>
> for subclassObject in objects {
> switch subclassObject {
> case let object = subclassObject as? Subclass1:
> doSomethingWith(object)
> case let object = subclassObject as? Subclass2:
> doSomethingWith(object)
> case let object = subclassObject as? Subclass3:
> doSomethingWith(object)
> default:
> return
> }
> }
>
> This gives an error, expecting a colon (:slight_smile: after object on every case.
>
> I wanted to be sure I wasn't missing something in my syntax (nor some
obvious-to-others reason this isn't supported) before going to swift
evolution.
>
>
> --
> Nate Birkholz
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Dan Loewenherz) #7

Beautiful, thanks Roth! This is much nicer. :slight_smile:

Dan

···

On Fri, Jul 8, 2016 at 10:34 AM, Roth Michaels via swift-users < swift-users@swift.org> wrote:

On Fri, Jul 08 2016 at 11:11:04 AM, Nate Birkholz via swift-users < > swift-users@swift.org> wrote:
> This gives an error, expecting a colon (:slight_smile: after object on every case.
>
> I wanted to be sure I wasn't missing something in my syntax (nor some
> obvious-to-others reason this isn't supported) before going to swift
> evolution.

There is a bug filed to improve this error message:
https://bugs.swift.org/browse/SR-2022

On Fri, Jul 08 2016 at 11:15:48 AM, Dan Loewenherz via swift-users < > swift-users@swift.org> wrote:
> To my knowledge, you can’t do exactly what you’re trying to do

Here is how:

```Swift

for object in objects {
    switch object {
    case let object as Subclass1:
        doSomethingWith(object)
    case let object as Subclass2:
        doSomethingWith(object)
    case let object as Subclass3:
        doSomethingWith(object)
    default:
        break
    }
}


(Nate Birkholz) #8

Much obliged!! This syntax is clean and makes sense once I see it.

···

Sent from my iPhone, please excuse brevity and errors

On Jul 8, 2016, at 8:49 AM, Dan Loewenherz via swift-users <swift-users@swift.org> wrote:

On Fri, Jul 8, 2016 at 10:34 AM, Roth Michaels via swift-users <swift-users@swift.org> wrote:
On Fri, Jul 08 2016 at 11:11:04 AM, Nate Birkholz via swift-users <swift-users@swift.org> wrote:
> This gives an error, expecting a colon (:slight_smile: after object on every case.
>
> I wanted to be sure I wasn't missing something in my syntax (nor some
> obvious-to-others reason this isn't supported) before going to swift
> evolution.

There is a bug filed to improve this error message:
https://bugs.swift.org/browse/SR-2022

On Fri, Jul 08 2016 at 11:15:48 AM, Dan Loewenherz via swift-users <swift-users@swift.org> wrote:
> To my knowledge, you can’t do exactly what you’re trying to do

Here is how:

```Swift

for object in objects {
    switch object {
    case let object as Subclass1:
        doSomethingWith(object)
    case let object as Subclass2:
        doSomethingWith(object)
    case let object as Subclass3:
        doSomethingWith(object)
    default:
        break
    }
}

Beautiful, thanks Roth! This is much nicer. :slight_smile:

Dan
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Rick M) #9

Hi Rick,

If you have a type (let's call it "T"), you can use it two ways:

* As a type, or part of a type, like such: "let x : T = blah()"
* As a value, just like any other variable, function argument, property, etc.

In the second case (type-as-value), you need to append ".self" to the type name according to the grammar:

"let x : Any.Type = T.self"

There was a "bug" in Swift 2.x where you could sometimes use just "T", without the ".self", in certain cases (in particular, when you were passing in a type-as-value to a function with one unlabeled argument). That bug has since been fixed.

As for types-as-values: Swift allows you to treat a type as a normal value, which means you can do whatever you want with it: pass it to functions and return it from functions, store it in properties or variables, etc. If you have one of these types-as-values (called 'metatypes'), you can do certain things like call static methods or initializers on them, use them to parameterize generic functions, etc.

Thanks, Austin. I'm familiar with all this in Swift. What threw me was that "subclassObject" was an instance, not a class.

However, to get back to your original question, the `.self` in that switch statement actually isn't necessary and you should really just be switching on the value of subclassObject itself, not the value of its type.

I would have thought so, but the response to this answer was something along the lines of "I never know when to use the object or its self."

To me, for an instance, foo an foo.self should be equivalent in all respects (shouldn't it?).

···

On Jul 8, 2016, at 09:45 , Austin Zheng <austinzheng@gmail.com> wrote:

Best,
Austin

On Fri, Jul 8, 2016 at 9:38 AM, Rick Mann via swift-users <swift-users@swift.org> wrote:
I just saw a question which brought up something I didn't know about. Apparently sometimes you have to call object.self in a place that looks like you should just use "object." What does this usage mean?

for subclassObject in objects {
    switch subclassObject.self { <--- Here, why not "subclassObject" alone?
    case is Subclass1:
        doSomethingWith(subclassObject as! Subclass1)

    case is Subclass2:
        doSomethingWith(subclassObject as! Subclass2)

    case is Subclass3:
        doSomethingWith(subclassObject as! Subclass3)

    default:
        break
    }
}

Thanks,
Rick

> On Jul 8, 2016, at 08:15 , Dan Loewenherz via swift-users <swift-users@swift.org> wrote:
>
> To my knowledge, you can’t do exactly what you’re trying to do, but this is close:
>
> for subclassObject in objects {
> switch subclassObject.self {
> case is Subclass1:
> doSomethingWith(subclassObject as! Subclass1)
>
> case is Subclass2:
> doSomethingWith(subclassObject as! Subclass2)
>
> case is Subclass3:
> doSomethingWith(subclassObject as! Subclass3)
>
> default:
> break
> }
> }
>
> On Fri, Jul 8, 2016 at 10:11 AM, Nate Birkholz via swift-users <swift-users@swift.org> wrote:
> This looks like it doesn't work (swift 2.x), but wanted to be sure it's not supported:
> class Superclass {}
> class Subclass1 : Superclass {}
> class Subclass2 : Superclass {}
> class Subclass3 : Superclass {}
>
> let sc1 = Subclass1()
> let sc2 = Subclass2()
> let sc3 = Subclass3()
>
> let objects : [Superclass] = [sc1, sc2, sc3]
>
> for subclassObject in objects {
> switch subclassObject {
> case let object = subclassObject as? Subclass1:
> doSomethingWith(object)
> case let object = subclassObject as? Subclass2:
> doSomethingWith(object)
> case let object = subclassObject as? Subclass3:
> doSomethingWith(object)
> default:
> return
> }
> }
>
> This gives an error, expecting a colon (:slight_smile: after object on every case.
>
> I wanted to be sure I wasn't missing something in my syntax (nor some obvious-to-others reason this isn't supported) before going to swift evolution.
>
>
> --
> Nate Birkholz
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

--
Rick Mann
rmann@latencyzero.com


(Austin Zheng) #10

Yes, as far as I know 'foo' and 'foo.self' are equivalent. I don't actually
know why the latter exists, except in analogy to "T.self".

There was a mistake in my response; the metatype of 'foo' is not
'foo.self', it is 'foo.dynamicType' (or whatever new form dynamicType is
going to take in Swift 3).

···

On Sat, Jul 9, 2016 at 2:27 PM, Rick Mann <rmann@latencyzero.com> wrote:

> On Jul 8, 2016, at 09:45 , Austin Zheng <austinzheng@gmail.com> wrote:
>
> Hi Rick,
>
> If you have a type (let's call it "T"), you can use it two ways:
>
> * As a type, or part of a type, like such: "let x : T = blah()"
> * As a value, just like any other variable, function argument, property,
etc.
>
> In the second case (type-as-value), you need to append ".self" to the
type name according to the grammar:
>
> "let x : Any.Type = T.self"
>
> There was a "bug" in Swift 2.x where you could sometimes use just "T",
without the ".self", in certain cases (in particular, when you were passing
in a type-as-value to a function with one unlabeled argument). That bug has
since been fixed.
>
> As for types-as-values: Swift allows you to treat a type as a normal
value, which means you can do whatever you want with it: pass it to
functions and return it from functions, store it in properties or
variables, etc. If you have one of these types-as-values (called
'metatypes'), you can do certain things like call static methods or
initializers on them, use them to parameterize generic functions, etc.

Thanks, Austin. I'm familiar with all this in Swift. What threw me was
that "subclassObject" was an instance, not a class.

> However, to get back to your original question, the `.self` in that
switch statement actually isn't necessary and you should really just be
switching on the value of subclassObject itself, not the value of its type.

I would have thought so, but the response to this answer was something
along the lines of "I never know when to use the object or its self."

To me, for an instance, foo an foo.self should be equivalent in all
respects (shouldn't it?).

>
> Best,
> Austin
>
>
> On Fri, Jul 8, 2016 at 9:38 AM, Rick Mann via swift-users < > swift-users@swift.org> wrote:
> I just saw a question which brought up something I didn't know about.
Apparently sometimes you have to call object.self in a place that looks
like you should just use "object." What does this usage mean?
>
> for subclassObject in objects {
> switch subclassObject.self { <--- Here, why not
"subclassObject" alone?
> case is Subclass1:
> doSomethingWith(subclassObject as! Subclass1)
>
> case is Subclass2:
> doSomethingWith(subclassObject as! Subclass2)
>
> case is Subclass3:
> doSomethingWith(subclassObject as! Subclass3)
>
> default:
> break
> }
> }
>
> Thanks,
> Rick
>
> > On Jul 8, 2016, at 08:15 , Dan Loewenherz via swift-users < > swift-users@swift.org> wrote:
> >
> > To my knowledge, you can’t do exactly what you’re trying to do, but
this is close:
> >
> > for subclassObject in objects {
> > switch subclassObject.self {
> > case is Subclass1:
> > doSomethingWith(subclassObject as! Subclass1)
> >
> > case is Subclass2:
> > doSomethingWith(subclassObject as! Subclass2)
> >
> > case is Subclass3:
> > doSomethingWith(subclassObject as! Subclass3)
> >
> > default:
> > break
> > }
> > }
> >
> > On Fri, Jul 8, 2016 at 10:11 AM, Nate Birkholz via swift-users < > swift-users@swift.org> wrote:
> > This looks like it doesn't work (swift 2.x), but wanted to be sure
it's not supported:
> > class Superclass {}
> > class Subclass1 : Superclass {}
> > class Subclass2 : Superclass {}
> > class Subclass3 : Superclass {}
> >
> > let sc1 = Subclass1()
> > let sc2 = Subclass2()
> > let sc3 = Subclass3()
> >
> > let objects : [Superclass] = [sc1, sc2, sc3]
> >
> > for subclassObject in objects {
> > switch subclassObject {
> > case let object = subclassObject as? Subclass1:
> > doSomethingWith(object)
> > case let object = subclassObject as? Subclass2:
> > doSomethingWith(object)
> > case let object = subclassObject as? Subclass3:
> > doSomethingWith(object)
> > default:
> > return
> > }
> > }
> >
> > This gives an error, expecting a colon (:slight_smile: after object on every case.
> >
> > I wanted to be sure I wasn't missing something in my syntax (nor some
obvious-to-others reason this isn't supported) before going to swift
evolution.
> >
> >
> > --
> > Nate Birkholz
> >
> > _______________________________________________
> > swift-users mailing list
> > swift-users@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-users
> >
> >
> > _______________________________________________
> > swift-users mailing list
> > swift-users@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-users
>
>
> --
> Rick Mann
> rmann@latencyzero.com
>
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>

--
Rick Mann
rmann@latencyzero.com