Pim
Pim

Reputation: 2128

Swift: Downcast to known type

I was just wondering…

let movie = item as? Movie

In this example item is either of type Movie or something else. In case of the latter movie will be assigned a nil value. Thus movie will be of type Movie?.

Now check out the next example:

let movie: Movie?

movie = item as? Movie

Let's say movie is a class variable which I'm assigning some value inside one of my class methods.

To me it feels like as? Movie is somewhat redundant, since movie is already known to be of type Movie?.

Is there any kind of syntax in Swift that says: "Downcast this object to the same type as the object to which I'm assigning it to. Assign nil if this is an optional type and the downcast fails."?

I was hoping for something like:

movie = item as?

or

movie =? movie

Upvotes: 12

Views: 576

Answers (3)

Mick MacCallum
Mick MacCallum

Reputation: 130222

The existing answers correctly state that there is no built in functionality for this. But just to build on what's already been written here, it is possible to define an infix operator =? which implements the behavior you described in your question. For example:

infix operator =? {
    associativity none
    precedence 130
}

func =? <T>(inout lhs: T?, rhs: Any?) {
    lhs = rhs as? T
}

var movie: Movie?
let item: Any? = Movie(name: "some movie")

movie =? item
movie?.name // "some movie"

Upvotes: 3

rintaro
rintaro

Reputation: 51911

Is there any kind of syntax in Swift ...

NO.

You have to implement by yourself

func conditionalCast<T, U>(val: T?) -> U? {
    return val as? U
}

// Usage:

class Movie {}
class Image {}    
let item:AnyObject = arc4random_uniform(2) == 0 ? Movie() : Image()

let movie: Movie?
movie = conditionalCast(item)

You can make it as a custom unary operator ( postfix /? for exmaple):

postfix operator /? {}
postfix func /?<T, U>(val: T?) -> U? {
    return val as? U
}

let movie: Movie?
movie = item/?

Upvotes: 1

Related Questions