Extending Failable Initializers


(Manav Gabhawala) #1

Its possible to extend the functionality of failable initializers beyond what they are capable of by making the parameters failable too. For instance:

  var someString : String? = “1” // Assume for some reason this is optional
    
  // Here the Int’s failable initializer allows for an optional Int even
  // though it was only actually written for a non optional type because
  // the failable initializer fails when you give it a nil value.
  guard let someInt = Int(someString)
  else { return }
  // There are many possible use cases for this:
    
  enum Some : String { case A, B, C }
  let optionalString: String? = “A"
  // This works too.
  let value = Some(rawValue: optionalString)
  // And can be extended out too.
  let image = NSImage(named: optionalString)

There are several reasons this can be beneficial. This allows you to initialize using optional types and can be really useful if you’re trying to initialize things with stuff downloaded from the network or when using NSUserDefaults, etc. That way you don’t need to explicitly bind everything you use to ensure non-null values twice but the failable initializers take care of it for you, so its kind of like chaining the nil value to the failable initializers.

Regards,
Manav Gabhawala


(Brent Royal-Gordon) #2

Its possible to extend the functionality of failable initializers beyond what they are capable of by making the parameters failable too. For instance:

  var someString : String? = “1” // Assume for some reason this is optional
    
  // Here the Int’s failable initializer allows for an optional Int even
  // though it was only actually written for a non optional type because
  // the failable initializer fails when you give it a nil value.
  guard let someInt = Int(someString)
  else { return }

You can get this kind of behavior with higher-order programming:

  var someString: String? = “1”
  guard let someInt = someString.flatMap(Int.init) else { return }

This says “if someString is nil, return nil; otherwise, initialize an Int passing the unwrapped value, and return the result”.

In general, Optional.map and Optional.flatMap let you do optional-chaining-like things in a much more general way. They’re pretty neat!

···

--
Brent Royal-Gordon
Architechies


(Lily Ballard) #3

Note that this exact example actually fails to compile:

error: type of expression is ambiguous without more context
guard let someInt = someString.flatMap(Int.init) else { return }
                                       ~~~~^~~~

The problem here is the initializer has a default parameter, but default
parameters are lost when treating methods (including initializers) as
function types. So you can actually say something like

let args: (String, Int)? = ("1", 10)
guard let someInt = args.flatMap(Int.init) else { return }

It would be great if the Swift language rules were altered to allow both
of these forms to work.

-Kevin Ballard

···

On Fri, Dec 4, 2015, at 05:29 PM, Brent Royal-Gordon wrote:

> Its possible to extend the functionality of failable initializers beyond what they are capable of by making the parameters failable too. For instance:
>
> var someString : String? = “1” // Assume for some reason this is optional
>
> // Here the Int’s failable initializer allows for an optional Int even
> // though it was only actually written for a non optional type because
> // the failable initializer fails when you give it a nil value.
> guard let someInt = Int(someString)
> else { return }

You can get this kind of behavior with higher-order programming:

  var someString: String? = “1”
  guard let someInt = someString.flatMap(Int.init) else { return }

This says “if someString is nil, return nil; otherwise, initialize an Int
passing the unwrapped value, and return the result”.

In general, Optional.map and Optional.flatMap let you do
optional-chaining-like things in a much more general way. They’re pretty
neat!

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution