前言
switch 语句是大部分计算机语言的基础语句之一,在做枚举判断的时候有着得天独厚的优势(代码缩进比较漂亮?)。今天来初步学习一下在 swift 中 switch 的常用用法。
用法
OC 和 Swift 比较
在 OC 语言中,switch 是不可以判断对象类型的。就连基础数据类型里面也只可以判断整型。而在 Swift 中就要灵活很多。下面简单列举一下 switch 在 OC 和 Swift 中的区别:
OC | Swift | |
---|---|---|
break | 需要写 | 不需要写 |
default位置 | 任意位置 | 最后 |
穿透 | 不写break | fallthrough关键词 |
判断类型 | 整型 | 多种多样 |
在 Swift 中的常用用法
- 判断 String 类型
let level: String = "A"
switch level {
case "A":
print("优秀")
case "B":
print("良好")
case "C":
print("一般般")
default:
print("不合格")
}
// 输出结果: 优秀
- 判断 浮点型数据
let source: Double = 61.5
switch source {
case 90:
print("优秀")
case 70:
print("良好")
case 61.5:
print("一般般")
default:
print("不合格")
}
// 输出结果: 一般般
- 判断区间和元组 在这里需要说明一下,区间和元组是可以嵌套使用的。
let tuple = (10, 25)
switch tuple {
case (10, 10):
print("(10 10)")
case (10, 25):
print("Good")
default:
print("没有命中")
}
let section = 38
switch section {
case 1...10:
print("(10 10)")
case 30...40:
print("Good")
default:
print("没有命中")
}
switch tuple {
case (1...10, 10...20):
print("Bad")
case (1...10, 20...30):
print("Good")
default:
print("没有命中")
}
// 输出结果:
Good
Good
Good
- 值绑定和条件判断
class TestObject {
var name: String = ""
}
let object = TestObject()
object.name = "Tony"
switch object {
case let tom where tom.name == "Tom":
print("object is Tom")
case let tony where tony.name == "Tony":
print("object is Tony")
case let normal where normal.name == "":
print("object is normal")
default:
print("不知道是谁")
}
// 输出结果: object is Tony
在上面的这些用法中,最后一个 值绑定和条件判断 是我认为最具有扩展性的, 我们可以通过这样的机制实现类似 SwiftyJSON 中对 Any 类型解包的操作。
switch unwrap(newValue) {
case let number as NSNumber:
if number.isBool {
type = .bool
rawBool = number.boolValue
} else {
type = .number
rawNumber = number
}
case let string as String:
type = .string
rawString = string
case _ as NSNull:
type = .null
case nil:
type = .null
case let array as [Any]:
type = .array
rawArray = array
case let dictionary as [String: Any]:
type = .dictionary
rawDictionary = dictionary
default:
type = .unknown
error = SwiftyJSONError.unsupportedType
}
写到这里基本已经结束了,但是还遗留一个小疑惑。在实际开发过程中,自定义对象的使用非常普遍,switch 可以判断自定义对象是否相等吗?
让我们来验证一下,我们把最后一个示例改动一下:
class TestObject: UIView {
var name: String = ""
}
let obj = TestObject()
let obj1 = TestObject()
let obj2 = TestObject()
switch obj {
case obj1:
print("same as obj1")
case obj2:
print("same as obj2")
default:
print("diff")
}
// 执行结果: diff
如果 switch 可以判断自定义对象是否相等,那么我们可以推测出执行的结果应该是命中 obj1 的 case,但实际的执行结果是走到了 default 分支。
我们再改动一下上面的示例:
class TestObject: Equatable {
static func == (lhs: TestObject, rhs: TestObject) -> Bool {
if lhs.name == rhs.name {
return true
}
return false
}
static func ~= (lhs: TestObject, rhs: TestObject) -> Bool {
return lhs == rhs
}
var name: String = ""
}
let obj = TestObject()
let obj1 = TestObject()
let obj2 = TestObject()
switch obj {
case obj1:
print("same as obj1")
case obj2:
print("same as obj2")
default:
print("diff")
}
// 执行结果: same as obj1
这时候我们发现,程序可以正确命中 obj1 的 case 了。
对比上面两个示例,经过调试我们可以发现,在 swift 中,switch 的 case 判断逻辑是通过标准库的~=
运算符来实现的。也就是说,只要实现了这个运算符,就可以通过 switch 判断连个自定义对象是否相等。
最后
以上就是本篇的全部内容,又水了一篇伪技术 Blog,文中势必会有一些错误和遗漏,欢迎斧正~
参考
https://www.jianshu.com/p/2aa5fd8635d4
https://juejin.im/post/5a309c556fb9a0451f30ec97
网友评论