swift4.1 系統(tǒng)學(xué)習(xí)二十 類型定義和類型投射

/*
今天為止,我們終于把swift中大部分的數(shù)據(jù)類型都給細(xì)細(xì)的學(xué)習(xí)了一遍。也寫了很多很多的測試代碼,相信大家對swift應(yīng)該有了全新的認(rèn)識。接下來我們繼續(xù)學(xué)習(xí)swift語言的一些特性。

本節(jié)呢,我們來學(xué)習(xí) 類型定義和類型投射等操作
在本節(jié)中,我們也能領(lǐng)略swift編程語言的動態(tài)特性。
*/

主要內(nèi)容總結(jié):
1 類型定義 typealias ;
2 元類型 Type;
3 類型獲取 type(of:);
4 Any與AnyObject
5 類型投射 as? as!
6 類型檢查 is
7 嵌套類型

// 1.類型定義
/*
學(xué)過C語言的小伙伴們都知道有類型別名的概念,就是將已經(jīng)定義好的類型定義為我們自己所指定的自定義類型。
swift中,使用typealias關(guān)鍵字聲明。

//typealias <#type name#> = <#type expression#>
*/

do {

print("\n-----------1.類型定義----------------\n")

// 這里將MyInt定義為Int32類型
typealias MyInt = Int32

// 這里將MyArray定義為一個整型數(shù)組
typealias MyArray = [MyInt]

// 這里將VoidFuncType定義為 () -> Void 的函數(shù)類型
typealias VoidFuncType = () -> Void

// 這里將Tuple定義為(Int, Float, String)的元組
typealias Tuple = (Int, Float, String)

// 使用
// 這里的a的類型是MyInt ,實(shí)際上相當(dāng)于Int32類型
let a: MyInt = 100 + MyInt.min
print("a = \(a)")

let array: MyArray = [1, 2, 3]
print("array: \(array)")

let tuple: Tuple = (10, 1.5, "abc")
print("tuple: \(tuple.0)")

func foo() {
    print("今天天氣不錯 ")
}

let ref: VoidFuncType
ref = foo
ref()

}

//2. 元類型
/*
什么是元類型?
元類型是指可引用某個類型的類型對象的類型。
有點(diǎn)兒像繞口令,不甚明白。
*/

protocol Prot {
    
    /// 計(jì)算式屬性
    static var s: Int { get }
    
    /// 類型方法
    static func method()
}

do {

print("\n----------2. 元類型------------\n")

struct MyStruct: Prot {
    
    static var s: Int {
        return 1
    }
    
    static func method() {
        print("這是一個結(jié)構(gòu)體")
    }
}

class MyClass: Prot {

    static var s: Int {
        return 100
    }
    
    static func method() {
        print("這是一個類")
    }
}

/*
 這里使用MyStruct結(jié)構(gòu)體的元類型定義了一個類型對象st,其類型是MyStruct.Type,
 而MyStruct.self 則是MyStruct這一類型的實(shí)體。
 */
let st: MyStruct.Type = MyStruct.self

/*
 這里用MyClass類的元類型定義了一個類型對象ct,其類型是MyClass.Type, MyClass.self是
 這一類型的實(shí)體。
 */
let ct: MyClass.Type = MyClass.self

/*
 這里使用Prot的元類型定義了一個類型對象pt,然后指向了st的元類型實(shí)體。
 */
var pt: Prot.Type = st

print("pt: \(pt.s)")
pt.method()

pt = ct
print("pt: \(pt.s)")
pt.method()

/*
 結(jié)果:
 pt: 1
 這是一個結(jié)構(gòu)體
 pt: 100
 這是一個類
 */

/*
 小結(jié):
 從這里可以看出,元類型能夠使用同一個對象指向不同類型的實(shí)體。
 */

}

/*
swift中,不僅類類型可以訪問self屬性,對象也是可以訪問self的,只不過得到的結(jié)果不是元類型實(shí)體
而是自身的值。
*/

do {

let a = 10.self
print("a = \(a)")

let tuple = (10, 12.3, "哈哈哈").self
print("tuple: \(tuple)")

}

//3. 類型獲取
/*
上面我們了解到元類型以及元類型實(shí)體。在傳遞的過程中,我們想知道目前對象指向的到底是什么類型呢?
這個時候我們就能使用 “類型獲取”來了解當(dāng)前的類型。
*/

print("\n--------------3. 類型獲取----------------\n")

protocol PA {
    
    static var s: Int { get }
    static func method()
    init()
    func foo()
}

do {
    
    struct MyStruct: PA {
        
        static var s: Int {
            return 10
        }
        
        static func method() {
            print("哈哈哈哈,結(jié)構(gòu)體啊")
        }
        
        func foo() {
            print("結(jié)構(gòu)體中的方法")
        }
    }
    
    class MyClass: PA {
        
        static var s: Int {
            return 100000
        }
        
        static func method() {
            print("喲呼呼, 這是一個類")
        }
        
        func foo() {
            print("這是一個類中的方法")
        }
        
        required init() {
           print("這是一個類的初始化方法")
        }
        
        deinit {
            print("類被銷毀了")
        }
    }
    
    // 定義一個方法,參數(shù)是PA的元類型
    func typeFetch(t: PA.Type) {
       
        print("value: \(t.s)")
        t.method()
        
        let obj = t.init()
        print("obj: \(obj)")
        obj.foo()
    }
    
    let ms: PA = MyStruct()
    let mc: PA = MyClass()
    
    typeFetch(t: type(of: ms))
    typeFetch(t: type(of: mc))
    
    /*
     結(jié)果:
     這是一個類的初始化方法
     value: 10
     哈哈哈哈,結(jié)構(gòu)體啊
     obj: MyStruct()
     結(jié)構(gòu)體中的方法
     value: 100000
     喲呼呼, 這是一個類
     這是一個類的初始化方法
     obj: swift20_類型定義投射_.(unknown context at 0x1004e634c).MyClass
     這是一個類中的方法
     類被銷毀了
     類被銷毀了
     */
}

// 4.Any與AnyObject
/*
本節(jié)中,我們談?wù)剆wift的根類型。大部分現(xiàn)在化的面向?qū)ο缶幊陶Z言都有自己的根類型。這些面向?qū)ο缶幊陶Z言中
的根類型的對象引用可以指向該編程語言中任意類類型的對象實(shí)例。

swift編程語言有兩個根類型,
一個是Any,它可以指向swift中的任一類型;
還有一個是AnyObject,它其實(shí)是一個協(xié)議類型,用于指向任一類類型的對象引用。
*/

do {

struct MyStruct {
    
}

class MyClass {
    
}

func foo() {
    
}

var obj: Any

obj = MyStruct()
obj = MyClass()
obj = foo

print("obj = \(obj)")

let cla: AnyObject = MyClass()
print("cla = \(cla)")

/*
 不過,這兩種類型聲明的對象一般無法直接使用,需要類型投射才能進(jìn)行使用。
 */

}

// 5. 類型投射

/*
當(dāng)我們有根類型的對象,如何將這個對象轉(zhuǎn)為具體的類型呢?這個時候就需要類型投射了。
swift語言中,提供了兩種投射操作符,分別是 as! 和 as?
由于向下投射可能會失敗,所以一般情況下,我們使用as?進(jìn)行操作,它返回一個optional對象。
*/

do {

print("\n-----------5. 類型投射------------\n")

var obj: Any = 10
/*
 這里編譯的時候回報(bào)錯:
  Could not cast value of type 'Swift.Int' (0x1005720b0) to 'Swift.Double' (0x100571718).
 為什么呢?因?yàn)閛bj是Int類型,不能直接投射成Double。
 */
//let value = obj as! Double
//print("value = \(value)")

let value2 = obj as! Int
print("value2 = \(value2)")
// 結(jié)果:value2 = 10

}

protocol PB {
    
    func method()
}
do {
    enum MyEnum: PB {
        case one, two, three
        
        func method() {
            print("現(xiàn)在的值是 \(self)")
        }
        
        func foo() {
            print("這是枚舉中的方法 foo")
        }
    }
    
    struct MyStruct: PB {
        
        func method() {
            print("這是一個結(jié)構(gòu)體 method")
        }
        
        func foo() {
            print("這是一個結(jié)構(gòu)體, foo")
        }
    }
    
    class Father: PB {
        
        func method() {
            print("這是一個類,method")
        }
        
        func foo() {
            print("這是類呢,哈哈哈哈哈")
        }
    }
    
    class Child: Father {
        
        override func method() {
            print("這里是Child,method")
        }
        
        override func foo() {
            print("這里是Child,foo ")
        }
    }
    
    func test(ref: Any) {
        
        if let obj = ref as? MyEnum {
            obj.foo()
        }
        
        if let obj = ref as? MyStruct {
            obj.foo()
        }
        
        if let obj = ref as? Father {
            obj.foo()
        }
        
        if let obj = ref as? Child {
            obj.foo()
        }
        
        if let obj = ref as? PB {
            obj.method()
        }
    }
    
    let ref: Any = test(ref: )
    let fun = ref as! (Any) -> Void
    
    fun(MyEnum.one)
    fun(MyStruct())
    fun(Father())
    fun(Child())
    
    /*
     結(jié)果:
     這是枚舉中的方法 foo
     現(xiàn)在的值是 one
     這是一個結(jié)構(gòu)體, foo
     這是一個結(jié)構(gòu)體 method
     這是類呢,哈哈哈哈哈
     這是一個類,method
     這里是Child,foo
     這里是Child,foo
     這里是Child,method
     */
    
}

// 6. 類型檢查
/*
我們了解了類型投射之后,有時候我們需要檢查某個對象類型的時候就可以使用as?進(jìn)行判斷。但是這不夠直接,
我們可以使用更加直觀的操作符 is。
*/

protocol PC {
    
}

do {

print("\n-----------6. 類型檢查------------\n")

class Father: PC {
    
}

class Child: Father {
    
}

var obj: Any = Father()

if obj is PC {
    print("這是一個協(xié)議PC")
}

if obj is Father {
    print("這是一個Father類")
}

obj = Child()

if obj is PC {
    print("哈哈哈哈,pc")
}

if obj is Child {
    print("這是一個Child")
}

if obj is Father {
    print("哈哈哈哈,F(xiàn)ather")
    print("\(type(of: obj))")
}

}

// 7. 嵌套類型
/*
與C++ 、Java等傳統(tǒng)的面向?qū)ο蟮木幊陶Z言一樣,swift也支持嵌套類型。
*/

do {

print("\n-------------7. 嵌套類型--------------\n")

struct Test {
    
    private var member: Int = 1
    
    enum MyEnum {
        
        case one, two, three
        
        class MyClass {
            
            private var p = 0.5
            
            func hello(test: Test) {
                print("value = \(test.member)")
            }
        }
        
        func test(cl: MyClass) {
            print("哈哈哈哈哈,test \(self)")
        }
    }
    
    func foo(cls: MyEnum.MyClass) {
        
        cls.hello(test: self)
    }
}

let t = Test()
let e = Test.MyEnum.two
let c = Test.MyEnum.MyClass()

t.foo(cls: c)
e.test(cl: c)

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,203評論 3 119
  • 準(zhǔn)確的說我今天過的陽歷生日,也恰逢今天有班組款待,也有幸參觀了G叔的房子,環(huán)境好,風(fēng)景好,地理位置好,又大又美又有...
    沙粒女超人閱讀 205評論 0 0
  • 愛熱鬧、群居的生活,也同樣適應(yīng)一個人冷清、獨(dú)處的日子。一個人,一個人的周末同樣可以過得有滋有味。 周末要是沒有約會...
    梁倩倩閱讀 254評論 0 1
  • 你關(guān)注我多久了呢?這個我不知道,我也不知道關(guān)注我的你,我們有沒有在生活中見過面。自己寫故事有一點(diǎn)好,寫自己的時候,...
    夕木由閱讀 412評論 0 0
  • 1、查找表中多余的重復(fù)記錄(多個字段)select * from test group by column1, c...
    LeLeBa閱讀 282評論 0 0

友情鏈接更多精彩內(nèi)容