Swift: difference as String? vs. as? String

4 Solutions Collect From Internet About “Swift: difference as String? vs. as? String”

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.

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.

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.

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 .