Разделение нескольких условий с запятыми в Swift
Мы уже знаем, что несколько необязательных привязок могут использоваться в одном выражении if/guard, разделяя их запятыми, но не с &&
eg
// Works as expected
if let a = someOpt, b = someOtherOpt {
}
// Crashes
if let a = someOpt && b = someOtherOpt {
}
Играя с игровыми площадками, формат в стиле запятой также, похоже, работает для булевых условий, хотя я не могу найти это нигде. например
if 1 == 1, 2 == 2 {
}
// Seems to be the same as
if 1 == 1 && 2 == 2 {
}
Является ли это приемлемым методом оценки нескольких логических условий и является ли поведение ,
идентичное поведению &&
или они технически разные?
Ответы
Ответ 1
На самом деле результат не тот. Скажем, что у вас есть 2 оператора в if и && между ними. Если в первом случае вы создадите let, используя необязательную привязку, вы не сможете увидеть его во втором выражении. Вместо этого, используя запятую, вы будете.
Пример запятой:
if let cell = tableView.cellForRow(at: IndexPath(row: n, section: 0)), cell.isSelected {
//Everything ok
}
&& Пример:
if let cell = tableView.cellForRow(at: IndexPath(row: n, section: 0)) && cell.isSelected {
//ERROR: Use of unresolved identifier 'cell'
}
Надеюсь это поможет.
Ответ 2
В Swift 3 ключевое слово where
в условии условия было заменено вместо запятой.
Поэтому утверждение вроде if 1 == 1, 2 == 2 {}
говорит "если 1 равно 1, где 2 равно 2..."
Это, вероятно, легче читать условный оператор с &&
вместо ,
, но результат тот же.
Подробную информацию об изменениях в Swift 3 можно найти в предложении Swift Evolution: https://github.com/apple/swift-evolution/blob/master/proposals/0099-conditionclauses.md
Ответ 3
Вот случай, когда они достаточно различны, чтобы требовать ,
. Следующий код даст
"Я" захвачено закрытием до инициализации всех членов
class User: NSObject, NSCoding {
public var profiles: [Profile] = []
private var selectedProfileIndex : Int = 0
public required init?(coder aDecoder: NSCoder) {
// self.profiles initialized here
let selectedIndex : Int = 100
if 0 <= selectedIndex && selectedIndex < self.profiles.count { <--- error here
self.selectedProfileIndex = selectedIndex
}
super.init()
}
...
}
Это связано с определением && на Bool:
static func && (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows -> Bool
selectedIndex < self.profiles.count
в RHS попадает в замыкание.
Изменение &&
на ,
избавит от ошибки. К сожалению, я не уверен, как ,
определяется, но я думал, что это было интересно.
Ответ 4
https://docs.swift.org/swift-book/ReferenceManual/Statements.html#grammar_condition-list
Грамматика Swift говорит, что condition-list
оператора if
может состоять из нескольких condition
разделенных запятыми ,
Простым условием может быть логическое expression
, optional-binding-condition
или другие вещи:
Таким образом, использование запятой для разделения нескольких выражений прекрасно.
Ответ 5
Когда шаблон соответствует ассоциированному значению в переключателе, это имеет значение при использовании ,
или &&
. Один компилируется, другой нет (Swift 5.1). Это компилируется (&&
):
enum SomeEnum {
case integer(Int)
}
func process(someEnum: SomeEnum) {
switch someEnum {
// Compiles
case .integer(let integer) where integer > 10 && integer < 10:
print("hi")
default:
fatalError()
}
}
Это не так (,
):
enum SomeEnum {
case integer(Int)
}
func process(someEnum: SomeEnum) {
switch someEnum {
// Compiles
case .integer(let integer) where integer > 10, integer < 10:
print("hi")
default:
fatalError()
}
}
Ответ 6
Когда дело доходит до вычисления логических условий, разделенных запятыми, простой способ представить запятую - это пара или скобки.
Итак, если у вас есть
if true, false || true {}
Это превращается в
if true && (false || true) {}