Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify a variadic (ellipsis) parameter as optional in Swift?

Is it possible to have a variadic parameter be optional in Swift? I tried the two ways that made sense and neither compile:

func myFunc(queryFormat: String?...) {

}

or

func myFunc(queryFormat: String...?) {

}

Note: The 1st implementation technically compiles but if you try to unwrap it:

if let queryFormatUnwrapped = queryFormat {
...
}

You get an error Bound value in a conditional binding must be of Optional Type which indicates to me its treating it as an Array of optional Strings not an optional Array of Strings (which is kind of silly).

like image 636
Shizam Avatar asked May 21 '15 21:05

Shizam


2 Answers

I would filter the nil values with compactMap like below:

func myFunc(queryFormat: String?...) {
    // queryFormat is now an optional-String array = [String?]

    let queryFormat = queryFormat.compactMap { $0 }
    // queryFormat is now a String array = [String]

    print(queryFormat)
}

This can be called as:

myFunc(queryFormat: nil)
myFunc(queryFormat: "format")
myFunc(queryFormat: "format1", "format2")

Output will be:

[]
["format"]
["format1", "format2"]
like image 88
Okhan Okbay Avatar answered Oct 23 '22 16:10

Okhan Okbay


It's not possible to have a an optional variadic parameter. The function will always receive an array for the variadic parameter.

However, the array can be empty, or the values in the array can be nil.

I threw some sample code together, hope it helps communicate what I'm trying to say.

func vardicPrint(strings: String...) {
    if strings.isEmpty {
        print("EMPTY")
    } else {
        for string in strings {
            print(string)
        }
    }
}

func optionalPrint(maybeStrings: String?...) {
    if maybeStrings.isEmpty {
        print("EMPTY")
    } else {
        for string in maybeStrings {
            if let string = string {
                print(string)
            } else {
                print("nil")
            }

        }
    }
}

vardicPrint("Hello", "World", "!")
vardicPrint()


var nilString: String?
optionalPrint("Goodbye", nilString, "World", "!")

/* OUTPUT:
Hello
World
!
EMPTY

Goodbye
nil
World
!
*/
like image 27
Tobias Avatar answered Oct 23 '22 17:10

Tobias