2015-12-02 2 views
2

Из того, что я понимаю, map функции Свифта выполняет следующие действия:Свифта Mapping Функция

  • Работа на что-нибудь, что принимает SequenceType
  • Идеи вернуть еще «что-то» (ищет лучший термин), что было это элементы, трансформированные с помощью логики вы передаете в закрытии
  • всегда возвращает «нечто», что по-прежнему соответствует SequenceType и тому # элементов не меняется

Например:

У нас есть 2 класса Молоко и сыр. Мы дали конструктор для сыра, который является следующим:

init(withMilk milk: Milk) { 
    self.milk = milk 
} 

Учитывая массив молока объектов, мы переходим массив молока объектов в сыр объектов, как так:

let arrayOfCheese = arrayOfMilk.map { Cheese(withMilk: $0) } 

Это прекрасно работает для меня. Но теперь я хочу что-то большее, чем обычный сыр. Мне нужно ингредиенты со всего места:

let arrayOfSuperCheese = arrayOfMilk.map { 
    let cheese = Cheese(usingMilk: $0) 
    let sulfur = Sulfur() 
    let minerals = Minerals() 
    let mixer = Mixer() 

    let superCheese = mixer.mixIn(sulphur: sulphur, minerals: minerals) 
    return superCheese 
} 

Compiler сказал мне:

Cannot invoke 'map' with an argument list of type '(@noescape (Element) throws -> _)

В приведенном выше примере это примерно проблема у меня в данный момент. Пожалуйста, дайте мне знать, если этот пример имеет смысл или нет.

+0

В вашем примере кода используется 'withMilk', но использование использует' usingMilk'. Вы уверены, что у вас нет опечатки в вашем коде? –

+0

Исправлено, извините. У меня на самом деле нет этого в коде, просто я решил внести какой-то контекст в мою проблему. –

ответ

2

Это достаточно сложно, что он не может разумно сделать заключение о закрытии. Так что укажите:

let arrayOfSuperCheese = arrayOfMilk.map { (milk: Milk) -> Cheese in 
    let cheese = Cheese(usingMilk: milk) 
    let sulfur = Sulfur() 
    let minerals = Minerals() 
    let mixer = Mixer() 

    let superCheese = mixer.mixIn(sulfur: sulfur, minerals: minerals) 
    return superCheese 
} 
+0

Очевидно, константа 'cheese' в этом закрытии не используется, но я хотел как можно больше сохранить фрагмент кода. Кроме того, в соответствии с обычными соглашениями я бы не использовал 'usingMilk' (или' withMilk', который вы ссылаетесь в другом месте) для первого параметра 'Cheese', а скорее просто« молоко », но это зависит от вас. – Rob

+0

Спасибо за ваш ответ и совет. Он работал, как только я четко определил подпись закрытия. Знаете ли вы, когда точным является то, что требуется явная подпись закрытия? –

+0

Нет, я не знаю точного порога, но он воспроизводится с примерами, намного проще, чем это. Например. 'let cheeses = milks.map {let cheese = Cheese (молоко: $ 0); return cheese} '. Существует некоторое поведение, которое изменяется при многострочном закрытии, поэтому, возможно, так оно и есть, но я подозреваю, что это может быть более тонким, чем это. В заключение я пишу код с предполагаемыми типами до такой точки, что компилятор говорит мне, что он больше не может вывести, а затем я явно указываю параметры. – Rob

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