swift的數據類型到底是什麼尿性 (說點別人沒講明白的)

文初:

如果你對swift的些許瞭解只侷限在

  • swift中的類型使用struct取代class
  • 多了Optional可選類型

這些最基礎的認知,而對其底層設計的原因和原理了解甚少,那這篇文章會給你新的視角,讓你更好的理解和使用。
爲了讓你能更宏觀的理解swift在類型設計方面的初衷,本文會也會從更加宏觀的角度着手。

其實swift的類型,從大的層面有兩種類型:

  • Named Types
  • Compound Types

Named Types

其具體包含如下:

   * class 
   * struct 
        {
            * String
            * Int
            * Float
            * Bool
            * ...
        }
    * enum
    * protocol

swift類型的新特點(區別與OC):


* 沒有特定的根類型(No dedicated type root )
* 類型通過遵守協議的方式,而非繼承來實現擴展( Type conforms to protocols instead of heavy inheritance )
* 低耦合(Super loose coupling )
* 概念分離(Nice separation of concerns )
* 結構清晰(Clean architecture )

對比OC,所有的對象類型都繼承自NSObject,其本質是Class類型。
爲了保證繼承的完整性,又多出了meta class等概念。Class中通過繼承來實現的方法的擴展。

比如:NSArray及NSMutableArray類型
NSMutableArray是NSArray的子類。子類NSMutableArray特有的addObject:等方法是通過繼承NSArray,在子類中單獨實現。

OC通過繼承擴展方法

這種設計本身無可挑剔,但OC過於依賴繼承來實現方法的擴展,導致整個體系特別臃腫,過於耦合。

@interface AClass: NSObject

- (void)aMethod;
- (void)bMethod;

- (void)oneMethod;
- (void)twoMethod;

@end

//BClass想擁有aMethod和bMethod方法,不需要oneMethod和twoMethod,在OC一般都繼承實現
@interface BClass: AClass

@end

而swift不過度依賴Class,其擴展了Struct,Enum, Protocol,並給其更高的權限(可更加靈活的添加屬性,定義方法等),讓其變成一等公民。

swift底層是結構體,結構體不是對象類型,自然沒辦法通過繼承來實現方法擴展。那其方法實現是通過何種方式完成的呢?
答案是協議,不同的協議包裹了不同的方法,通過遵守不同的協議來擴展特定的方法。

對於上述需求,在swift中一般通過如下方法實現

// swift通過protocol來擴充方法,通過遵守不同的協議來獲取不同方法,更偏重組合,而非繼承
protocol FirstProtocol {
    func aMethod()
    func bMethod()
}

protocol SecondProtocol {
    func oneMethod()
    func twoMethod()
}

class AClass: FirstProtocol,SecondProtocol {
    //實現兩個方法
}

class BClass: FirstProtocol {
    //實現兩個方法
}

比如Array類型,其通過繼承不同的協議來獲取不同的方法。


Array遵守的協議
* 類比理解:

繼承更講究出身,尤其OC是單繼承,只能有一個父類,你想獲取父類制定的方法,必須繼承父類。
而面向協議則更加靈活,不同的protocol封裝了不同的技能包,某個類型想要獲取對應方法,只需遵守該protocol就ok了。而且一個類型可以遵守多個協議,更加靈活。而且Enum,Struct都可以通過遵守協議來獲取方法。

Compound Types (複合類型)

  • Tuples(元組)
  • Function(函數)

Tuples Types

Tuples(元組)是swift的新類型。其成員不同,Tuple類型就不同。

var aTuple = (x: 10, y: 20)
// 此時就會報錯,x的類型只能是Int
// aTuple = (x: "name", y: 50) 

當Tuples作爲函數的返回值類型,就可以返回多個值

let nameDictionary: [Int: String] = [001: "Jimmy"]
let ageDictionary: [Int: Int] = [001: 20]

func getInformationFrom (ID: Int) -> (name: String, age: Int) {
    let name = nameDictionary[ID] ?? "找不到對應的名字"
    let age = ageDictionary[ID] ?? 0
    
    return (name, age)
}

Function Types

swift將Function(函數)提升爲一等類型

let nameDictionary: [Int: String] = [001: "Jimmy"]
let ageDictionary: [Int: Int] = [001: 20]

func getInformationFrom (ID: Int) -> (name: String, age: Int) {
    let name = nameDictionary[ID] ?? "找不到對應的名字"
    let age = ageDictionary[ID] ?? 0
    
    return (name, age)
}
// 用aPerson接受這個函數,類型爲一個元組類型,值爲(name: "Jimmy", age: 20)
let aPerson = getInformationFrom(ID: 001)

Blocks VS Closures(閉包)

swift中的closure類似於OC的block,但還是有些區別。

Blocks VS Closures
關於兩者語法的不同,可以參考

Block Syntax and Closure Syntax

Function VS Closures

A closure is actually a higher usage of a function type. Above, we just have two types of types; the closure is defined quite similarly to the function itself. This is because it takes the parameters and the area and the return type just as the type signage. This makes functions and closures siblings.

Optional可選類型

swift中的Optional底層就是一個帶泛型的枚舉類型。

其源碼抽象出來如下:

public enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none
    case some(Wrapped)
    
    public init(_ some: Wrapped)
    public init(nilLiteral: ())
}
// 此時定義中的Wrapped就是String類型
var myName : String? = "Walker"
    print(myName)
    print(myName!)

    if let name = myName {
        print(name)
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章