Ваш пример:
let str = createClass("someStr")["0"]{"One"}
использует синтаксис трейлинг-закрытия .
Синтаксис трейлинг-закрытия работает с включением трейлинг-замыкания как дополнительный параметр к вызову функции. Подписание массива на самом деле является вызовом функции изнутри (функции, называемой subscript
), и Swift пытается передать это замыкание в качестве второго параметра для вызова подписки, что объясняет ошибка:
Невозможно указать значение типа SomeClass с аргументом типа (String, () -> String).
Другими словами, вы не можете передать оба "0"
и закрытие {"One"}
для функции подписки.
Существует как минимум 3 способа исправить это и все же поместить его в одну строку:
Опция 1: используйте явный вызов для передачи замыкания вместо использования синтаксиса конечного замыкания
Оберните замыкание в ()
, чтобы сделать вызов явным:
let str1 = createClass("someStr")["0"]({"One"})
print(str1)
Вариант 2: обернуть createClass("someStr")["0"]
в скобки
Это позволяет Swift знать, что подписка получает только "0"
в качестве параметра и позволяет синтаксису замыкания замыкания работать должным образом:
let str2 = (createClass("someStr")["0"]){"One"}
print(str2)
Вариант 3: Добавить .self
к результату До синтаксиса завершающего замыкания:
Это снова завершает вызов по подписке и позволяет избежать путаницы.
let str3 = createClass("someStr")["0"].self {"One"}
print(str3)
Лично я бы выбрал Вариант 1 , потому что синтаксис завершающего замыкания является ненужным syntacti c сахар, который здесь явно не работает.
Решение задачи
В комментарии, которые я спросил:
Я согласен, что синтаксис конечного замыкания, скорее всего, является ошибкой, которую они могли бы исправить, но я не понимаю, почему вы настаиваете на использовании здесь синтаксиса конечного замыкания. Что такого нежелательного в том, чтобы обернуть замыкание в (), чтобы сделать вызов явным, даже если это просто обход ошибки в Swift?
Вы ответили:
причина настаивать на том, что я пытаюсь решить проблему. на самом деле, эта функция, которая возвращает замыкание, является только одной из сторон, она выглядит следующим образом С помощью операции индексации, хитрость заключается в том, чтобы спроектировать класс, который берет замыкание с помощью операции индексации:
class SomeClass {
subscript(_ s: String, closure: () -> String) -> String {
return String(closure().reversed())
}
}
func foo(_ str: String) -> SomeClass {
return SomeClass()
}
func Challenge() {
// Do not edit below this line
XCTAssertEqual(foo("str1")["str2"]{ "654321" }, "123456")
}