rajneesh biswal
rajneesh biswal

Reputation: 93

Assign print function to a variable

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

Answers (2)

rob mayoff
rob mayoff

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

Rob Napier
Rob Napier

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

Related Questions