Xcode 8: типы функций не могут иметь метки аргументов, нарушающих мою сборку

Похоже, что по какой-то причине Swift решили сделать кодирование в нем менее читаемым, заставив пользователей удалять метки меток завершения обработки. Я прочитал "Быстрое обсуждение" и все еще считаю это ошибкой. По крайней мере, они могли сделать это необязательным.

При создании с использованием Xcode 8 - есть ли способ заставить компилятор использовать Swift 2.3, чтобы я больше не получал эти ошибки? Я обновил опцию использования устаревшего Swift (в настройках сборки) legacy support in xcode, но я все еще, кажется, получаю эту ошибку:

Типы функций не могут содержать метку аргументов 'isloggedIn'; вместо этого используйте '_'

error Xcode 8

Как я могу хранить свои ярлыки в обработчиках завершения?

Ответ 1

Дизайнеры Swift решили запретить ярлыки аргументов для типов функций.

Обоснование объясняется здесь: https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md

Это разочаровывающий и сомнительный выбор, поскольку запрещение ярлыков аргументов значительно упрощает неправильное обращение к закрытию, что кажется более важным, чем упрощение системы языкового типа.

Юзабилити> идеология.

Ответ 2

Обходной путь для рассмотрения. Вы не можете:

func doStuff(completion: (foo: Int, bar: String) -> Void) {
    ...
    completion(foo: 0, bar: "")
}

... но вы можете сделать:

func doStuff(completion: ((foo: Int, bar: String)) -> Void) {
    ...
    completion((foo: 0, bar: ""))
}

т.е. иметь единственный неназванный аргумент для вашего закрытия, который является кортежем, в этом случае (foo: Int, bar: String).

Это уродливо по-своему, но по крайней мере вы сохраняете метки аргументов.

Отказ от ответственности: я не думал об улавливании или последствиях этого подхода.

Ответ 3

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

  1. улучшая скорость разработки (без меток аргументов он требует от нас прокрутки вверх до вершины метода каждый раз, когда мы помещаем обработчик завершения.
  2. Уменьшить ошибки: (У меня уже было несколько ошибок, вызванных неправильными вводами обработчика завершения, особенно с теми, которые ожидают логические значения)
  3. Сделайте код более понятным для всех членов команды. Не у каждого есть только один член команды, и, таким образом, он может легко подобрать код других людей, который должен иметь.
  4. Наконец, хорошая практика программирования означает, что решение должно выглядеть так же, как и фактический разрабатываемый элемент. completionhandler: (newvalues, nil) выглядит менее похоже на управляемый элемент, чем completionhandler(results: newValue, error:nil)

Мне бы очень хотелось, чтобы люди, читающие это, делились своими отзывами/комментариями по этому поводу, прежде чем я отправлю его, чтобы показать, что есть другие, которые поддерживают это.

Изменение: я подал заявку здесь: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161010/028083.html, который, как представляется, был согласован. Похоже, что это произойдет, однако обсуждение заключается в том, представлено ли это как улучшение Swift 4 (весьма вероятно)

Ответ 4

Вы должны использовать _, чтобы сделать ваши параметры неназванными, и это несчастливо. Вместо того, чтобы ссылаться на каждый параметр, а затем слепо называть свою функцию, я предлагаю создать объект-оболочку.

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

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

struct LineNoteCellState {

    var lineNoteText: String?
    var printOnInvoice = false
    var printOnLabel = false
}

Вот пример его использования:

cell.configure(editCallback: { (_ state: LineNoteCellState) in

    self.lineNoteText = state.lineNoteText
    self.printOnInvoice = state.printOnInvoice
    self.printOnLabel = state.printOnLabel
})

Ответ 5

Полупродолжительное, обратите внимание на _

completion: (_ success: Bool) -> Void