John
John

Reputation: 1015

Getting error non-void return value in void function | Swift

I don't understand why I am getting the following error when executing this function:

error: unexpected non-void return value in void function return [index, dic[value]!]

func findIndexes(_ nums: [Int], _ target: Int) -> [Int] {
    var dic = [Int:Int]()
    var answer: [Int] = []
    nums.enumerated().forEach { index, value in
        
        //the goal is to get the index of the value matching the difference
        //check if current value == anything in dictionary
        
        //MARK: Add the Index and Difference to Dictionary
        let difference = (target - value)
        if (dic.keys.contains(value) && !dic.values.contains(index)) {
            return [index, dic[value]!]
        }
        dic[difference] = index
    }
    return []
}

print(findIndexes([0,11,15,2,7], 9))

Upvotes: 1

Views: 122

Answers (1)

matt
matt

Reputation: 536047

I'm unclear what you're trying to do, but this is a version of what you are doing that compiles:

func findIndexes(_ nums: [Int], _ target: Int) -> [Int] {
    var dic = [Int:Int]()
    var answer: [Int] = []
    for (index, value) in nums.enumerated() {
        let difference = (target - value)
        if (dic.keys.contains(value) && !dic.values.contains(index)) {
            return [index, dic[value]!]
        }
        dic[difference] = index
    }
    return []
}

Why the difference? for...in is a loop. You can return from the surrounding function from within it, break out of it, etc. forEach loops implicitly but it is not a loop; it takes a closure, and you can't return out of that unless it's a closure that yields a return value, and this one doesn't; its type, as you can see from the docs, is (Self.Element) throws -> Void — and Void means "no return value".

If you insist on using forEach, you can do what you're trying to do with a bit of extra jiggery-pokery:

func findIndexes(_ nums: [Int], _ target: Int) -> [Int] {
    var dic = [Int:Int]()
    var answer: [Int] = []
    nums.enumerated().forEach { index, value in
        let difference = (target - value)
        if (dic.keys.contains(value) && !dic.values.contains(index)) {
            answer = [index, dic[value]!]
            return
        }
        dic[difference] = index
    }
    return answer
}

I think that does what you're trying to do, but I'm not sure; it seems unnecessarily obscure. In my personal opinion, the way to program is to Say What You Mean (SWYM).

Upvotes: 2

Related Questions