Раннее возвращение из void-func в Свифт?
Может кто-нибудь объяснить мне следующее поведение в Swift?
func test() -> Bool {
print("1 before return")
return false
print("1 after return")
}
func test2() {
print("2 before return")
return
print("2 after return")
}
test()
test2()
возвращает:
1 before return
2 before return
2 after return
Я ожидаю, что print("2 after return")
никогда не будет выполняться, так как это после оператора return
.
Есть ли что-то, что мне не хватает?
(протестировано с Swift 4/4.1 и Xcode 9.2/Xcode 9.3 beta 2)
Ответы
Ответ 1
Это сложная вещь, Swift не требует полуколоней (они необязательно используются), это позволяет компилятору Swift автоматически выводить, должна ли следующая строка быть новой строкой или завершением для старой. print()
- это функция, которая возвращает void. Значит, слово return print("something")
. Так
return
print("Something")
может быть выведено как return print("something")
Ваше решение - написать
return;
print("Something")
Ответ 2
func test2()
похож на func test2() -> Void
Итак, ваш код обрабатывается как
func test2() -> Void {
print("2 before return")
return print("2 after return")
}
Добавление точки с запятой после печати должно исправить ее.
func test2() -> Void {
print("2 before return")
return; print("2 after return")
}
Вы также можете увидеть ошибку, если вы поместите тип значения после строки возврата, и вы поймете больше,
func test2() {
print("2 before return")
return
2
}
ошибка: неожиданное неволевое возвращаемое значение в функции void 2 ^
Ответ 3
Когда я попробовал это в IBM Swift Sandbox, я получил следующее предупреждение:
warning: expression following 'return' is treated as an argument of the 'return'
print("2 after return")
^
что в значительной степени объясняет эту проблему. Свифт интерпретирует это так, как если бы вы написали:
return(print("2 after return"))
Выполняется инструкция печати и возвращается возвращаемое значение print ()
.
Добавление ;
после возврата делает отдельный оператор
return;
print("2 after return")
а затем предупреждение будет:
warning: code after 'return' will never be executed
print("2 after return")
Ответ 4
func noReturn() {...}
совпадает с
func noReturn() -> (Void) {...} //or func noReturn() -> ()
и поскольку print (...) имеет одну и ту же подпись, нормально звонить return print (...)
в функции void
Ответ 5
Ответ извлечен из вопроса:
Кажется, проблема в том, что swift не завершает функцию сразу же после оператора return в void-функции и использует последовательное значение void
в качестве параметра функции и завершается, как ожидается, если она не void.
Код после возврата никогда не будет выполнен
[...]
return; // <- would return here
[...]
return () // <- would return here
[...]
return // <- would return here
let x = 42
Если Xcode будет работать надежно, это сообщение должно быть показано на следующих примерах:
Выражение после возврата обрабатывается как аргумент возврата
[...]
return
print("oh no") // <- would return here
[...]
return
myClosure("this feels wrong") // <- would return here and execute the function / closure
Эта проблема уже существует в Swift-bug-tracker с 2016 года: https://bugs.swift.org/browse/SR-2028