user49354
user49354

Reputation: 199

How to pass variadic parameter in swift?

I know I can call print directly, but why pass items to another function make it like wrapped by Array? I wanna know why and how to fix it

func test(items:Any...) {
  print(items)
}

test(1,2,3)     // print [1,2,3]
print(1, 2,3)   // print 1 2 3

How to make test function act like print function?

Upvotes: 6

Views: 3289

Answers (4)

greatxp117
greatxp117

Reputation: 77

The accepted solution works fine, but I figured I'd add, since it doesn't explain the behavior.

by defining the function with args: Any... you are using Swift's variadic parameters. These variadic parameters are defined as arrays. On further examination, this makes sense, as how else would you be able to access all the parameters of such a function if they weren't in some sort of data structure?

For more information on variadic parameters, check out this article: https://www.avanderlee.com/swift/variadic-parameters/

Upvotes: 0

Michael
Michael

Reputation: 9044

EDIT: Ah, I did not understand your question. Swift is not written in Swift, so you cannot necessarily define a func in the same way. From the documentation...

The values passed to a variadic parameter are made available within the function’s body as an array of the appropriate type.

If you do pass an array to print, you get the same effect as you are seeing with a Swift func. i.e.

print(1, 2, 3)    - prints 1 2 3
print([1, 2, 3])  - prints [1, 2, 3]

Furthermore, the following prints "Array<Any>".

func printIt(_ args: Any...) {
    print(type(of: args))
}

Since in Swift the only choice for defining the func with variable arguments is "...", I take it to mean you cannot define a func in the same manner as print. Therefore your only choice if you need the same result is to simulate it by converting the array to a string, joined with spaces. Is your question theoretical or do you have a particular objective?

========

I'm not sure I understand your question, as the following works:

func printIt(args: Any...) {
    print(args)
}

printIt(args: 1, 2, 3)

Alternatively, if you don't want to pass the parameter name:

func printIt(_ args: Any...) {
    print(args)
}

printIt(1, 2, 3)

Upvotes: -1

user49354
user49354

Reputation: 199

Finally, I wrap test like this:

func test( items:Any...) {
    for num in items {
        print("\(num) ", separator:" ", terminator:"")
    }
    print("")
}

And this works fine, But Any better solutions?

Upvotes: 6

Sweeper
Sweeper

Reputation: 271515

If you want to make test do the same thing as print, why not just call print?

func test(args: Any...) {
    print(args)
}

If you are not allowed/don't want to use this little trick, you can try this. But this only works with CustomStringConvertible:

func test(args: CustomStringConvertible...) {

    print(args.map {
        $0.description
    }.joinWithSeparator(" "))

}

Upvotes: 1

Related Questions