iOS学习笔记(3)-Swift概览

作者: __七把刀__ | 来源:发表于2016-04-05 00:39 被阅读138次

    上次找到一个iOS实战教程,用的是swift,看了下确实比obj-c要方便不少,于是看了《swift programming language》,总结下基础语法,swift版本为2.2。

    1 数据类型

    • 常量和变量: 用let声明常量,用var声明变量,常量只能赋值一次。
    • 类型推断: 定义变量的时候可以不用声明类型,swift可以自动推断。不过要注意的是,如果初始值信息不够或者没有初始值,需要声明变量类型,见下面例子。
    • 类型转换: 值不会隐式转换为其他类型,比如下面的字符串拼接,可以用+拼接字符串,但是整数需要先显示转换为String类型才可以拼接。另外,也可以通过反斜杠加括号的方式拼接。需要注意的是,不像python等其他语言,Swift的字符串必须用""而不是''括起来。
    • 元组: 通过()创建,元组内部的元素数据类型可以任意,不需要一样。
    • 数组和字典:数组和字典统一通过[]来创建。空的数组和字典需要使用初始化语法。如果类型信息可以推断出来,可以省掉类型信息。
    • 可选类型: 可选类型用来处理值可能缺失的情况,这是swift独有的,C或者objective-C中都没有这个类型。定义的时候在类型后面加个?表示可选类型。注意,nil不能用于非可选的变量,如果变量有可能缺失值,则需要声明为可选类型。可选类型如果声明的时候没有赋值,则自动会被设置为nil。
    • 类型别名: 可以通过typealias关键字来给已有类型定义一个别名。
    //1 常量和变量
    let apples = 3
    apples = 4 //错误,常量只能赋值一次
    var orange = 5
    orange = 6 //正确
    
    let orangesAreOrange = true 
    let turnipsAreDelicious = false
    
    //2 类型推断
    let implicitInteger = 70
    let implicitDouble = 70.0
    let explicitDouble: Double = 70 //显示声明类型,因为根据初始值无法确定变量类型
    
    //3 类型转换
    let desc = "Apple num: "
    let descLabel = desc + String(apples)
    let appleSummary = "I have \(apples) apples."
    
    
    //4 元组
    let http404Error = (404, "Not Found") //元组里的数据类型可以任意,不需要一致
    
    //5 数组和字典
    var shoppingList = ["catfish", "water", "tulips"]
    shoppingList[1] = "bottle of water"
     
    var occupations = [
        "Malcolm": "Captain",
        "Kaylee": "Mechanic",
    ]
    occupations["Jayne"] = "Public Relations"
    
    let emptyArray = [String]() //不加类型信息 let emptyArray = []
    let emptyDictionary = [String: Float]() //不加类型信息 let emptyDictionary = [:]
    
    //6 可选类型
    var serverResponseCode: Int? = 404 //serverResponseCode 包含一个可选的 Int 值 404 
    serverResponseCode = nil //serverResponseCode 现在不包含值
    
    oranges = nil //错误
    var surveyAnswer: String?// surveyAnswer 被自动设置为 nil
    
    //7 类型别名
    typealias AudioSample = UInt16
    var maxAmplitudeFound = AudioSample.min
    
    

    2 控制流

    与其他语言一样,有 if...else..., while, repeat...while, for...in

    • 括号问题: 循环或判断语句的括号可以省略,如下面的for...in,但是语句体的花括号{}必须有。
    • 强制解析和可选绑定: 在确定可选类型有值的情况下,使用!可以强制解析可选类型,也使用可选绑定来判断可选类型是否有值以及解析出可选类型的值。
    • 隐式解析可选类型: 有些可选类型在第一次被赋值后可以确定总会有值,这时候可以将可选类型定义为隐式解析可选类型,隐式解析可选类型方式为将类型后面的?改为!
    • switchif: switch语句支持任意类型的数据和各种操作,也不需要在每个case后面加break。还有if语句的判断必须是Bool类型,不能像其他语言那样可以直接拿整数值进行判断。
    //1 括号问题
    let individualScores = [75, 43, 103, 87, 12]
    var teamScore = 0
    for score in individualScores {
        if score > 50 {
            teamScore += 3
        } else {
            teamScore += 1
        }
    }
    print(teamScore)
    
    //2 强制解析和可选绑定
    let possibleNumber = "123"
    let convertedNumber = Int(possibleNumber)
    if convertedNumber != nil {
         print("convertedNumber has an integer value of \(convertedNumber!).")
    }
    if let actualNumber = Int(possibleNumber) { //Int
        print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
    } else {
        print("\'\(possibleNumber)\' could not be converted to an integer")
    }
    // 输出 "'123' has an integer value of 123"
    
    
    //3 可选类型/隐式解析可选类型
    let possibleString: String? = "An optional string."
    let forcedString: String = possibleString! // 需要惊叹号来获取值
    let assumedString: String! = "An implicitly unwrapped optional string." 
    let implicitString: String = assumedString // 不需要感叹号
    
    //4 switch语句不用在每个case后面加break,if判断必须是Bool类型
    let vegetable = "red pepper"
    switch vegetable {
    case "celery":
        print("Add some raisins and make ants on a log.")
    case "cucumber", "watercress":
        print("That would make a good tea sandwich.")
    case let x where x.hasSuffix("pepper"):
        print("Is it a spicy \(x)?")
    default:
        print("Everything tastes good in soup.")
    }
    
    let i = 1 
    if i {
       //编译错误
    }
    if i == 1 {
      //编译成功 
    }
    
    

    3 函数

    • 使用func来声明函数,使用->来指定函数返回值的类型,函数可以带有可变个数的参数(可变参数后面带...)。
    • 函数可以嵌套函数。函数也可以作为参数和另一个函数的返回值。
    //1 函数声明
    func sumOf(numbers: Int...) -> Int {
        var sum = 0
        for number in numbers {
            sum += number
        }
        return sum 
    }
    sumOf()
    sumOf(42, 597, 12)
    
    //2 函数作为参数
    func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool {
        for item in list {
            if condition(item) {
                return true
            }
        }
        return false
    }
    func lessThanTen(number: Int) -> Bool {
        return number < 10
    }
    var numbers = [20, 19, 17, 12]
    hasAnyMatches(numbers, condition: lessThanTen)
    

    4 对象和类 & 枚举和结构体

    • 使用class来创建一个类,类中属性和常量声明普通变量和常量声明,只是它们属于这个类。引用实例变量用self关键字,调用父类方法用super关键字。属性也可以有gettersetter
    • 构造函数为init,析构函数为deinit(注意后面没有括号),不需要func关键字。
    • 类之间继承用:,子类覆盖父类方法需要用override关键字。
    • 结构体和类相似,只是传参的时候结构体传的是值,类是传引用。
    //1 类
    class NamedShape {
        var numberOfSides: Int = 0
        var name: String
        init(name: String) {
            self.name = name
        }
        deinit { 
            print("deinit")
        }
        func simpleDescription() -> String {
            return "A shape with \(numberOfSides) sides."
        } 
    }
    
    
    class EquilateralTriangle: NamedShape {
        var sideLength: Double = 0.0
        init(sideLength: Double, name: String) {
            self.sideLength = sideLength
            super.init(name: name) //调用父类的构造器方法
            numberOfSides = 3 //修改父类定义的属性值
        }
        var perimeter: Double {
            get {
                return 3.0 * sideLength
            }
            set {
                sideLength = newValue / 3.0
            }
        }
        override func simpleDescription() -> String {
            return "An equilateral triagle with sides of length \(sideLength)."
        }
    }
    let optionalSquare: EquilateralTriangle? = EquilateralTriangle(sideLength: 2.5, name: "optional square")
    let sideLength = optionalSquare?.sideLength //处理可选变量的新语法,如果变量为nil,则返回nil,否则返回问号后面的值。注意,整个表达式返回的也是可选值。
    
    //2 枚举和结构体
     enum Suit {
         case Spades, Hearts, Diamonds, Clubs
         func simpleDescription() -> String {
             switch self {
             case .Spades:
                 return "spades"
             case .Hearts:
                 return "hearts"
             case .Diamonds:
                 return "diamonds"
             case .Clubs:
                 return "clubs"
             }
         } 
     }
     let hearts = Suit.Hearts
     let heartsDescription = hearts.simpleDescription()
    
     struct Card {
         var rank: Rank
         var suit: Suit
         func simpleDescription() -> String {
             return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
         }
     }
     let threeOfSpades = Card(rank: .Three, suit: .Spades)
     let threeOfSpadesDescription = threeOfSpades.simpleDescription()
    
    

    5 协议和扩展

    • 使用protocol声明协议,extension声明扩展。协议有点类似接口,而扩展用来为已有类添加新的功能。
    • 类,结构体和枚举都可以实现协议。注意结构体中的方法需要声明为mutating,用于标记该方法会修改结构体。而类中的方法不需要,因为类中方法总是可以修改类属性。
    //1 协议声明
    protocol ExampleProtocol {
        var simpleDescription: String { get }
        mutating func adjust()
    }
    
    //2 类实现协议
    class SimpleClass: ExampleProtocol {
        var simpleDescription: String = "A very simple class."
        var anotherProperty: Int = 69105
        func adjust() {
            simpleDescription += "  Now 100% adjusted."
        }
    }
    var a = SimpleClass()
    a.adjust()
    let aDescription = a.simpleDescription
     
    //3 结构体实现协议
    struct SimpleStructure: ExampleProtocol {
        var simpleDescription: String = "A simple structure"
        mutating func adjust() {
            simpleDescription += " (adjusted)"
        }
    }
    var b = SimpleStructure()
    b.adjust()
    let bDescription = b.simpleDescription
    
    //4 扩展Int,添加一个测试函数。
    extension Int: ExampleProtocol {
        var simpleDescription: String {
            return "The number \(self)"
        }
        mutating func adjust() {
            self += 42 
        }
    }
    print(7.simpleDescription)
    
    

    6 错误捕获

    • 使用throws关键字声明一个函数可能抛出异常,使用do...catch关键字捕获函数。
    enum PrinterError: ErrorType {
        case OutOfPaper
        case NoToner
        case OnFire
    }
    
    func sendToPrinter(printerName: String) throws -> String {
        if printerName == "Never Has Toner" {
            throw PrinterError.NoToner
        }
        return "Job sent"
    }
    
    do {
        let printerResponse = try sendToPrinter("Bi Sheng")
        print(printerResponse)
    } catch {
        print(error)
    }
    

    7 泛型

    • 泛型用尖括号<>来标识,跟Java里面一样。
    func repeatItem<Item>(item: Item, numberOfTimes: Int) -> [Item] {
         var result = [Item]()
         for _ in 0..<numberOfTimes {
             result.append(item)
         }
         return result
     }
    repeatItem("knock", numberOfTimes:4)
    

    参考资料

    相关文章

      网友评论

        本文标题:iOS学习笔记(3)-Swift概览

        本文链接:https://www.haomeiwen.com/subject/bahplttx.html