20

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?

netwire
  • 7,108
  • 12
  • 52
  • 86

4 Answers4

36

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 generated

However, 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 fails
  • as! 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.
Behdad
  • 941
  • 12
  • 23
Antonio
  • 71,651
  • 11
  • 148
  • 165
  • Interesting answer, a small clarification if I may, given the above, what then is the difference between 'as' and 'as!' - both are forced casts that will generate runtime exceptions if casting invalid objects no? – Woodstock Dec 13 '15 at 22:18
  • @Woodstock the `as` operator has changed since 1.2. I've updated the answer. Thanks!! – Antonio Dec 14 '15 at 08:06
  • thanks for the update my friend! – Woodstock Dec 14 '15 at 10:43
5

From The Swift Programming Language book,

  1. 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.

  1. String? An optional value either contains a value or contains nil to indicate that the value is missing.

From this,

  1. 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
  2. as String? means it's an Optional Value, it may either contain a String or Nil value.
arthankamal
  • 6,341
  • 4
  • 36
  • 51
0

Yes there is a difference.

In the first case, you are doing an optional cast to the type String. This will return a value if the object you are attempting to cast is indeed a String or nil if it is not.

In the second case, you are doing a forced cast to the type String?. If the value you are casting is not a string, it will crash your program.

drewag
  • 93,393
  • 28
  • 139
  • 128
0

YES, there is diffrence.

variable as String? downcast to optional String.If variable is not String? it will cause run-time exception.

while variable as? String will return nil if your variable is not String type or return downcast variable to String. This is conditional downcasting, if you not sure about down-casting you need to use this .

codester
  • 36,891
  • 10
  • 74
  • 72