swift

Swift5.x入门14--协议,Any,as,元类型,Erro

2021-08-02  本文已影响0人  YanZi_33
import Foundation

protocol Drawable {
    func draw() -> Void
    var x: Int { get set }
    var y: Int { get }
    subscript(index: Int) -> Int { get set }
}

static 与 class

mutating

init

protocol Drawable1 {
    init(x: Int,y: Int)
}

class Point : Drawable1 {
    required init(x: Int, y: Int) {
        
    }
}

final class Size : Drawable1{
    init(x: Int, y: Int) {
        
    }
}
protocol Livable {
    init(age: Int)
}

class Person {
    init(age: Int) {
        
    }
}

class Student : Person,Livable {
    required override init(age: Int) {
        super.init(age: age)
    }
}

init,init?,init!

protocol Livable {
    init()
    init?(age: Int)
    init!(no: Int)
}

class Person : Livable {
    required init() {} //可二选一
    required init!() {}
    
    required init?(age: Int) {} //可三选一
    required init!(age: Int) {}
    required init(age: Int) {}
    
    required init!(no: Int) {} //可三选一
    required init?(no: Int) {}
    required init(no: Int) {}
}

协议的继承

protocol Runable {
    func run()
}


protocol Livable : Runable{
    func sleep()
}

class Person : Livable {
    func run() {
        
    }
    func sleep() {
        
    }
}

协议的组合

protocol Livable {}
protocol Runable {}
class Person {}

//参数:接收Person或其子类的实例
func fn0(obj: Person) {}

//参数:接收遵守Livable协议的实例
func fn1(obj: Livable) {}

//参数:接收同时遵守Livable与Runable协议的实例
func fn2(obj: Livable & Runable) {}

//参数:接收同时遵守Livable与Runable协议的实例且是Person或其子类的实例
func fn3(obj: Person & Livable & Runable) {}

typealias RealPerson = Person & Livable & Runable
func fn4(obj: RealPerson) {}

CaseIterable协议

enum Season : CaseIterable {
    case spring,summer,autum,winter
}

//Season.allCases协议属性
let seasons = Season.allCases
print(seasons.count) //4

for season in seasons {
    print(season)
}

CustomStringConvertible协议

class Person : CustomStringConvertible {
    var age: Int
    var name: String
    init(age: Int,name: String) {
        self.age = age
        self.name = name
    }
    //实现协议方法
    var description: String {
        "age = \(age),name = \(name)"
    }
}

var person = Person(age: 31, name: "liyanyan")
print(person) //age = 31,name = liyanyan

Any 与 AnyObject

is,as,as?,as!

protocol Runnable {
    func run()
}

class Person  {
    
}

class Student : Person, Runnable{
    func run() {
        print("Student run")
    }
    func study() {
        print("Student study")
    }
}

//var stu: Any = 10
//print(stu is Int) //true
//stu = "li"
//print(stu is String) //true
//stu = Student()
//print(stu is Person) //true
//print(stu is Student)//true
//print(stu is Runnable) //true


var stu: Any = 10
//第一个问号:表示强制转换可能失败
//第二个问号:可选链
(stu as? Student)?.study() //no
stu = Student()
(stu as? Student)?.study() //yes
(stu as! Student).study()  //yes
(stu as? Student)?.run()   //yes

//数组 存放任意类型
var data = [Any]()
data.append(Int("123") as Any)

.self,.Type,AnyClass,type(of: T)

import Foundation

let intType: Int.Type = Int.self
let floatType: Float.Type = Float.self

print(intType) //Int
print(floatType) //Float
class YYAnimal {
    
}

class YYPerson: YYAnimal {
    
}

let type1: YYAnimal.Type = YYAnimal.self //success
let type2: YYAnimal.Type = YYPerson.self //success
let type3: YYPerson.Type = YYAnimal.self //报错
class Person {
    
}
var person: Person = Person()
var pType: Person.Type = Person.self
Snip20210803_108.png

Self

protocol Runnable {
    func test() -> Self
}

class Person : Runnable{
    required init() {}
    func test() -> Self {
        //Person.init() 返回实例对象
        type(of: self).init()
    }
}
class Person {
    var age: Int = 30
    static var cout: Int = 50
    func test() {
        print(self.age)
        print(Self.cout)
    }
}
class Person {
    static var age = 0
    static func run() {}
}

Person.age = 10
Person.run()

Person.self.age = 10
Person.self.run()

var p0 = Person()
var p1 = Person.self()
var p2 = Person.init()
var p3 = Person.self.init()

//var pType0 = Person
var pType1: Person.Type = Person.self

错误处理

自定义错误

enum MyError : Error {
    case illegaArg(String)
    case outOfBounds(Int,Int)
    case outOfMemory
}

func divide(num1: Int,num2: Int) throws -> Int {
    if num2 == 0 {
        throw MyError.illegaArg("0不能作为除数")
    }
    return num1 / num2
}

func test() {
    print("1")
    do {
        print("2")
        print(try divide(num1: 200, num2: 0))//后面的代码停止执行
        print("3")
    } catch let MyError.illegaArg(msg) {
        print("参数异常:",msg)
    }catch let MyError.outOfBounds(size, index){
        print("下标越界:","size = \(size)","index = \(index)")
    }catch MyError.outOfMemory{
        print("内存溢出")
    }catch{
        print("其他错我")
    }
    print("4")
}

test()

Error的处理

enum MyError : Error {
    case illegaArg(String)
    case outOfBounds(Int,Int)
    case outOfMemory
}

func divide(num1: Int,num2: Int) throws -> Int {
    if num2 == 0 {
        throw MyError.illegaArg("0不能作为除数")
    }
    return num1 / num2
}

func test() throws{
    print("1")
    print(try divide(num1: 200, num2: 0))
    print("2")
}

try test() //会闪退
enum MyError : Error {
    case illegaArg(String)
    case outOfBounds(Int,Int)
    case outOfMemory
}

func divide(num1: Int,num2: Int) throws -> Int {
    if num2 == 0 {
        throw MyError.illegaArg("0不能作为除数")
    }
    return num1 / num2
}

func test0() throws{
    print("1")
    try test1()
    print("2")
}

func test1() throws{
    print("3")
    try test2()
    print("4")
}

func test2() throws{
    print("5")
    print(try divide(num1: 200, num2: 0))
    print("6")
}

try test0() //会闪退

try?,try!

enum MyError : Error {
    case illegaArg(String)
    case outOfBounds(Int,Int)
    case outOfMemory
}

func divide(num1: Int,num2: Int) throws -> Int {
    if num2 == 0 {
        throw MyError.illegaArg("0不能作为除数")
    }
    return num1 / num2
}

func test2() {
    print("1")
    var result1 = try? divide(num1: 200, num2: 10) //Optional(2)
    var result2 = try? divide(num1: 200, num2: 0) //nil
    var reslut3 = try! divide(num1: 200, num2: 2) //Int 100
    print("2")
}
enum MyError : Error {
    case illegaArg(String)
    case outOfBounds(Int,Int)
    case outOfMemory
}

func divide(num1: Int,num2: Int) throws -> Int {
    if num2 == 0 {
        throw MyError.illegaArg("0不能作为除数")
    }
    return num1 / num2
}

var a = try? divide(num1: 200, num2: 0)

//如果抛出异常,b的赋值操作不会执行 则默认为nil
//如果不抛出异常 b的赋值操作会执行
var b: Int?
do {
    b = try divide(num1: 200, num2: 0)
}catch{
    
}

rethrows

enum MyError : Error {
    case illegaArg(String)
    case outOfBounds(Int,Int)
    case outOfMemory
}

func divide(num1: Int,num2: Int) throws -> Int {
    if num2 == 0 {
        throw MyError.illegaArg("0不能作为除数")
    }
    return num1 / num2
}

func exec(_ fn: (Int,Int) throws -> Int,_ num1: Int,_ num2: Int) rethrows{
    print(try fn(num1,num2))
}

try exec(divide, 20, 0)

defer

enum MyError : Error {
    case illegaArg(String)
    case outOfBounds(Int,Int)
    case outOfMemory
}

func divide(num1: Int,num2: Int) throws -> Int {
    if num2 == 0 {
        throw MyError.illegaArg("0不能作为除数")
    }
    return num1 / num2
}

func open(_ fileName: String) -> Int {
    print("open")
    return 0
}

func close(_ file: Int) -> Void {
    print("close")
}

func processFile(_ fileName: String) throws -> Void {
    let file = open(fileName)
    
    //use file
    //...
    
    try divide(num1: 100, num2: 0)
    
    close(file)
}

try processFile("test.txt")
func processFile(_ fileName: String) throws -> Void {
    let file = open(fileName)
    //当前函数执行完成之前,会执行defer语句中的代码
    defer {
        close(file)
    }
    //use file
    //...
    
    try divide(num1: 100, num2: 0)
}
func fn1() {
    print("fn1")
}

func fn2() {
    print("fn2")
}

func test() {
    defer {
        fn1()
    }
    
    defer {
        fn2()
    }
}

test() //fn2  fn1

断言(assert)

func divide(_ v1: Int,_ v2: Int) -> Int {
    assert(v2 != 0,"除数不能为0")
    return v1 / v2
}

fatalError

func test(_ num: Int) -> Int {
    if num >= 0 {
        return 1
    }
    fatalError("num不能小于0") //来到这里 会闪退
}
class Person {
    required init(){}
}

class Student : Person {
    var age: Int
    
    required init() {
        fatalError("不要调用这个初始化器")
    }
    init(age: Int) {
        self.age = age
    }
}

泛型

func swapValues<T>(num1: inout T,num2: inout T) -> Void {
    let temp = num1
    num1 = num2
    num2 = temp
}

var n1 = 10
var n2 = 20
swapValues(num1: &n1, num2: &n2)
print(n1)
print(n2)

var d1 = 10.0
var d2 = 20.0
swapValues(num1: &d1, num2: &d2)
print(d1)
print(d2)

var fn1: (inout Int,inout Int) -> () = swapValues
fn1(&n1,&n2)


var fn2: (inout Double,inout Double) -> () = swapValues
fn2(&d1,&d2)
class Stack<E> {
    var elements = [E]()
    func push(_ element: E) -> Void {
        elements.append(element)
    }
    func pop() -> E {
        elements.removeLast()
    }
    func top() -> E {
        elements.last!
    }
    func size() -> Int {
        elements.count
    }
}
 
//存储string的栈
var stringStack = Stack<String>()
//存储int的栈
var intStack = Stack<Int>()
//存储任意类型的栈
var anyStack = Stack<Any>()
func swapValues<T>(num1: inout T,num2: inout T) -> Void {
    let temp = num1
    num1 = num2
    num2 = temp
}

var n1 = 10
var n2 = 20
swapValues(num1: &n1, num2: &n2)

var d1 = 10.0
var d2 = 20.0
swapValues(num1: &d1, num2: &d2)
Snip20210803_109.png Snip20210803_110.png

关联类型

protocol Stackable {
    associatedtype Element //关联类型
    mutating func push(_ element: Element)
    mutating func pop() -> Element
    func top() -> Element
    func size() -> Int
}

class stringStack : Stackable {
    //给关联类型赋值真正要使用的类型
    //这行代码也可以不写,编译器也能正确确定要使用的类型
    typealias Element = String
    var elements = [String]()
    func push(_ element: String) {
        elements.append(element)
    }
    func pop() -> String {
        elements.removeLast()
    }
    
    func top() -> String {
        elements.last!
    }
    func size() -> Int {
        elements.count
    }
}

类型约束

protocol Runnable {
    
}

class Person {
    
}

func swapValues<T: Person & Runnable>(_ a: inout T,_ b: inout T) {
    (a,b) = (b,a)
}
protocol Stackable {
    associatedtype Element : Equatable
}

class Stack<E : Equatable> : Stackable {
    typealias Element = E
}

func equal<S1: Stackable,S2: Stackable>(_ s1: S1, _s2: S2) -> Bool
    where S1.Element == S2.Element,S1.Element : Hashable
{
    return false
}
protocol Runnable { }

class Person : Runnable { }

class Car : Runnable { }

func get(_ type: Int) -> Runnable {
    if type == 0 {
        return Person()
    }
    return Car()
}

var r1 = get(0)
var r2 = get(1)
protocol Runnable {
    associatedtype Speed
    var speed: Speed { get }
}

class Person : Runnable {
    var speed: Double { 0.0 }
}

class Car : Runnable {
    var speed: Int { 0 }
}

func get(_ type: Int) -> Runnable {
    if type == 0 {
        return Person()
    }
    return Car()
}

var r1 = get(0)
var r2 = get(1)
protocol Runnable {
    associatedtype Speed
    var speed: Speed { get }
}

class Person : Runnable {
    var speed: Double { 0.0 }
}

class Car : Runnable {
    var speed: Int { 0 }
}

func get<T: Runnable>(_ type: Int) -> T {
    if type == 0 {
        return Person() as! T
    }
    return Car() as! T
}

var r1: Person = get(0)
var r2: Car = get(1)
protocol Runnable {
    associatedtype Speed
    var speed: Speed { get }
}

class Person : Runnable {
    var speed: Double { 0.0 }
}

class Car : Runnable {
    var speed: Int { 0 }
}

func get(_ type: Int) -> some Runnable {
    return Car()
}

var r1 = get(0)
var r2 = get(1)

some

protocol Runnable {
    associatedtype Speed
}

class Person : Runnable {
    typealias Speed = Double
}

class Dog : Runnable {
    typealias Speed = Double
    
    var pet: some Runnable {
        return Dog()
    }
}
上一篇 下一篇

猜你喜欢

热点阅读