Is there a difference between as? String
vs. as String?
in Swift? If so, what's the difference and when should I use one vs. another?
There's a subtle but important difference:
variable as? String
: variable
can be any type, such as an array, an integer, etc. Cast to string if it's a string, set to nil
otherwise.
variable as String?
: variable
is a String?
, but stored in an opaque type, such as AnyObject?
, or it's a non optional string. If it's something different, a runtime exception is generated.
Some examples:
var x: AnyObject? = "Test"
x as String? // OK, the result is an optional string
x as? String // OK, evaluates to an optional string
"string" as String? // OK, evaluates to optional string
x as? Int // OK, evaluates to nil, it's not an Int
x as Int? // Runtime exception, it's not castable to optional Int
So:
as? Type
means: cast to this type, if possible, otherwise evaluate to nil
as Type?
means: cast to an optional Type
, because I know it's an optional Type
. I understand that if it's not that, a runtime exception is generatedHowever, the real difference is between as?
and as
: the former is an attempt to cast, the latter is a forced cast, resulting in runtime error if not possible.
Update Dec 14, 2015 Since Swift 1.2, there are 3 variations of the as
operator:
as?
is an attempt to cast, evaluating to nil
if cast failsas!
is a forced cast, resulting to an runtime exception if cast fails (this is what as
previously did)as
is now a special type of cast to be used when casting to equivalent types, usually bridged types, such as Swift's String
and NSString
.From The Swift Programming Language
book,
as
is a type cast operator which we use to downcast to the subclass
and as?
is used for an optional form, when we are not sure if the downcast
will succeed. Consider the following example
for item in library {
if let movie = item as? Movie {
println("Movie: '(movie.name)', dir. (movie.director)")
} else if let song = item as? Song {
println("Song: '(song.name)', by (song.artist)")
}
}
The example starts by trying to downcast
the current item as a Movie
. Because item
is a MediaItem
instance, it’s possible that it might be a Movie
; equally, it’s also possible that it might be a Song
, or even just a base MediaItem.
String?
An optional value
either contains a value or contains nil
to indicate that the value is missing.From this,
as? String
means when you don't know what you're downcasting, you are assuming that as a String
, but it might me Integer
or Float
or Array
or Dictionary
as String?
means it's an Optional Value
, it may either contain a String
or Nil
value.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With