#swift
#swift
Вопрос:
Это кажется очень простым. Заранее приношу свои извинения. Но рассмотрим следующие четыре варианта на ту же тему:
var q : String? = nil
if let z : String? = q {
println("q is non-nil")
} else {
println("q is nil")
}
var zz : String? = nil
if (zz) {
println("zz is not nil")
} else {
println("zz is nil")
}
if let z : String? = nil {
println("nil is non-nil")
} else {
println("nil is nil")
}
/*
if (nil) {
println("nil is non-nil")
} else {
println("nil is nil")
}
*/
Наивно, я думаю, что все они должны вести себя одинаково. Но результат есть…
q is nil
zz is nil
nil is non-nil
Если я раскомментирую окончательную форму, я получу…
Playground execution failed: error: <REPL>:57:5: error: type 'NilType' does not conform to protocol 'LogicValue'
if (nil) {
Каковы правила, которые объясняют, когда необязательное выражение может обрабатываться как логическое, с nil как false и {Some whatever} как true ? Почему третий оператор if выводит «nil не nil», когда он кажется семантически идентичным другим? Почему значение nil является приемлемым / преобразуемым в LogicValue в операторе if при привязке к переменной или в выражении let, но не при представлении в виде литерала?
Комментарии:
1. Третья
if
печатьnil is non-nil
очень похожа на ошибку в компиляторе. Вы сообщили об этом в Apple?2. (нет … я подумал, что, должно быть, что-то упускаю. я впервые играю со swift; когда сомневаюсь, я предполагаю, что ошибаюсь.)
3. Как правило, большую часть времени это очень разумное предположение. Бета-тестирование является одним заметным исключением из этого правила 😉
4. Существует ли какая-либо документация о том, что
if let z : String? = q
предполагается делать, в отличиеif let z = q
от того, что хорошо документировано как возвращающее значение true и разворачивающее q в z, если q не равно нулю?5. Что касается
if nil
… для оператора if требуется логическое значение. nil не является логическим значением
Ответ №1:
Результат третьего случая имеет смысл. «If let» проверяет, выполнено ли назначение успешно. Обычный шаблон:
var optional : String?
if let nonOptional : String = optional {
// the optional could successfully be converted to a non-optional
}
Вы просто пытаетесь присвоить nil необязательному, что действительно возможно и допустимо. Следовательно, «пусть, если» возвращает true.
Также часто то же самое делается с назначениями с понижением
var any : AnyObject = "Hello"
if let string = any as? String {
// Downcast to String was successful
}
Наконец, это необязательный тип, который соответствует тому, чтобы быть a LogicValue
, позволяя использовать его в if
инструкции. Дело НЕ в том, что необязательный возвращает nil
и nil
проверяется. nil
автономный режим не может использоваться в операторе if, поскольку он не реализует LogicValue
протокол, и для этого нет причин.
Комментарии:
1. Спасибо. но разве nil не должен соответствовать самому необязательному типу, так что не нужно ли тогда реализовать протокол LogicValue, если Optional соответствует для соответствия? (еще раз извините, если я упускаю что-то очень простое.)
2. @SteveWaldman nil не обязательно должен соответствовать необязательному, необязательному просто нужно определить оператор присваивания с его помощью
Ответ №2:
Ваш Optional Binding
синтаксис неверен.
это должно быть if let z = q {}
Если необходимо добавить тип, он должен быть: if let z:String = q
Если вы сделаете это,
if let z : String = nil {
println("nil is non-nil")
} else {
println("nil is nil")
}
Это ведет себя правильно и печатается nil is nil
.
В последнем случае выражение должно быть a bool
. Причина if q
компиляции в том, что она проверяет nil
для вас и все равно возвращает логическое значение.