2014-12-28 4 views
2

Я читаю руководство Apple Swift Programming Language от Apple и столкнулся со следующей проблемой. Книга определяет функцию sumation как:Ошибка Swift: (int) не конвертируется в int

func sumOf(numbers: Int...) -> Int { 
    var s = 0 
    for number in numbers { 
     s += number 
    } 
    return s 
} 

и включает в себя эксперимент, чтобы «написать функцию, которая вычисляет среднее из его аргументов», которые я пытаюсь повторно использовать sumOf определить:

func averageOf(numbers: Int...) -> Float { 
    var sum = sumOf(numbers) 
    return Float(sum)/Float(numbers.count) 
} 

Xcode возвращает ошибку, вызывающую sumOf (числа): «'[Int]' не конвертируется в 'Int' ' Игнорирование очевидного деления на нулевую проблему, почему переменные параметры теряют свой тип внутри метода и есть ли способ чтобы передать это, чтобы передать вариационный параметр функции sumOf?

+2

К понижающим избирателям этого вопроса ... это кажется совершенно разумным удивляться, что вы не можете передать вариационный аргумент в другую вариационную функцию. Просто потому, что это очевидно для вас, это не значит, что это плохой вопрос. –

+0

(но я не сделал ни единого слова), некоторые исследования можно ожидать до публикации вопроса, и поиск «sumOf» в категории Swift привел бы к быстрому решению. –

+0

Это справедливо, но это то, что означает флаг. Я подозреваю, что голоса были в том, что «этот вопрос является глупым» разнообразием ... –

ответ

4

Путь VARIADIC аргументы работают в том, что в то время как вызывающий абонент может передать любое количество индивидуальных аргументов один за другим:

sumOf(1, 2, 3, 4) 

они представлены в функции в виде массива:

sumOf(numbers: Int…) { 
    // numbers is of type [Int] 
    // (you can see this by option-clicking numbers in Xcode) 
} 

Таким образом, функция-исполнитель может определить, сколько из них существует, петля над ними и т. Д.

Но это означает, что вы не можете назвать одну вариационную функцию, используя вариационный аргумент nt другой функции. Функция sumOf требует нескольких аргументов типа Int, например. 1, 2, 3, 4, но вы передаете один аргумент массива типа [Int], например [1, 2, 3, 4].

Это на самом деле боль, потому что в Swift нет функциональности «splat» - возможность превратить массив в кортеж. Таким образом, вы не можете легко использовать свою функцию sumOf по своему усмотрению.

Одним из решений этой проблемы заключается в реализации sumOf дважды: один раз как функцию, которая принимает массив:

func sumOf(numbers: [Int]) -> Int { 
    // an alternative to the for loop 
    // you might want to try... 
    return reduce(numbers, 0, +) 
} 

И однажды, как VARIADIC функции:

func sumOf(numbers: Int...) -> Int { 
    // don’t reimplement sumOf, just 
    // call the array version 
    return sumOf(numbers) 
} 

Тогда вы можете назвать его либо путь:

sumOf(1,2,3) 
sumOf([1,2,3]) 

и функция перегрузки функции Swift w плохо выбрать соответствующую версию.

Теперь ваша реализация averageOf, которая была в отличном состоянии, будет работать, потому что она может использовать версию массива sumOf.

(если вы хотите дополнительные проблемы: попробуйте перегрузки averageOf таким же образом, а затем, возможно, попробовать писать версии sumOf и averageOf, которые работают на любом целом типе, используя дженерик :)

2

Когда вы проходите numbers, вы передаете один элемент типа [Int]. То, что требуется вариационной сигнатурой, - это некоторое количество отдельных Int s, которые он упаковывает в массив.

Аналогичным образом, вы можете написать sumOf(1, 2, 3, 4), но не sumOf([1, 2, 3, 4]).

Смежные вопросы