Saranjith
Saranjith

Reputation: 11577

How to create Compiler warning for my function in Swift

I want to validate my inputs to function with some conditions and show as a compiler warning/error.

How it is possible?

For example:

func getPoints(start: Int, end: Int) {

}

I want to show compiler warning/error when someone tries to give input high for start than end.

getPoints(start: 3, end: 10) // No warnings
getPoints(start: 6, end: 2) // Compiler warning like: end value can not be less than start value

Actually this is for a framework purpose. I want to ensure that the parameters are not bad inputs.

Upvotes: 0

Views: 507

Answers (2)

Paulw11
Paulw11

Reputation: 115041

You can't generate a warning at compile time, since the arguments are not evaluated beyond checking for type conformance.

In your example, you have used constants, so it would, in theory, be possible to perform the check you want, but what if you passed a variable, or the result of another function? How much of your code would the compiler need to execute in order to perform the check?

You need to enforce your requirements at run time. For example, you could have your function throw if the parameters were incorrect:

enum MyErrors: Error {
     case rangeError
}

func getPoints(start: Int, end: Int) throws {
    guard start <= end else {
        throw MyErrors.rangeError
    }
    ...
}

Or you could have the function simply handle the problem:

func getPoints(start: Int, end: Int) {
     let beginning = min(start,end)
     let ending = max(start,end)
     ...
}

Also, I recommend Alexander's suggestion of using Range instead of Int; it is always a good idea to take advantage of Foundation types, but I will leave my answer as it shows some approaches for handling issues at runtime.

Upvotes: 2

Alexander
Alexander

Reputation: 63379

Such a constraint can't be enforced at compile time. Take Range for example, which enforces that the lowerBound always compares as less or equal to the upperBound. That's just an assertion that runs at run-time, and crashes if it's not met.

I would suggest you just change your API design to use a Range<Int> or ClosedRange<Int> taking pairs of Ints to model ranges is a bad idea, for many reasons:

  1. It doesn't communicate the semantics of a range. Two integers could be anything, but a range is something much more specific.
  2. It doesn't have any of the useful methods, like contains(_:), or support for pattern matching via the ~= operator.
  3. Its error prone, because when passing pairs around, you might make a copy/paste error leading you to accidentally use the same param twice.
  4. It reads better: getPoint(3...10)

Upvotes: 3

Related Questions