Passing individual array elements one by one to variadic parameters

Hi Community,

I'm trying to write a wrap function around print() by adding filename, function name and line number.

If I pass the whole items parameter to print() there will be additional brackets and quotation marks. It looks different from print() . Is there a way to pass individual item one by one to print() without call print() repeatedly?

Thanks

func my_print(_ items: Any..., function: String = #function, line: Int = #line) {
    print(function, line, items)
    //print(function, line, item1, item2, ..)
}

var array = [1:1,2:2,3:3,4:4]
my_print("hello", 3.14, array)
print("hello", 3.14, array)

//hello_swift 13 ["hello", 3.14, [2: 2, 3: 3, 1: 1, 4: 4]]
//hello 3.14 [2: 2, 3: 3, 1: 1, 4: 4]

~
~

In answer to your actual question, in Swift you cannot splat an array into a variadic call. There are many threads discussing how it could be implemented in the future.

But to solve it for your use case, you can mimic the formatting done by print(_:_:_:) and pass it a single string relatively easily:

func my_print(_ items: Any..., function: String = #function, line: Int = #line) {
    let array = [function, line] + items

    let string = array
        .map({ String(describing: $0) })
        .joined(separator: " ")
    print(string)
}
3 Likes

Thanks @SDGGiesbrecht

Just checked that print() is implemented using for in loop.

Is it efficient printing repeatedly inside a loop?

Aren't .map(), .joined() available for those code?

Summary

swift/Print.swift at main · apple/swift · GitHub

  for item in items {
    output.write(prefix)
    _print_unlocked(item, &output)
    prefix = separator
  }

for loops are faster, at least with optimizations turned off. When I wrote the code above I was aiming to be succinct to read, not fast to execute. The standard library has the opposite goal.