日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Swift?Access?Control訪問控制與斷言詳細介紹_Swift

作者:撲騰的蛾子 ? 更新時間: 2022-11-05 編程語言

訪問控制(Access Control)

1、在訪問權限控制這塊,Swift提供了5個不同的訪問級別(以下是從高到低排序,實體指被訪問級別修飾的內容)

  • open:允許在定義實體的模塊、其他模塊中訪問,允許其他莫模塊進行繼承、重寫(open只能用在類、類成員上)
  • public:允許在定義實體的模塊、其他模塊中訪問,不允許其他模塊進行繼承、重寫
  • internal:只允許在定義實體的模塊中訪問,不允許在其他模塊中訪問
  • fileprivate:只允許在定義實體的源文件中訪問
  • private:只允許在定義實體的封閉聲明中訪問

2、絕大部分實體默認都是internal級別

訪問級別的使用準則

1、一個實體不可以被更低訪問級別的實體定義,比如

  • 變量\常量類型 >= 變量\常量
  • 參數類型、返回值類型 >= 函數
  • 父類 >= 子類
  • ……

元組類型

1、元組類型的訪問界別是所有成員類型最低的那個

internal struct Dog {}
fileprivate class Person {}
 
//(Dog, Person)的訪問級別是fileprivate
fileprivate var data1: (Dog, Person)
private var data2: (Dog, Person)

泛型類型

1、泛型類型的訪問級別是 類型的訪問級別 以及 所有泛型類型參數的訪問級別 中最低的那個

成員、嵌套類型

1、類型的訪問級別會影響成員(屬性、方法、初始化器、下標)嵌套類型的默認訪問級別

  • 一般情況下,類型為private或fileprivate,那么成員\嵌套類型默認也是private或fileprivate
  • 一般情況下,類型為internal或public,那么成員\嵌套類型默認是internal

2、直接在全局作用域下定義的private等價于fileprivate

private struct Dog {
    var age: Int = 0
    func run() {}
}
fileprivate struct Person {
    var dog: Dog = Dog()
    mutating func walk() {
        dog.run()
        dog.age = 1
    }
}

3、子類重寫的成員訪問級別必須 >= 父類的成員訪問級別

getter與setter

1、getter、setter默認自動接收他們所屬環境的訪問級別

2、可以給setter單獨設置一個比getter更低的訪問級別,用以限制寫的權限

fileprivate(set) public var num = 10
class Person {
    private(set) var age = 0
    fileprivate(set) public var weight: Int {
        set {}
        get { 10 }
    }
    internal(set) public subscript(index: Int) -> Int {
        set {}
        get { index }
    }
}

初始化器

1、如果一個public類想在另一個模塊調用編譯生成的默認無參初始化器,必須顯式提供public的無參初始化器

因為public類的默認初始化器時internal級別的

2、required初始化器必須跟他所屬類擁有相同的訪問級別

3、如果結構體有private\fileprivate的存儲實例屬性,那么它的成員初始化器也是private\fileprivate

否則默認就是internal

枚舉類型的case

1、不能給enum的每個case單獨設置訪問級別

2、每個case自動接收enum的訪問級別

public enum定義的case也是public

協議

1、協議中定義的要求(方法)自動接收協議的訪問級別,不能單獨設置訪問級別

public協議定義的要求(方法)也是public

2、協議實現的訪問級別必須 >= 類型的訪問級別,或者 >= 協議的訪問級別

擴展

1、如果有顯式設置擴展的訪問級別,擴展添加的成員自動接收擴展的訪問級別

2、如果沒有顯式設置擴展的訪問級別,擴展添加的成員的默認訪問級別,跟直接在類型中定義的成員一樣

3、可以單獨給擴展添加的成員設置訪問級別

4、不能給用于遵守協議的擴展顯式設置擴展的訪問級別

5、在同一文件中的擴展,可以寫成類似多個部分的類型聲明

  • 在原本的聲明中聲明一個私有成員,可以在同一文件的擴展中訪問他
  • 在擴展中聲明一個私有成員,可以在同一文件的其他擴展中、原本生明中訪問他

將方法賦值給var\let

1、方法也可以像函數那樣,賦值給一個let或者var

struct Person {
    var age: Int
    func run(_ v: Int) {
        print("func run", age, v)
    }
}
var fn: (Person) -> (Int) -> () = Person.run(_:)
fn(Person(age: 10))(20)

一些補充知識

CustomStringConvertible

1、遵守CustomStringConvertible、CustomDebugStringConvertible協議,都可以自定義實例的打印字符串

class Person: CustomStringConvertible, CustomDebugStringConvertible {
    var age = 0
    var description: String {
        "person_\(age)"
    }
    var debugDescription: String {
        "debug_person_\(age)"
    }
}

2、print調用的是CustomStringConvertible協議的description

3、debugPrint、po調用的是CustomDebugStringConvertible協議的debugDescription

Self

1、Self一般用作返回值類型,限定返回值跟方法調用者必須是同一類型(也可以作為參數類型)

2、Self代表當前類型

class Person {
    var age = 1
    static var count = 2
    func run() {
        print(self.age) // 1
        print(Self.count) // 2
    }
}

assert (斷言)

1、很多編程語言都有斷言機制:不符合指定條件就拋出運行時錯誤,常用語調試(Debug)階段的條件判斷

2、默認情況下,Swift的斷言只會在debug模式下生效,release模式下會忽略

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

fatalError

1、如果遇到嚴重問題,希望結束程序運行時,可以直接使用fatalError函數拋出錯誤(這是無法通過do-catch捕捉的錯誤)

2、使用了fatalError函數,就不需要再寫return

func test(_ num: Int) -> Int {
    if num >= 0 {
        return 1
    }
    fatalError("num不能小于0")
}

3、在某些不得不實現,但不希望別人調用的方法,可以考慮內部使用fatalError函數

class Person {
    required init() {}
}
class Student: Person {
    required init() {
        fatalError("don't call Student init()")
    }
    init(score: Int) {}
}
var stu1 = Student(score: 98)
var stu2 = Student()

原文鏈接:https://blog.csdn.net/run_in_road/article/details/126691679

欄目分類
最近更新