Разрушение кортежа Swift 5.2 в замыкании имеет противоречивое поведение - PullRequest
0 голосов
/ 29 апреля 2020

Я столкнулся со странной проблемой разрушения кортежей в Swift 5.2. Я думал, что деструктурирование кортежей не работает внутри параметра замыкания с некоторого времени go. И действительно, следующее не работает:

let expected: ((Int, Int)) -> Void = { a, b in  // does not compile
    print(a, b)
}

Однако я заметил, что все нижеприведенное работает:

func weird(closure: @escaping ((Int, Int)) -> Void) {
    closure((1, 3))
}

// I can understand this
weird { print($0.0 + $0.1) }
weird { a, b in print(a + b) }

// Surprise!
weird { print($0 + $1) }
weird { p in print(p.0 + p.1) }

Работали ли два последних примера до Swift 5.2? Задокументировано ли это поведение где-нибудь?

1 Ответ

2 голосов
/ 29 апреля 2020

Это относится к этому предложению, которое когда-то было принято в Swift 4.0.

SE-0110 Distin guish между типами функций с одним кортежем и несколькими аргументами

Итак, два ваших примера (хотя не последние два) вызвали ошибку в определенной версии Swift, но команда Swift обнаружила некоторые недопустимые регрессии в этой реализации. Дополнительный комментарий

И поскольку в определенной версии Swift (точной версии я не помню, это могла быть 4.0.x или 4.1), вы можете передать закрытие двух аргументов параметру с типом функции, принимающим один кортеж.

И в последнее время это исключение подтверждается как часть SE-0110, и, если потребуется еще какое-то изменение, будет сделано новое предложение и go через обычное Процесс быстрой эволюции.

Обновление SE-0110 и SE-0155

первоначальное предложение в пересмотренном виде не включает преобразование в особом случае из (T, U, ...) -> V до ((T, U, ...)) -> V для аргументов функции. В ответ на отзывы сообщества это преобразование было добавлено как часть принятия основной командой предложения.

Книга Swift может не содержать четкого объяснения этого поведения, но она, безусловно, задокументирована .

...