Reputation: 7483
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
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 typeT?
.
Upvotes: 3
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