2015-07-14 18 views
11

Właśnie się zastanawiałem ...Swift: Downcast do znanego typu

let movie = item as? Movie 

W tym przykładzie item jest albo typu Movie lub coś innego. W przypadku tej ostatniej movie zostanie przypisana wartość zerowa. Tak więc movie będzie typu Movie?.

Teraz sprawdź następny przykład:

let movie: Movie? 

movie = item as? Movie 

Powiedzmy movie jest klasą zmienną, która mam przypisując pewną wartość w jednym z moich metod klasy.

Dla mnie wygląda na to, że as? Movie jest nieco zbędny, ponieważ movie jest już znany jako typ Movie?.

Czy jest jakaś składnia w Swift, która mówi: "Rzuć ten obiekt na ten sam obiekt co obiekt, do którego go przypisuję. Przypisz zero, jeśli jest to typ opcjonalny, a downcast kończy się niepowodzeniem." ?

Miałem nadzieję na coś takiego:

movie = item as? 

lub

movie =? movie 
+0

Masz na myśli opcjonalne połączenie? https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html – vadian

+0

To byłby miły skrót do składni. –

Odpowiedz

2

Istniejące odpowiedzi poprawnie stwierdzają, że nie ma wbudowany w funkcjonalności do tego. Ale aby zbudować na tym, co już tu napisano, można zdefiniować operatora infiksów =?, który implementuje zachowanie opisane w pytaniu. Na przykład:

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" 
+0

Dokładnie tego oczekiwałem. Z pewnością wykorzystam to w moim następnym projekcie. – Pim

+1

Należy zauważyć, że infix 'inout' operator nie może przypisać stałej' let'. – rintaro

1

Czy istnieje jakiś rodzaj składni w Swift ...

NO.

Trzeba wdrożyć samemu

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) 

Można zrobić to za zwyczaj jednoargumentowego operatora (postfix /? dla exmaple):

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

let movie: Movie? 
movie = item/? 
Powiązane problemy