ฉันคุ้นเคยกับswitch
ข้อความใน Swift แต่สงสัยว่าจะแทนที่โค้ดนี้ด้วยswitch
:
if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
ฉันคุ้นเคยกับswitch
ข้อความใน Swift แต่สงสัยว่าจะแทนที่โค้ดนี้ด้วยswitch
:
if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
คำตอบ:
นี่คือวิธีหนึ่ง สมมติว่า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
}
Desugars ถึงสิ่งนี้:
if 1 ~= x { print(1) }
else if 2 ~= x { print(2) }
else if 3..<5 ~= x { print(3..<5) }
else { }
หากคุณดูที่การอ้างอิงไลบรารีมาตรฐานมันสามารถบอกคุณได้อย่างชัดเจนว่าสิ่งใดที่~=
มากไปที่ต้องทำ : รวมคือการจับคู่ช่วงและการเทียบเคียงสิ่งที่เท่าเทียม (ไม่รวมคือการจับคู่กรณีซึ่งเป็นคุณสมบัติภาษามากกว่าฟังก์ชั่นใน std lib)
คุณจะเห็นว่ามันไม่ตรงกับบูลีนทางด้านซ้ายมือ สำหรับการเปรียบเทียบแบบนั้นคุณต้องเพิ่มคำสั่ง 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
ฟังก์ชั่น นอกจากคุณจะโอเวอร์โหลดโอเปอเรเตอร์บางตัวมากเกินไป ...
คุณสามารถโอเวอร์โหลดโอเปอเรเตอร์ของ infix ปกติเพื่อให้เป็นคำนำหน้า curried หรือโอเปอเรเตอร์ postfix นี่คือตัวอย่าง:
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
คำแถลง ที่กล่าวว่ารูปแบบงบเปลี่ยนของ
switch 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:
ที่นี่เป็นทางเลือกสำหรับผู้ที่เป็นsomeVar
Int
switch someVar{
case Int.min...0: // do something
case 0: // do something
default: // do something
}
และนี่ก็เป็นอีกทางเลือกหนึ่งสำหรับผู้ที่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"
}
การ<0
แสดงออกไม่ทำงาน (อีกต่อไป?) ดังนั้นฉันจึงลงเอยด้วยสิ่งนี้:
สวิฟท์ 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") }
เหตุใดตัว <=
ดำเนินการจึงไม่ได้รับการยอมรับ ถ้าฉันเขียนโดยไม่เท่ากันมันใช้งานได้ ขอบคุณ
case 0...7200:
ตัวดำเนินการ<=
เป็นตัวดำเนินการเปรียบเทียบ ในสวิตช์คุณสามารถใช้โอเปอเรเตอร์ช่วง(ดูเอกสาร)
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
}
ใช้งานได้ แต่ไม่เหมาะ