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

时间:2018-02-03 11:16:37

标签: swift generics optional

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?

2 个答案:

答案 0 :(得分:3)

您可以重载foo以指定不同的两种情况。

// 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

具有可选T参数(T?)的方法可能始终由非可选参数T调用,但会进行隐式转换(后端);因此,如果具有非可选参数T的重载可用,则在使用非可选参数T调用时,它将优先于重载解析,因为不需要隐式转换为T?

有关从TT?的隐式转换的详细信息,请参阅:

  

Swift提供了许多涉及此内容的特殊内置行为   库类型:

     
      
  • 从任何类型T隐式转换为相应的可选类型T?
  •   

答案 1 :(得分:2)

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?
{
    // ...
}