Constructor
Constructor

Reputation: 7483

How to make type optional if and only if it is not so?

I need to write some foo function like so:

func foo<T>(_ v : T) -> R
{
    // ...
}

Here R should be T if T is an optional type and T? if it is not so. How can I achieve this goal?

Upvotes: 0

Views: 68

Answers (2)

dfrib
dfrib

Reputation: 73196

You can overload foo to specify the different two cases.

// Dummy protocol for this example to allow a concrete dummy T instance
// return in case the provided T? argument is nil (in your actual
// implementation you might have other logic to fix this scenario).
protocol SimplyInitializable { init() }
extension Int : SimplyInitializable {}

func foo<T>(_ v : T) -> T? {
    print("Non-optional argument; optional return type")
    return v
}

func foo<T: SimplyInitializable>(_ v : T?) -> T {
    print("Optional argument; Non-optional return type")
    return v ?? T()
}

let a = 1        // Int
let b: Int? = 1  // Int?

foo(a) // Non-optional argument; optional return type
foo(b) // Optional argument; Non-optional return type

A method with an optional T parameter (T?) may always be called by a non-optional argument T, but there will be an implicit conversion done (backend); hence if an overload with a non-optional parameter T is available, it will take precedence in overload resolution when invoked with a non-optional argument T, as there will be no need of an implicit conversion to T?.

For details regarding the implicit conversion from a T to T?, see:

Swift provides a number of special, builtin behaviors involving this library type:

  • There is an implicit conversion from any type T to the corresponding optional type T?.

Upvotes: 3

davidethell
davidethell

Reputation: 12018

You cannot achieve this in Swift. You are better off declaring the function with optional argument and result and just handling it as an optional wherever you use this function:

func foo<T>(_ v : T?) -> T?
{
    // ...
}

Upvotes: 2

Related Questions