8 ответов:
вот один подход. Предполагая, что
someVar- этоIntиComparable, вы можете дополнительно назначить операнд новой переменной. Это позволяет вам охватить его, однако вы хотите использоватьwhereключевые слова:var someVar = 3 switch someVar { case let x where x < 0: print("x is \(x)") case let x where x == 0: print("x is \(x)") case let x where x > 0: print("x is \(x)") default: print("this is impossible") }это можно немного упростить:
switch someVar { case _ where someVar < 0: print("someVar is \(someVar)") case 0: print("someVar is 0") case _ where someVar > 0: print("someVar is \(someVar)") default: print("this is impossible") }вы также можете избежать
whereключевое слово полностью с диапазоном соответствия:switch someVar { case Int.min..<0: print("someVar is \(someVar)") case 0: print("someVar is 0") default: print("someVar is \(someVar)") }
С помощью Swift 4 Вы можете выбрать один из следующих коммутаторов для замены вашего оператора if.
#1 с помощью переключателя с
CountablePartialRangeFromиPartialRangeUpTolet value = 1 switch value { case 1...: print("greater than zero") case 0: print("zero") case ..<0: print("less than zero") default: fatalError() }
#2 с помощью переключателя с
CountableClosedRange,CountableRange,Int' smaxстатическое свойство иInt' sminстатическое свойствоlet value = 1 switch value { case 1 ... Int.max: print("greater than zero") case Int.min ..< 0: print("less than zero") case 0: print("zero") default: fatalError() }
#3 с помощью переключателя с предложением where
let value = 1 switch value { case let val where val > 0: print("\(val) is greater than zero") case let val where val == 0: print("\(val) is zero") case let val where val < 0: print("\(val) is less than zero") default: fatalError() }
#4 с помощью переключателя с предложением where и назначение на
_let value = 1 switch value { case _ where value > 0: print("greater than zero") case _ where value == 0: print("zero") case _ where value < 0: print("less than zero") default: fatalError() }
#5 с помощью переключателя с
RangeExpressionпротокол~=(_:_:)операторlet value = 1 switch true { case 1... ~= value: print("greater than zero") case ..<0 ~= value: print("less than zero") default: print("zero") }
#6 с помощью выключателя с
Equatableпротокол~=(_:_:)операторlet value = 1 switch true { case value > 0: print("greater than zero") case value < 0: print("less than zero") case 0 ~= value: print("zero") default: fatalError() }
#7 с помощью переключателя с
CountablePartialRangeFrom,PartialRangeUpToиRangeExpression' scontains(_:)методlet value = 1 switch true { case (1...).contains(value): print("greater than zero") case (..<0).contains(value): print("less than zero") default: print("zero") }
The
switchзаявление, под капотом, использует~=оператора. Так вот:let x = 2 switch x { case 1: print(1) case 2: print(2) case 3..<5: print(3..<5) default: break }Desugars к этому:
if 1 ~= x { print(1) } else if 2 ~= x { print(2) } else if 3..<5 ~= x { print(3..<5) } else { }если вы посмотрите на стандартные библиотеки, он может сказать вам точно, что
~=перегружен, чтобы сделать: в комплекте идет согласование диапазона и приравнивание к равным вещам. (Не входит в комплект, является enum-случае соответствия, что является особенностью языка, а не функция стандартной библиотеки)вы увидите, что он не соответствует прямому булеву с левой стороны. Для такого рода сравнений необходимо добавить оператор where.
если только... вы перегружаете
~=оператором. (Это вообще не рекомендуется) одна возможность будет что-то вроде этого:func ~= <T> (lhs: T -> Bool, rhs: T) -> Bool { return lhs(rhs) }так что соответствует функция, которая возвращает логическое значение слева значение справа. Вот такая вещь, которую вы могли бы использовать ибо:
func isEven(n: Int) -> Bool { return n % 2 == 0 } switch 2 { case isEven: print("Even!") default: print("Odd!") }для вашего случая, вы можете иметь заявление, которое выглядит следующим образом:
switch someVar { case isNegative: ... case 0: ... case isPositive: ... }но теперь вы должны определить новый
isNegativeиisPositiveфункции. Если вы не перегрузите еще несколько операторов...вы можете перегружать обычные инфиксные операторы, чтобы быть карри префиксными или постфиксными операторами. Вот пример:
postfix operator < {} postfix func < <T : Comparable>(lhs: T)(_ rhs: T) -> Bool { return lhs < rhs }это будет работать примерно так:
let isGreaterThanFive = 5< isGreaterThanFive(6) // true isGreaterThanFive(5) // falseобъедините это с более ранней функцией и вашим коммутатором заявление может выглядеть так:
switch someVar { case 0< : print("Bigger than 0") case 0 : print("0") default : print("Less than 0") }теперь, вы, вероятно, не должны использовать такие вещи на практике: это немного изворотливо. Вы (вероятно) лучше придерживаться
whereзаявление. Тем не менее, шаблон оператора switchswitch x { case negative: case 0: case positive: }или
switch x { case lessThan(someNumber): case someNumber: case greaterThan(someNumber): }кажется достаточно распространенным, чтобы это стоило рассмотреть.
вы можете:
switch true { case someVar < 0: print("less than zero") case someVar == 0: print("eq 0") default: print("otherwise") }
так как кто-то уже написал
case let x where x < 0:вот альтернатива для wheresomeVar- этоInt.switch someVar{ case Int.min...0: // do something case 0: // do something default: // do something }и вот альтернатива для where
someVar- этоDouble:case -(Double.infinity)...0: // do something // etc
вот как это выглядит с диапазонами
switch average { case 0..<40: //greater or equal than 0 and less than 40 return "T" case 40..<55: //greater or equal than 40 and less than 55 return "D" case 55..<70: //greater or equal than 55 and less than 70 return "P" case 70..<80: //greater or equal than 70 and less than 80 return "A" case 80..<90: //greater or equal than 80 and less than 90 return "E" case 90...100: //greater or equal than 90 and less or equal than 100 return "O" default: return "Z" }
The
<0выражение не работает (больше?) так что я закончил с этим:Swift 3.0:
switch someVar { case 0: // it's zero case 0 ..< .greatestFiniteMagnitude: // it's greater than zero default: // it's less than zero }
рад, что Swift 4 решает эту проблему: В качестве обходного пути в 3 я сделал:
switch translation.x { case 0..<200: print(translation.x, slideLimit) case -200..<0: print(translation.x, slideLimit) default: break }работает, но не идеально
Comments