回答:
これが1つのアプローチです。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)")
}
default: fatalError()
考えられる論理エラーを早期に検出することをお勧めします。
assertionFailure
は、特にチームで作業する場合、より安全なオプションのようです。
Swift 5では、ifステートメントを置き換えるために、次のスイッチのいずれかを選択できます。
PartialRangeFrom
およびでスイッチを使用するPartialRangeUpTo
let value = 1
switch value {
case 1...:
print("greater than zero")
case 0:
print("zero")
case ..<0:
print("less than zero")
default:
fatalError()
}
ClosedRange
およびでスイッチを使用するRange
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()
}
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()
}
_
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()
}
RangeExpression
プロトコルの~=(_:_:)
オペレーターでスイッチを使用するlet value = 1
switch true {
case 1... ~= value:
print("greater than zero")
case ..<0 ~= value:
print("less than zero")
default:
print("zero")
}
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()
}
PartialRangeFrom
、PartialRangeUpTo
そしてRangeExpression
S」contains(_:)
メソッドlet value = 1
switch true {
case (1...).contains(value):
print("greater than zero")
case (..<0).contains(value):
print("less than zero")
default:
print("zero")
}
0.1
ので、致命的なエラーをスローし1...
た場合、このソリューションは唯一の1からのカバー数字のみで動作しますのでvalue
あるInt
変数の型は、任意のコンパイラエラーなしで機能区切りを変更した場合ので、それは危険です。
switch
声明は、ボンネットの下に、使用する~=
演算子を。したがって、この:
let x = 2
switch x {
case 1: print(1)
case 2: print(2)
case 3..<5: print(3..<5)
default: break
}
これに砂糖:
if 1 ~= x { print(1) }
else if 2 ~= x { print(2) }
else if 3..<5 ~= x { print(3..<5) }
else { }
標準ライブラリのリファレンスを見ると、~=
がオーバーロードして何をすべきかを正確に知ることができます。含まれているのは範囲マッチングであり、等値化可能なものと同等です。(含まれていないのは、std libの関数ではなく言語機能である列挙型と大文字のマッチングです)
左側のまっすぐなブール値と一致しないことがわかります。これらの種類の比較では、whereステートメントを追加する必要があります。
~=
自分でオペレーターをオーバーロードしない限り... (これは一般に推奨されません)1つの可能性は次のようなものです。
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ステートメントは次のようになります。
switch someVar {
case 0< : print("Bigger than 0")
case 0 : print("0")
default : print("Less than 0")
}
さて、あなたはおそらくこの種のものを実際に使用すべきではありません:それは少し危険です。あなたは(おそらく)そのwhere
声明にこだわる方が良いでしょう。とはいえ、switchステートメントパターン
switch x {
case negative:
case 0:
case positive:
}
または
switch x {
case lessThan(someNumber):
case someNumber:
case greaterThan(someNumber):
}
検討する価値があるのに十分一般的なようです。
これは、範囲でどのように見えるかです
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"
}
<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
}
X_MAX
.greatestFiniteMagnitude
Double.greatestFiniteMagnitude
CGFloat.greatestFiniteMagnitude
case 0..< .greatestFiniteMagnitude
someVar
var timeLeft = 100
switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }
はなぜ <=
ですか?イコールなしで書いた場合、動作します。おかげで
someVar
だったInt
と私がしなければならなかったDouble(
... `それを動作させるために)SOMEVARを
Swift 4が問題に対処できてうれしい:
3での回避策として、次のことを行いました。
switch translation.x {
case 0..<200:
print(translation.x, slideLimit)
case -200..<0:
print(translation.x, slideLimit)
default:
break
}
機能するが理想的ではない