Не удалось найти перегрузку для '/', которая принимает прилагаемые аргументы
// 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