Swift 基础小结一

Swift 基础小结

  1. 在 Swift 中使用 varlet 分别声明变量和常量,至于类型,则可以通过后面的初始值信息进行推断,或者直接在变量名后进行指定。

    var str = "string"
    let num: Int = 0
    var isOpen: Bool
    

    这种不同于 OC 的声明书写格式,是否会觉得有点不习惯呢,但是鉴于其自动推断类型的强大功能,通常我们是可以省略类型说明的,书写起来会更加便捷。

    使用反引号可以将关键字指定为变量名称,但是不提倡这样做。

    let `var` = "var"
    print(`var`)
    
  2. 在 Swift 中值的类型转换必须是显示的,如下面将字符串转换为整型:

    let str = "2"
    let num = 3
    let result = Int(str)! + num
    

    如果 Int(str) 强制转换失败,那么可选值结果为 nil ,此时进行强制解包则会报错。

  3. 数组和字典的声明更佳便捷,同样可以省略类型说明。

    let array = [String]()
    let dic = [String:Int]()
    
    let array = ["str1","str2"]
    let dic = ["1":1,"2":2]
    

    数组和字典的声明如此相似,是否可以将字典看作是元素是键值对的无序数组呢,并且元素的类型可以是诸如 Int 的基本类型,相对于 OC 是不是帮了大忙了!

  4. 在 Swift 中不再支持 C 语言中的 for 语句循环,如打印 0 到 9 ,使用如下写法是无法编译通过的:

    for(int i = 0;i<10;i++) {
        print(i)
    }	
    

    但是这里引入了范围表达式:..<... ,分别表示不包括上界限和包括上界限的范围,所以有如下写法:

    for i in 0..<10 {
        print(i)
    }
    
  5. 另外,do-while 循环则修改为了 repeat-while 循环,当然,while 循环还可以使用。

  6. for-in 循环进行了强化,临时变量无需声明类型且可以是元组类型。

    for (key,value) in ["2":2] {
        print(key,":",value)
    }
    
  7. 对于条件语句而言,判断条件必须是布尔表达式,不会在隐式的将数值同 0 进行比较或判断可选类型是否为 nil ,并且包裹判断条件的圆括号可以省略。

    let num = 3
    if num > 0 {
    	print(num)
    }
    

    不过,对于可选类型,这里提供了一种书写方式,将判断其是否是 nil ,然后再去进行解包合为一步,也称为可选绑定。

    let str: String? = "5"
    if let temp = str,let num = Int(temp),num == 5 {
        print(num)
    }else if let num = Int("5") {
        print(num)
    }
    

    如果可选值有值,则将值赋给临时变量,而后执行下面的语句,如果为 nil ,那么则跳过下面的语句。

    需要注意的是,这种写法必须要省略圆括号。

  8. 在 Swift 中使用 switch 选择分支时,如果将所有的情况都列出了,则可以省略 default 选项。如果无法列出所有的可能项,则需要使用 default 默认项。

    let str = "Test Str"
            
    switch str {
    case "Test":
        print("content : \(str)")
    case "Test Str1":
        print("content : \(str)")
    case let x where str.hasPrefix("Test"):
        print("x : \(x)")
    default:
        print("default")
    }
    

    switch 中可以比较的值不在限于整型值,其他类型也可以,而且还可以使用 where 关键字来添加限定条件。

  9. 使用 struct 关键字定义结构体,其和类一样,可以声明变量、方法和构造器,但是其同类有个重要区别,就是类实例传递时,传递的是引用,而结构体传递的是值。

    protocol Named {
        var name: String { get }
    }
    protocol Aged {
        var age: Int { get }
    }
    struct Person: Named, Aged {
        var name: String
        var age: Int
    }
    

    结构体可以遵循协议,但是不能继承结构体。

  10. 使用 enum 关键字定义枚举类型,除了使用 case 定义枚举值外,还可以定义方法,但是不能定义存储属性。而且,枚举值除了其原始值外,还可以有不同的关联值,相同原始值的枚举实例变量如果关联值不同,那么这两个枚举变量是不相等的。

    enum EnumTest {
        case tt1(str: String,num: NSNumber)
        case tt2(str: String,num: NSNumber)
        case tt3(str: String,num: NSNumber)
        
        func test() {
            switch self {
    
            case .tt1(str: "str1", num: NSNumber.init(value: 1)):
                print(self)
                
            case .tt1(str: "str1", num: NSNumber.init(value: 2)):
                print(self)
                
            case .tt1(let str, let num):
                print(str,num)
                
            case .tt2(str: "str2", num: nil):
                print(self)
                
            case .tt3(str: "str3", num: nil):
                print(self)
            default:
                print(self)
            }
        }
    }
    
    let enumT1 = EnumTest.tt1(str: "str1", num: NSNumber.init(value: 1))
    enumT1.test()
    

    如果需要通过 : 指定枚举的原始值,那么该原始值类型需要遵循 RawRepresentable 协议。枚举同样不能继承枚举,但同样可以遵循协议。

  11. 使用 protocol 关键字来定义协议,类、枚举、结构体都可以遵循协议,并且如果协议会被结构体实现,且其中定义的函数需要修改结构体中的属性,那么需要使用 mutating 关键字来修饰该函数,来表明这是一个可以修改结构体属性的函数,而类函数本身就可以修改属性,则不需要额外标记。

  12. 可以使用 extension 关键字来扩展某个类型,声明其遵循某个协议。

  13. 类如果继承其他类,那么其遵循的协议要写在继承的类之后。

  14. 声明函数时,可以指定参数类型为遵循某一协议的任意类型,遵循多个协议的类型使用 & 进行连接。

    func test(para: Named&Aged){ }
    
  15. 闭包是自包含的函数代码块,可以在代码中被传递和使用,全局函数和嵌套函数实际上是特殊的闭包。

  16. 使用 @escaping 来声明一个闭包是逃逸闭包,即作为参数传递给函数的闭包,可以在该函数执行结束之后进行调用,常用于异步操作。在逃逸闭包中,是不可以隐式引用 self 的,必须显示地引用。

    var completionHandlers: [() -> Void] = []
    func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
        completionHandlers.append(completionHandler)
    }
    
    someFunctionWithEscapingClosure {
        print(self.completionHandlers.count)
    }  
    completionHandlers[0]()  
    
  17. 自动闭包不接受参数,但是可以有返回值。如果一个函数的参数是一个闭包,那么使用 @autoclosure 进行修饰后,调用该函数时,其必须接收一个非闭包参数并自动将其转换为闭包。

    var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
            
    func serve(customer customerProvider: @autoclosure () -> String) {
        print("Now serving \(customerProvider())!")
    }
    serve(customer: customersInLine.remove(at: 0))
    

    并且此时,如果传递闭包参数 serve(customer: {customersInLine.remove(at: 0)}) 是会报错的。

  18. 在 Swift 中可以使用泛型来表示函数的参数为任意类型,而且需要使用 inout 修饰参数,来表示参数是可以被修改的。

    public func swap<T>(_ a: inout T, _ b: inout T)

  19. 函数、方法、类、枚举、结构体都可以使用泛型。使用泛型时,还可以限定其必须是某个类的子类或必须实现某个协议,还可以使用 where 子句来添加额外的约束条件。

    func allItemsMatch<C1: Container, C2: Container>
            (_ someContainer: C1, _ anotherContainer: C2) -> Bool
            where C1.ItemType == C2.ItemType, C1.ItemType: Equatable
            
    protocol Container {
        associatedtype ItemType
        mutating func append(_ item: ItemType)
        
        var count:Int { get }
        
        subscript(_ index:Int)->ItemType { get }
    }        
    

    对于 allItemsMatch 函数而言,其接收的两个参数必须都遵循了 Container 协议,而且关联的类型 ItemType 必须遵循 Equatable 协议。

  20. 在定义类的实例变量或方法时,可以使用关键字 staticclass ,但是在协议、结构体或扩展中,只能使用 static 关键字。如此,当类遵循的某个协议中使用 static 定义了一个变量,那么该类在实现该协议时,使用 staticclass 声明该变量都可以。

  21. 在 Swift 中,使用 typealias 关键字取代 typedef 关键字,定义类型别名。

    typealias Int_16 = Int16
    
发布了129 篇原创文章 · 获赞 23 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u011374318/article/details/93739537