Reputation: 93
I am new to swift programming . How to assign print function to a variable and call via that variable in swift?
var myPrint = print
myPrint("calling print function")//This line shows error
Second line (myPrint("calling print function")
) shows this error:
Missing argument for parameter #2 in call
Playground execution failed: error: TestingPlayground.playground:5:33: error: missing argument for parameter #2 in call myPrint("calling print function") ^ , TestingPlayground.playground:4:5: note: 'myPrint' declared here var myPrint = print ^
Upvotes: 2
Views: 144
Reputation: 385580
I believe you've found a known bug (or limitation) of the Swift compiler.
The built-in print
function has three parameters. Parameter #1 is unlabeled and is type String ...
(variadic). Parameter #2 has label separator
, is type String
, and has a default value. Parameter #3 has label terminator
, is type String
, and has a default value. Since parameters #2 and #3 have default values, you can call it like print("hello")
.
Closures (like myPrint
) cannot use labeled parameters. So myPrint
takes three unlabeled parameters. Parameter #1 is type String ...
(variadic). Parameter #2 is type String
. Parameter #3 is also type String
. Closure parameters cannot have default values, so myPrint
requires all three parameters. You cannot call it like myPrint("hello")
, because you haven't passed anything for parameters #2 and #3 and they do not (and cannot) have default values.
In Swift, a variadic parameter (like parameter #1 of print
and myPrint
) consumes all arguments until in reaches a label. If you try to call myPrint("hello", " ", "\n")
, all three arguments will be assigned to parameter #1, and nothing will be assigned to parameters #2 and #3.
Since you cannot have labeled parameters in a closure, there is no way to call your myPrint
closure, because there is no way to pass values for parameters #2 and #3.
This is a known limitation. See SR-2475 and SR-494.
Upvotes: 2
Reputation: 299275
print
includes a variadic parameter followed by named parameters with defaults, which means it's hard to use a reference to it this way. The signature for print
is:
public func print(_ items: Any..., separator: String = default, terminator: String = default)
So the type of myPrint
is (Any..., String, String) -> ()
. This is difficult to call because two more parameters are required after the Any...
has sucked up all the parameters. Closures don't allow named parameters currently, so getting this to work is difficult at best, impossible at worst.
The way you do this in Swift is to create wrapping closure:
let myPrint = { print($0) }
Upvotes: 2