字面量
- 常见的字面量的默认类型(标准库中已有定义)
- public typealias IntergerLiteralType = Int
- public typealias FloatLiteralType = Double
- public typealias BooleanLiteralType = Bool
- public typealias StringLiteralType = String
//可以通过typealias修改字面量的默认类型 但不建议修改
typealias FloatLiteralType = Float
typealias IntergerLiteralType = UInt8
var age = 10//UInt8
var height = 1.68//Float
- Swift绝大部分类型,都支持直接通过字面量进行初始化
- Bool、Int、Float、Double、String、Array、Dictionary、Set、Optional等...
字面量协议
- Swift自带类型之所以能够通过字面量进行初始化,是因为它们遵守了对应的协议
- Bool : ExpressibleByBooleanLiteral
- Int : ExpressibleByIntegerLiteral
- Float 、Double : ExpressibleByFloatLiteral、ExpressibleByIntegerLiteral
- Dictionary : ExpressibleByDictionaryLiteral
- String : ExpressibleByStringLiteral
- Array、Set : ExpressibleByArrayLiteral
- Optional : ExpressibleByNilLiteral
字面量协议的应用
//使用bool字面量初始化Int类型
extension Int : ExpressibleByBooleanLiteral{
public init(booleanLiteral value: Bool) {
self = value ? 1 : 0
}
}
var num: Int = true
print(num)//输出: 1
class Student : ExpressibleByIntegerLiteral,ExpressibleByFloatLiteral,ExpressibleByStringLiteral, CustomStringConvertible{
var name: String = ""
var score:Double = 0
required init(floatLiteral value: Double) {
self.score = value
}
required init(stringLiteral value: String) {
self.name = value
}
required init(integerLiteral value: Int) {
self.score = Double(value)
}
required init(unicodeScalarLiteral value: String){
self.name = value
}
required init(extendedGraphemeClusterLiteral value: String){
self.name = value
}
var description: String{
"name = \(name),score = \(score)"
}
}
var stu:Student = 90
print(stu)//输出:name = ,score = 90.0
stu = 98.5
print(stu)//输出:name = ,score = 98.5
stu = "Jack"
print(stu)//输出:name = Jack,score = 0.0
struct Point {
var x = 0.0,y = 0.0
}
extension Point : ExpressibleByArrayLiteral,ExpressibleByDictionaryLiteral{
typealias Key = String
typealias Value = Double
typealias ArrayLiteralElement = Double
init(arrayLiteral elements: Self.ArrayLiteralElement...) {
guard elements.count > 0 else {
return
}
self.x = elements[0]
guard elements.count > 1 else {
return
}
self.y = elements[1]
}
init(dictionaryLiteral elements: (Self.Key, Self.Value)...) {
for (k, v) in elements {
if k == "x" {
self.x = v
}
else if k == "y" {
self.y = v
}
}
}
}
var p: Point = [10.5,20.5,30.5]
print(p)//输出:Point(x: 10.5, y: 20.5)
p = ["x" : 11, "y" : 22]
print(p)//输出:Point(x: 11.0, y: 22.0)
模式匹配
什么是模式?
- 模式是用于匹配的规则,比如Switch的case、捕捉错误的catch、if\guard\where\for语句条件等
Swift中的模式
- 通配符模式(Wildcard Pattern)
- 标识符模式(Identifier Pattern)
- 值绑定模式(Value-Binding Pattern)
- 元组模式(Tuple Pattern)
- 枚举case模式(Enumeration case Pattern)
- 可选模式(Optional Pattern)
- 类型转换模式(Type-Casting Pattern)
- 表达式模式(Expression Pattern)
- 通配符模式
enum Life{
case human(String,Int?)
case animal(String,Int?)
}
func check(_ life:Life){
switch life {
case .human(let name, _)://后面的元素不管
print("human",name)
case .animal(let name, _?)://必须为非nil值,但是不使用
print("animal name",name)
default:
print("other")
}
}
var value1 = Life.human("Jack", nil)
check(value1)//输出:human Jack
value1 = Life.animal("Dog", nil)
check(value1)//输出:other
value1 = Life.animal("Cat", 5)
check(value1)//输出:animal name Cat
- 通配符模式标识符模式
var value1 = 10
- 值绑定模式
let point = (3, 2)
switch point {
case let (x,y):
print("(\(x), \(y))")
}
- 元组模式
let points = [(0, 0), (2, 2), (3, 3)]
for (_,y) in points{
print(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")
}
- 枚举case模式
let age = 3
//原来的写法
if age >= 0 && age <= 9{
print("age is [0,9]")
}
//枚举case模式
if case 0...9 = age{
print("age is [0,9]")
}
//switch
switch age {
case 0...9:
print("age is [0,9]")
default:
print("")
}
//guard case 该语句需要在函数中使用
guard case 0...9 = age else {
return
}
print("age is [0,9]")
let age : [Int?] = [2, 3, nil, 10]
for case nil in age{//age中的每个元素和nil匹配
print("有nil值")
break
}
let points = [(1,2),(2,3),(2,0),(3,3)]
for case let (x,0) in points{
print("\(x)")
}//2
- 可选模式
- if case语句等价于 只有一个case的switch语句
let age: Int? = 42
if case .some(let x) = age {
print(x)
}
if case let x? = age {
print(x)
}
let ages:[Int?] = [nil, 2, 3, nil, 5]
for case let age? in ages{
print(age)
}
//与上面的效果是等价的
for item in ages{
if let age = item {
print(age)
}
}
func check(_ num:UInt?){
switch num {
case (0...5)?:
print("match in 0...5")
case _?:
print("other value, not match in 2...5")
case _:
print("nil")
}
}
check(0)//输出:match in 0...5
check(4)//输出:match in 0...5
check(7)//输出:other value, not match in 2...5
check(nil)//输出:nil
- 类型转换模式
let num :Any = 6
switch num {
case is Int:
//编译器依然认为num是Any类型
print("is Int",num)
//case let n as Int:
// print("as Int",n)
default:
break
}
class Animal {
func eat() {
print(type(of: self),"eat")
}
}
class Dog: Animal {
func run() {
print(type(of: self),"run")
}
}
class Cat: Animal {
func jump() {
print(type(of: self),"jump")
}
}
func check(_ animal:Animal) {
switch animal {
case let dog as Dog://将animal强转为Dog类型
dog.eat()
dog.run()
case is Cat:
animal.eat()
animal.jump()//报错 animal会被认为是Animal实例
//(animal as? Cat)?.jump()
default:
break
}
}
var ani = Animal()
check(ani)
var dog = Dog()
check(dog)
var cat = Cat()
check(cat)
- 表达式模式
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
自定义表达式模式
struct Student {
var score = 0,name = ""
static func ~= (pattern: Int, values: Student) -> Bool {
values.score >= pattern
}
static func ~= (pattern: ClosedRange<Int>, values: Student) -> Bool {
pattern.contains(values.score)
}
static func ~= (pattern: Range<Int>, values: Student) -> Bool {
pattern.contains(values.score)
}
}
var stu = Student(score: 75, name: "Jack")
switch stu{
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
var info = (Student(score: 70, name: "Jack"),"及格")
switch info{
case let (60, text):
print(text)
default:
break
}//及格
extension String{
static func ~= (pattern: (String) -> Bool, values: String) -> Bool {
pattern(values)
}
}
func hasPrefix(_ prefix:String) -> ((String) -> Bool) {
{ $0.hasPrefix(prefix) }
}
func hasSuffix(_ suffix:String) -> ((String) -> Bool) {
{ $0.hasSuffix(suffix) }
}
var str = "Jack"
switch str {
case hasPrefix("J"),hasSuffix("k"):
print("以J开头,以k结尾")
default:
break
}//以J开头,以k结尾
func isEven(_ i: Int) -> Bool{
i % 2 == 0
}
func isOdd(_ i: Int) -> Bool{
i % 2 != 0
}
extension Int {
static func ~= (pattern: (Int) -> Bool, value: Int) -> Bool{
pattern(value)
}
}
var age = 9
switch age {
case isEven:
print("偶数")
case isOdd:
print("奇数")
default:
print("其他")
}//奇数
prefix operator ~>
prefix operator ~>=
prefix operator ~<
prefix operator ~<=
prefix func ~> (_ i: Int) -> ((Int) -> Bool){
{ $0 > i }
}
prefix func ~>= (_ i: Int) -> ((Int) -> Bool){
{ $0 >= i }
}
prefix func ~< (_ i: Int) -> ((Int) -> Bool){
{ $0 < i }
}
prefix func ~<= (_ i: Int) -> ((Int) -> Bool){
{ $0 <= i }
}
extension Int{
static func ~= (pattern:(Int) -> Bool,values: Int) -> Bool{
pattern(values)
}
}
var age = 9
switch age {
case ~>=0:
print("1")
case ~>10:
print("2")
default:
break
}//1
where
//以前举过的例子
var data = (10, "Jack")
switch data {
case let (age, _) where age > 10:
print(data.1,"age > 10")
case let (age, _) where age > 0:
print(data.1,"age > 0")
default:
break
}
var ages = [10, 20, 34, 59]
for age in ages where age > 20{
print(age)
}
protocol Stackable {
associatedtype Element
}
protocol Container {
associatedtype Stack : Stackable where Stack.Element : Equatable
}
func equal<S1 : Stackable,S2 : Stackable>(_ s1: S1, _ s2: S2) -> Bool where S1.Element == S2.Element,S1.Element :Equatable{
return false
}
extension Container where Self.Stack.Element : Hashable{
}