字面量(Literal Type)就是基本类型的常量值。 比如: 10、false、“Jack"就是字面量
var age = 10
var isRed = false
var name = "Jack"
而如果类实现了对应的字面量协议后,就可以用字面量来初始化对象了。 常用的字面量协议有:
- Bool: ExpressibleByBooleanLiteral
- Int: ExpressibleByIntegerLiteral
- Float、Double: ExpressibleByIntegerLiteral、ExpressibleByFloatLiteral
- String: ExpressibleByStringLiteral
- Array、Set: ExpressibleByArrayLiteral
- Dictionary: ExpressibleByDictionaryLiteral
- Optional: ExpressibleByNilLiteral
样例代码:
class LiteralTypeClass : ExpressibleByBooleanLiteral {
var boolValue : Bool
//实现了bool的字面量协议,可以用bool来初始化了
required init(booleanLiteral value: BooleanLiteralType) {
boolValue = value
}
}
let obj : LiteralTypeClass = false
模式是用于匹配的规则,比如switch的case、捕捉错误的catch、if\guard\while\for语句的条件等。
1.1 _ 匹配任何值 1.2 _? 匹配非nil值
样例代码:
enum Life {
case human(name: String, age: Int?)
case animal(name: String, age: Int?)
}
func check(_ life: Life) {
switch life {
case .human(let name, _): //case 1
print("human", name)
case .animal(let name, _?): //case 2
print("animal", name)
default: //case 3
print("other")
}
}
check(.human(name: "Rose", age: 20)) // 满足case 1
check(.human(name: "Jack", age: nil)) //满足 case 1
check(.animal(name: "Dog", age: 5)) // 满足case 2
check(.animal(name: "Cat", age: nil)) // 满足 case3
let point = (3, 2)
switch point {
case let (x, y):
print("The point is at (\(x), \(y).")
}
let name: String? = "jack"
let age = 18
let info: Any = [1, 2]
switch (name, age, info) {
case (_?, _, _ as String):
print("case")
default:
print("default")
} // default
if case语句等价于只有1个case的switch语句
let age = 2
// 枚举Case模式
if case 0...9 = age {
print("[0, 9]")
}
let ages: [Int?] = [2, 3, nil, 5]
for case nil in ages {
print("有nil值")
break
} // 有nil值
let points = [(1, 0), (2, 1), (3, 0)]
for case let (x, 0) in points {
print(x)
} // 1 3
let ages: [Int?] = [nil, 2, 3, nil, 5]
for case let age? in ages {
print(age)
} // 2 3 5
// 同上面效果等价
let ages: [Int?] = [nil, 2, 3, nil, 5]
for item in ages {
if let age = item {
print(age)
}
}
class Animal {
func eat() {
print(type(of: self), "eat")
}
}
class Dog: Animal {
}
class Cat: Animal {
}
func check(_ animal: Animal) {
switch animal {
case let dog as Dog:
dog.eat()
dog.run()
case is Cat:
animal.eat()
default: break
}
}
check(Dog()) // Dog eat, Dog run
check(Cat()) // Cat eat
表达式用在 case 中
let point = (1, 2)
switch point {
case (0, 0):
print("(0, 0) is at the origin.")
case (-2...2, -2...2):
print("(\(point.0), \(point.1) is near the origin.")
default:
print("The point is at (\(point.0), \(point.1).")
} // (1, 2) is near the origin.
重载 ~= 运算符,可以实现 case 里的字定义条件匹配。
下面是数值类型以及区间的自定义匹配实现。
struct Student {
var score = 0, name = ""
// pattern:放的是case后面的值
// value:放的是switch后面的值
//与Int 值的匹配判断
static func ~= (pattern: Int, value: Student) -> Bool {
value.score >= pattern
}
//与 0…5 此类区间的匹配判断
static func ~= (pattern: ClosedRange<Int>, value: Student) -> Bool {
pattern.contains(value.score)
}
//与 0..<5 此类区间的匹配判断
static func ~= (pattern: Range<Int>, value: Student) -> Bool {
pattern.contains(value.score)
}
//与Double值的匹配判断
static func ~= (pattern: Double, value : Student) -> Bool {
return Double(value.score) > pattern
}
}
var stu = Student(score: 75, name: "Jack")
switch stu {
case 61.1: print("DOuble???")
case 100: print(">= 100")
case 90: print(">= 90")
case 80..<90: print("[80, 90]")
case 60...79: print("[60, 79]")
case 0: print(">= 0")
default: break
} // [60, 79]
if case 60 = stu {
print(">= 60")
} // >= 60
打印结果是: DOuble??? >= 60
extension String {
static func ~= (pattern: (String) -> Bool, value: String) -> Bool {
pattern(value)
}
}
func hasPrefix(_ prefix: String) -> ((String) -> Bool) {
{ $0.hasPrefix(prefix) }
}
func hasSuffix(_ suffix: String) -> ((String) -> Bool) {
{ $0.hasSuffix(suffix) }
}
var str = "jack"
switch str {
//这里 hasPrefix和 hasSuffix 返回的closure 就是重载的 ~= 运算符的 pattern 参数
case hasPrefix("j"), hasSuffix("k"):
print("以j开头,以k结尾")
default: break
} // 以j开头,以k结尾