我需要像这样编写一些foo
函数:
func foo<T>(_ v : T) -> R
{
// ...
}
如果T
是可选类型,则应在此处R
T
,如果不是可选类型,则应T?
。如何实现这一目标?
您可以重载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?
.
有关从 T
到 T?
的隐式转换的详细信息,请参阅:
- Swift:编译器从类型到可选类型的转换
Swift 提供了许多特殊的内置行为,涉及此 库类型:
- 存在从任何类型
T
到相应的可选类型T?
的隐式转换。
在 Swift 中无法实现这一点。您最好使用可选参数和结果声明函数,并在使用此函数的任何地方将其作为可选处理:
func foo<T>(_ v : T?) -> T?
{
// ...
}