Не удалось найти перегрузку для '/', которая принимает прилагаемые аргументы

// Playground - noun: a place where people can play


func getAverage(numbers: Int...) -> Double{
    var total = 0
    var average:Double = 0

    for number in numbers{
        total = total + number
    }

    average = total / numbers.count

    return average
}

getAverage(3, 6)

Я получаю сообщение об ошибке average = total / numbers.count

Не удалось найти перегрузку для '/', которая принимает предоставленные аргументы

Я попытался исправить:

average = Double(total/numbers.count)

но затем getAverage был установлен на 4 вместо 4.5

Ответ 1

В Swift нет таких неявных преобразований, поэтому вам придется явно преобразовать это:

average = Double(total) / Double(numbers.count)

Из Язык быстрого языка: "Значения никогда не будут неявно преобразованы в другой тип". (Раздел: Быстрый тур)

Но вы теперь используете Swift, а не Objective-C, поэтому постарайтесь думать более функционально. Ваша функция может быть написана следующим образом:

func getAverage(numbers: Int...) -> Double {
    let total = numbers.reduce(0, combine: {$0 + $1})
    return Double(total) / Double(numbers.count)
}

reduce принимает первый параметр в качестве начального значения для переменной аккумулятора, затем применяет функцию combine к переменной аккумулятора и каждому элементу массива. Здесь мы передаем анонимную функцию, которая использует $0 и $1 для обозначения первого и второго параметров, которые она передаёт, и добавляет их.

Еще более кратко, вы можете написать это: numbers.reduce(0, +).

Обратите внимание на то, что вывод типа делает приятную работу по выяснению того, что total является Int.

Ответ 2

Компилятор выбирает реализацию оператора / на основе ваших входных и выходных параметров. В вашем случае входными параметрами являются два значения Int, а выходной параметр Double. Это то, что ищет компилятор:

func / (left: Int, right: Int) -> Double

Однако такой реализации оператора / не существует, поэтому вы получаете ошибку. Когда вы выполняете Double(total/numbers.count), ваш выходной параметр изменяется на Int, поэтому компилятор выбирает следующую реализацию для оператора /, который существует:

func / (left: Int, right: Int) -> Int

Вот почему вы получаете 4 вместо 4.5 в результате, хотя впоследствии вы преобразовываете результат в Double.

Вы можете предоставить собственную реализацию оператора /, который сначала преобразует ваши номера в Double s:

func / (left: Int, right: Int) -> Double {
    return Double(left) / Double(right)
}

Затем вы можете сделать следующее:

let a: Int = 3
let b: Int = 2
let c: Double = a/b  // -> 1.5