WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: day 5: For variadic func, can i assign nil to its parameter name if nothing is passed to it?

Forums > 100 Days of Swift

Hi, how do i edit the below error code such that when calling the variadic function with no parameter value, i can print - "Nothing was passed inside variadic function".

func squareVariadic(numbers: Int...){

if numbers == nil{ //ERROR: Comparing non-optional value of type '[Int]' to 'nil' always returns false
    print("Nothing was passed inside variadic function.")
}

for number in numbers{
    print("\(number) squared is \(number*number)")
}

}

squareVariadic(numbers: )

1      

Why call it when nothing is passed and nothing is done? Do the check before the call.

What you can do is, though, check if numbers isEmpty, not nil. You always have to pass an array. You can't pass nil.

2      

Why call it when nothing is passed and nothing is done? Do the check before the call.

Except that currently in Swift, you can't do the check before because you can't pass an array where a list of variadic parameters is expected.

func squareVariadic(numbers: Int...) {
    for number in numbers {
        print("\(number) squared is \(number*number)")
    }
}

let arrayOfNumbers: [Int] = []

if !arrayOfNumbers.isEmpty {
    squareVariadic(numbers: arrayOfNumbers)
} else {
    print("Nothing was passed inside variadic function.")
}

This results in a compiler error: Cannot pass array of type '[Int]' as variadic arguments of type 'Int'

There have been proposals to correct this (say, with something like Python's "splat" operator to expand or unpack an array into its elements), but the Swift team is holding off while the design of how variadic generics should work is hashed out.

It often makes more sense to do those kinds of checks inside a function anyway. That minimizes the amount of things the programmer has to know to do before using the function and presents a cleaner API.

This is exactly the kind of situation that the guard statement is for. (Sorry if this doesn't make sense yet, @rabinexpressoSwift; I'm not sure on which of the 100 Days guard gets covered)

func squareVariadic(numbers: Int...) {
    guard !numbers.isEmpty else {
        print("Nothing was passed inside variadic function.")
        return
    }

    for number in numbers {
        print("\(number) squared is \(number*number)")
    }
}

let arrayOfNumbers: [Int] = []

squareVariadic(numbers: arrayOfNumbers)

Which still won't compile for the same reason as before but is a cleaner API with less cognitive load when using it. Instead of having to remember to check that your array isn't empty before you call squareVariadic, you just pass the array and let squareVariadic handle it appropriately.


To answer the original question:

Hi, how do i edit the below error code such that when calling the variadic function with no parameter value, i can print - "Nothing was passed inside variadic function".

The way to call squareVariadic with zero parameters is to just leave the variadic argument out of the call and check for an empty array inside the function, either by checking for numbers.isEmpty or using a guard:

func squareVariadic(numbers: Int...) {
    if numbers.isEmpty {
        print("Nothing was passed inside variadic function.")
    } else {
        for number in numbers {
            print("\(number) squared is \(number*number)")
        }
    }
}

or:

func squareVariadic(numbers: Int...) {
    guard !numbers.isEmpty else {
        print("Nothing was passed inside variadic function.")
        return
    }

    for number in numbers {
        print("\(number) squared is \(number*number)")
    }
}

And then call it like so:

squareVariadic()
//prints Nothing was passed inside variadic function.

2      

The problem stays the same. You have to check before to call it with or without parameters. Or do I miss something?

1      

Thanks @roosterboy for explaining that

  1. arrays cannot be passed into a variadic function
  2. showing how both guard and if-else conditions can work inside called function to check if argument value is empty
  3. how to call function with empty value by removing function argument during call; squareVariadic()

Thanks @Hatsushira for suggesting .isEmpty.

2      

Hacking with Swift is sponsored by Emerge

SPONSORED Optimize your app’s startup time, binary size, and overall performance using Emerge’s advanced app optimization and monitoring tools. Reliably measure app size, speed up your app's startup time with Emerge's Launch Booster, and much more. Emerge is actively used by many of the top mobile development teams in the world.

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.