Swift - Take Nil as Argument in Generic Function with Optional Argument
I guess the compiler can't figure out what T
is just from nil
.
The following works just fine though for example:
somethingGeneric(Optional<String>.None)
I believe you've overcomplicated the problem by requiring the ability to pass untyped nil
(which doesn't really exist; even nil
has a type). While the approach in your answer seems to work, it allows for the creation of ??
types due to Optional promotion. You often get lucky and that works, but I've seen it blow up in really frustrating ways and the wrong function is called. The problem is that String
can be implicitly promoted to String?
and String?
can be implicitly promoted to String??
. When ??
shows up implicitly, confusion almost always follows.
As MartinR points out, your approach is not very intuitive about which version gets called. UnsafePointer
is also NilLiteralConvertible
. So it's tricky to reason about which function will be called. "Tricky to reason about" makes it a likely source of confusing bugs.
The only time your problem exists is when you pass a literal nil
. As @Valentin notes, if you pass a variable that happens to be nil
, there is no issue; you don't need a special case. Why force the caller to pass an untyped nil
? Just have the caller pass nothing.
I'm assuming that somethingGeneric
does something actually interesting in the case that it is passed nil
. If that's not the case; if the code you're showing is indicative of the real function (i.e. everything is wrapping in an if (input != nil)
check), then this is a non-issue. Just don't call somethingGeneric(nil)
; it's a provable no-op. Just delete the line of code. But I'll assume there's some "other work."
func somethingGeneric<T>(input: T?) {
somethingGeneric() // Call the base form
if (input != nil) {
print(input!);
}
}
func somethingGeneric() {
// Things you do either way
}
somethingGeneric(input: "Hello, World!") // Hello, World!
somethingGeneric() // Nothing