1

Swift doesn't support exception as I know. But I'm wondering why? Actually I need advice on the following scenario.

   public func get(pos : Int) -> Int
    {
        if pos >= length
        {
            // what should I do here?
            //throw OutsideBounds;
        }
        return _data.get(pos);
    }

As you see, if the position is greater than the count of the _data, I normally throw an exception. But what should I do in Swift? Need your advice. Thanks

Bagusflyer
  • 12,675
  • 21
  • 96
  • 179
  • 1
    I think maybe I should return nil in my case and the return type of the method should be Int? – Bagusflyer Sep 24 '14 at 09:42
  • https://developer.apple.com/library/prerelease/mac/documentation/Cocoa/Reference/Foundation/Classes/NSException_Class/ – Maxim Shoustin Sep 24 '14 at 09:49
  • it was a hothead decision to mark this question as duplicate, and linked to another question which is not related to this question at all... – holex Sep 24 '14 at 10:07

3 Answers3

2

If an absence of value is a good response in case the condition fails, then you can turn the return type into an optional and implement the function as follows:

public func get(pos : Int) -> Int?
{
    if pos >= length {
        return .None
    }

    return _data.get(pos);
}

If you need to return more information about the error, for example as an instance of NSError, then you can create an enum which can either contain a value (called Some) or an error (called Error):

public enum RetVal {
    case Some(Int)
    case Error(NSError)
}

and change the implementation of your function to something like:

public func get(pos : Int) -> RetVal
{
    if pos >= length {
        return RetVal.Error(NSError(domain: "MyApp", code: 55, userInfo: nil))
    }

    return RetVal.Some(_data.get(pos));
}

and use it as follows:

let returnValue = get(55)
switch returnValue  {
case .Some(let value):
    println(value)
case .Error(let error):
    println(error)
}

This prevent you from forgetting to handle exceptions (like in C#) or polluting your code with catches for any exception that a function/method call can raise (like in java). I didn't like absence of exceptions too at beginning, but now I see that my code is cleaner by avoiding them.

Antonio
  • 71,651
  • 11
  • 148
  • 165
2

Swift support the optional types, those with the ? appended. This seems like the right case to use them. The implication is that the method can either return and Int or, in case of problems, a "non value".

Just rewrite the function as

public func get(pos : Int) -> Int?
    {
        if pos >= length
        {
            return nil
        }
        return _data.get(pos)
    }

If there are more different kind of errors that the method caller needs to know, then you may need a more complex solution to be able to tell the caller what the exact problem is.

Nicola Miotto
  • 3,647
  • 2
  • 29
  • 43
2

I would use power of Optional feature in Swift and write get method like:

var _data:Array<Int> = [1,2,3]
var length = _data.count

func get(pos : Int) -> Int?
{
    if pos >= length{
       return nil
    }

    return _data[pos]
}

// TEST
var value = get(2)  // {Some 3}
var value = get(10) // nil

So next step is pretty simple - to unwrap it:

if let tempData = get(10){
   // success
}
else{
   // failure
}
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225