Search code examples
iosswift3option-typeoptional-binding

Swift3, unwrapping Optional<Binding> (in SQLite.swift)


In the most excellent SQLite.swift, I have

 let stmt = try local.db!.prepare(..)
 for row in stmt {
    for tricky in row {

each "tricky" is an Optional<Binding>

The only way I know to unwrap each tricky is like this

var printable:String = "

if let trickyNotNil = tricky {
    if let anInt:Int64 = trickyNotNil as? Int64 {
       print("it's an Int") 
        .. use anInt
        }
    if let aString:String = trickyNotNil as? String {
        print("it's a String")
        .. use aString}
}
else {
    tricky is nil, do something else
}

In the example, I'm pretty sure it can only be either an Int64 or String (or something that goes to a String); I guess one would have to cover any other possibilities in there perhaps with a default case.

Is there a swiftyer way?

Is there are way to get the type of an Optional<Binding> ?

(BTW regarding, specifically, SQLite.swift; there may be a way I am unaware of from the doco to "get the type of column n". That would be cool, but, the question in the previous paragraph remains, in general.)


Solution

  • You can use a switch statement based on the class. Sample code for this kind of switch statement looks like this:

    let array: [Any?] = ["One", 1, nil, "Two", 2]
    
    for item in array {
      switch item {
      case let anInt as Int:
        print("Element is int \(anInt)")
      case let aString as String:
        print("Element is String \"\(aString)\"")
      case nil:
        print("Element is nil")
      default:
        break
      }
    }
    

    You can also add where clauses to one or more of your cases if needed:

    let array: [Any?] = ["One", 1, nil, "Two", 2, "One Hundred", 100]
    
    for item in array {
      switch item {
      case let anInt as Int
           where anInt < 100:
        print("Element is int < 100 == \(anInt)")
      case let anInt as Int where anInt >= 100:
        print("Element is int >= 100 == \(anInt)")
      case let aString as String:
        print("Element is String \"\(aString)\"")
      case nil:
        print("Element is nil")
      default:
        break
      }
    }