字面量
- 常見的字面量的默認(rèn)類型(標(biāo)準(zhǔn)庫(kù)中已有定義)
- public typealias IntergerLiteralType = Int
- public typealias FloatLiteralType = Double
- public typealias BooleanLiteralType = Bool
- public typealias StringLiteralType = String
//可以通過typealias修改字面量的默認(rèn)類型 但不建議修改
typealias FloatLiteralType = Float
typealias IntergerLiteralType = UInt8
var age = 10//UInt8
var height = 1.68//Float
- Swift絕大部分類型友浸,都支持直接通過字面量進(jìn)行初始化
- Bool、Int偏窝、Float收恢、Double、String祭往、Array伦意、Dictionary、Set链沼、Optional等...
字面量協(xié)議
- Swift自帶類型之所以能夠通過字面量進(jìn)行初始化默赂,是因?yàn)樗鼈冏袷亓藢?duì)應(yīng)的協(xié)議
- Bool : ExpressibleByBooleanLiteral
- Int : ExpressibleByIntegerLiteral
- Float 、Double : ExpressibleByFloatLiteral括勺、ExpressibleByIntegerLiteral
- Dictionary : ExpressibleByDictionaryLiteral
- String : ExpressibleByStringLiteral
- Array缆八、Set : ExpressibleByArrayLiteral
- Optional : ExpressibleByNilLiteral
字面量協(xié)議的應(yīng)用
//使用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)
模式匹配
什么是模式?
- 模式是用于匹配的規(guī)則疾捍,比如Switch的case奈辰、捕捉錯(cuò)誤的catch、if\guard\where\for語(yǔ)句條件等
Swift中的模式
- 通配符模式(Wildcard Pattern)
- 標(biāo)識(shí)符模式(Identifier Pattern)
- 值綁定模式(Value-Binding Pattern)
- 元組模式(Tuple Pattern)
- 枚舉case模式(Enumeration case Pattern)
- 可選模式(Optional Pattern)
- 類型轉(zhuǎn)換模式(Type-Casting Pattern)
- 表達(dá)式模式(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
- 通配符模式標(biāo)識(shí)符模式
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 該語(yǔ)句需要在函數(shù)中使用
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中的每個(gè)元素和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語(yǔ)句等價(jià)于 只有一個(gè)case的switch語(yǔ)句
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)
}
//與上面的效果是等價(jià)的
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
- 類型轉(zhuǎn)換模式
let num :Any = 6
switch num {
case is Int:
//編譯器依然認(rèn)為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強(qiáng)轉(zhuǎn)為Dog類型
dog.eat()
dog.run()
case is Cat:
animal.eat()
animal.jump()//報(bào)錯(cuò) animal會(huì)被認(rèn)為是Animal實(shí)例
//(animal as? Cat)?.jump()
default:
break
}
}
var ani = Animal()
check(ani)
var dog = Dog()
check(dog)
var cat = Cat()
check(cat)
- 表達(dá)式模式
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
自定義表達(dá)式模式
- 可以通過重載運(yùn)算符,自定義表達(dá)式模式的匹配規(guī)則
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結(jié)尾")
default:
break
}//以J開頭瑟啃,以k結(jié)尾
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("偶數(shù)")
case isOdd:
print("奇數(shù)")
default:
print("其他")
}//奇數(shù)
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{
}