2015-09-05 7 views
0

EDIT: Я знаю, что я использовал неправильную версию Xcode для Swift 2, теперь. Задача решена.Swift: функция как другой аргумент функции

Я следую за книгой Swift 2 от Apple. В какой-то момент есть следующий пример:

import Foundation 

func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool { 
    for item in list { 
     if condition(item) { 
      return true 
     } 
    } 
    return false 
} 

func lessThanTen(number: Int) -> Bool { 
    return number < 10 
} 

var numbers = [20, 19, 7, 12] 
hasAnyMatches(numbers, condition: lessThanTen) 

То, что я думаю, странно, это последняя строка. Почему он говорит condition: lessThanTen, а не только lessThanTen? Мой компилятор (Xcode) также дает мне ошибку, делая это так, как показано в книге.

Также: почему он только говорит list: [Int] в третьей строке, но condition: Int -> Bool? Почему не что-то вроде list: [Int] -> Int?

ответ

1
  1. В нем указано condition: lessThanTen, поскольку в Swift вы можете определить «метки», то есть описания для данных, которые требует вызов функции. Это дает вам ошибку, потому что вызов был бы правильным, если объявление функции было func hasAnyMatches(list: [Int], #condition: Int -> Bool) -> Bool (по крайней мере, это было бы в случае с Swift 1.2). Знак числа производит внутри каждого вызова функции метку, идентичную имени аргумента функции. Указанный ярлык не должен быть удален из вызова, поскольку он предназначен для уточнения цели этого параметра для того, кто вызывает функцию.
  2. list: [Int] означает, что первый аргумент функции принимает имя «список» и имеет тип [Int]. condition: Int -> Bool означает, что второй аргумент функции принимает имя «условие» и имеет тип «Int to Bool», то есть condition - это функция, которая принимает один аргумент типа Int и возвращает значение типа Bool. Фактически, если вы читаете последнюю строку, в вызове функции hasAnyMatches передаются следующие: i) массив Ints и ii) функция, которая принимает Int и возвращает Bool (обратите внимание, что при передаче функций в качестве параметров мы только напишите их имя - нет круглых скобок).
+0

1. Изменение строки на 'func hasAnyMatches (список: [Int], #condition: Int -> Bool) -> Bool' удаляет эту ошибку! «Использование» этой метки не требуется, но упрощает чтение программы, не так ли? – PeterPan

+0

Точно. Ярлыки не являются обязательными, но они сделают код более читабельным и явным. – MustangXY

+0

Спасибо за это объяснение! 2. Какая разница, если я напишу 'list: [Int] -> Int' в объявлении функции? Будет ли это иметь значение вообще? Будет ли он еще работать? – PeterPan

2

Быстрые функции и методы могут определять свои параметры либо иметь внешние имена, либо нет.

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

Выписка от: Apple Inc. "Язык быстрого программирования (Swift 2 Preerelease)." IBooks. https://itun.es/us/k5SW7.l

Тег condition: - это внешнее имя закрытия, которое вы передаете в свою функцию hasAnyMatches.

Этот код должен компилироваться и запускаться.

+1

К сожалению, он не компилируется и не запускается. Xcode говорит следующее: _Issue: Посторонняя метка «условие:» в вызове. Fix-it: Удалить "condition:" _ Он отлично работает, если я удалю _condition: _. – PeterPan

+0

@MustangXY дал понять, что может быть опечатка (отсутствует # в объявлении функций). Теперь он работает без проблем! – PeterPan

+1

Это не опечатка. Это потому, что вы используете неправильную версию Swift для тестирования. См. Мой ответ ... – matt

2

Мой компилятор (Xcode) также дает мне ошибку, делая это так, как это показано в книге.

Потому что язык изменился! В Swift 2, который вы , читаете, у функции есть condition:, поэтому ваш звонок должен быть condition:. Но вы - тестирование в Swift 1.2, совсем другом языке, где правила не совпадают.

В Swift 1.2, функция верхнего уровня, объявленный с condition: означает, что вызов должен не иметь condition:. В Swift 1.2, чтобы потребовать, чтобы звонок имел condition:, объявление функции должно было бы указать # condition:.

Вы сбиваете с толку. Обновите Xcode, чтобы язык, который вы используете, совпадает с языком, о котором вы читаете.

+0

Спасибо за этот намек! Я не знал, что Swift 2 работает только с Xcode 7 Beta. – PeterPan

+0

Хороший улов Мэтт. Я задавался вопросом, так ли это происходит. –

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