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


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

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

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

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

5 69

5 ответов:

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

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

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

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

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

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).

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

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

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

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

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
})

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

  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 что, похоже, было согласовано. Похоже, что это произойдет, однако обсуждение заключается в том, представлено ли это как быстрое улучшение 4 ( весьма вероятно)

полу-обходной путь, обратите внимание на _

completion: (_ success: Bool) -> Void