美文网首页
Swift4.0官方文档学习笔记

Swift4.0官方文档学习笔记

作者: 优雨 | 来源:发表于2018-07-24 23:32 被阅读55次

    主要记录一下可能容易遗忘的知识点

    1.没有隐式类型转换

    所有的转换需要显示的进行,例如:

    var widthStr = "The width is "
    var widthValue = 15
    var width = widthStr + String(widthValue)
    
    var num = 12 // num默认为Int类型
    var num2 = 12.0 // num2默认为Double类型
    

    2.把值插入字符串的更简单方法

    let apple = 2
    let banana = 3
    let total = "I have \(apple + banana) pieces of fruits"
    

    3.多行字符串

    let multiLineStr = """
    I am ABC
    I like DEF
    """
    

    4.除了数组 字典也用方括号组来创建

    let dict = [
      "key1" : "value1",
      "key2" : "value2"
    ]
    let value1 = dict["key1"]
    

    5.创建空数组或者空字典

    • 指定元素类型
    let arr = [String]()
    let dict = [String:Float]()
    
    • 数组或者字典内元素类型已知 可以用如下方式声明其为空
    arr = []
    dict = [:]
    

    6.for in循环不再强制需要给for in语句写括号 但是循环体的花括号还是需要的

    其他例如if判断、while、repeat-while也是如此

    for str in strArr {
      print(str)
    }
    
    var n = 1
    while n < 10 {
      n = n * 2
    }
    

    7.if语句的判断条件现在必须为布尔表达式 而不能是 if score 这种格式

    布尔值的类型为Booltruefalse这两个常量值 和OC中的YESNO不同
    可以使用let/varif来对可能为nil的值进行判断 如果值存在就将值赋予给一个常量或者变量 并执行if内的语句 这个称为可选项绑定

    var optionalName : String? = "Tom"
    // var optionName : String? = nil
    var greeting = "Hello"
    if let name = optionName {
      greeting = "Hello \(name)!"
    }
    

    8.也可以使用??返回可选类型的默认值

    ??对可选项进行判断 如果存在值就返回这个值 否则返回运算符后面的值

    var a : Int?
    var b = a ?? 10
    

    9.switch语句不需要再写break了 会自动退出当前case

    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.")
    }
    

    10.遍历字典更方便了 只需要提供一对存储键值对的变量就行了

    let interestingNumbers = [
        "Prime": [2, 3, 5, 7, 11, 13],
        "Fibonacci": [1, 1, 2, 3, 5, 8],
        "Square": [1, 4, 9, 16, 25],
    ]
    var largest = 0
    for (kind, numbers) in interestingNumbers {
        for number in numbers {
            if number > largest {
                largest = number
            }
        }
    }
    print(largest)
    

    11.使用..<创建一个不包含最大值的区间 使用...创建一个包含最大值的区间

    其实相当于声明了数组

    for i in 0..<4 {
      print(i)  //输出为0 1 2 3
    }
    
    for i in 0...4 {
      print(i)  //输出为0 1 2 3 4
    }
    

    12.函数的声明和调用

    func greet(person:String, day:String) -> String {
      return "Hello, \(person), today is \(day)!"
    }
    greet(person:"Bob", day:"Tuesday")
    

    ->表示返回值类型
    调用时候要带上实参标签
    也可以在申明的时候用_取消标签
    或者声明另一个标签名称

    func greet(_ person:String, on day:String) -> String {
      return "Hello, \(person), today is \(day)!"
    }
    greet("Bob", on:"Tuesday")
    

    13.使用元组可以让函数返回一个复合值

    func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
        var min = scores[0]
        var max = scores[0]
        var sum = 0
        
        for score in scores {
            if score > max {
                max = score
            } else if score < min {
                min = score
            }
            sum += score
        }
        
        return (min, max, sum)
    }
    

    14.函数可以用...接受多个参数 并放到一个数组里面

    func printManyNumber(numbers : Int...) {
      for num in numbers {
        print(num)
      }
    }
    printManyNumber(numbers: 1,2,3,4) // 传递参数的时候用逗号隔开
    

    15.函数可以内嵌函数 内嵌函数可以访问外部函数的变量

    func foo(a : Int) -> Int {
      a = a * 2
      func bar() {
        a = a + 5
      }
      bar()
      return a
    }
    foo(5)
    

    16.函数可以作为函数的返回值

    func getFunc() -> ((Int) -> Int) {
      func increase(num : Int) -> Int {
        return num + 1
      }
      return increase
    }
    
    var increaseFunc = getFunc()
    increaseFunc(1)
    

    17.函数也可以作为函数的参数传递

    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, 7, 12]
    hasAnyMatches(list: numbers, condition: lessThanTen)
    

    18.闭包

    • 闭包的一般表达式语法为:
    {  (parameter) -> returnType in
      statements
    }
    
    • 举个例子(当函数的最后一个参数为闭包的时候 可以省略函数的括号)
    var userNames = ["Tom", "Bob", "Jack"]
    userNames.sort{ (name1:String, name2:String) ->Bool in 
      return name1 < name2
    }
    
    • 由于sort函数的函数参数的类型已知(即 (String, String) -> Bool)所以闭包可以简化 省略参数的括号和返回类型
    userNames.sort{ name1, name2 in
      return name1 < name2
    }
    
    • 单行表达式闭包可以通过省略return关键字来隐式返回单行表达式的结果
    userNames.sort{ name1, name2 in name1 < name2 }
    
    • 内联闭包可以省略参数名直接用参数顺序 $0$1$2调用
    userNames.sort{ $0 < $1 }
    
    • 闭包默认是不允许逃逸的 如果允许逃逸 需要用@escaping声明
    var completionHandlers: [() -> Void] = []
    func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
        completionHandlers.append(completionHandler)
    }
    

    那么何时闭包允许逃逸呢?比如处理异步回调的时候,异步函数本身是直接返回的,但是异步处理需要异步操作完成之后才进行,这时候的闭包就需要允许逃逸。

    • 让闭包 @escaping 意味着你必须在闭包中显式地引用 self
    func someFunctionWithNonescapingClosure(closure: () -> Void) {
        closure()
    }
     
    class SomeClass {
        var x = 10
        func doSomething() {
            someFunctionWithEscapingClosure { self.x = 100 }
            someFunctionWithNonescapingClosure { x = 200 }
        }
    }
     
    let instance = SomeClass()
    instance.doSomething()
    print(instance.x)
    // Prints "200"
     
    completionHandlers.first?()
    print(instance.x)
    // Prints "100"
    

    19.子类重写父类的方法 需要使用override关键字 不使用会造成编译器报错

    class Son : Father {
      var k
      init( j: String , k: Int) {
         super.init(j)
         self.k = k
      }
    
      override func foo() {
        print("This is son's foo func")
      }
    }
    
    let instance = Son()
    instance.foo()
    

    20.类型别名

    类型别名可以为已经存在的类型定义了一个新的可选名字。用 typealias关键字定义类型别名。

    typealias AudioSample = UInt32
    let maxAudioLength = AudioSample.max
    

    21.可选项

    var optionalStr : String? = "abc" // 声明一个可选项 optionalStr有可能没有值(nil在swift里表示没有值 对所有类型有效)
    let strVal = optionalStr! // 在可选项变量后面加上一个!表示强制展开可选项 如果可选项没有值会报错
    let assumedStr : String! = "I have value" // 隐式展开可选项 表示assumedStr被访问的时候一定有值 不需要做检查
    

    22.错误处理

    • 当一个函数可能抛出错误时,使用throws关键字
    func canThrowError() throws {
      // statements
    }
    
    • 当调用一个可能抛出错误的函数时,使用try关键字
    do {
      try canThrowError()
      // 未抛出错误
    }  catch {
      // 抛出错误
    }
    

    23.断言和先决条件

    断言只在debug模式下检查 先决条件则都会检查
    在不满足条件的时候 两者都会终止程序的运行

    let age = -1
    assert(age >= 0, "Age must be greater than 0")
    
    precondition(index > 0, "Index must be greater than zero.")
    

    24.字符串是值类型

    也就是说作为参数传入的时候,传递的是这个字符串的拷贝,在函数里修改字符串对原来的字符串没有任何影响

    25.Character类型也用双引号表示

    let charA : Character = "A"
    
    let str : String = "ABCDE"
    for char in str {
      print(char)
    }
    
    str.append(charA) // 用append方法可以给字符串后拼接Character
    

    26.可以以Unicode标量形式声明一个字符

    let dollarString : Character = "/u{24}" // 24代表Unicode标量码位为U+0024的美元符号"$"
    

    有些特殊字符可以由一个单一的Unicode标量或者几个Unicode标量组合表示 但是在Swift中,都用Character这个类型表示这个字符

    let eAcute: Character = "\u{E9}" // é
    let combinedEAcute: Character = "\u{65}\u{301}" // e followed by ́ 
    // eAcute is é, combinedEAcute is é
    

    使用count属性获取一个字符串里面Character的数量

    var word = "cafe"
    print("the number of characters in \(word) is \(word.count)")
    // Prints "the number of characters in cafe is 4"
     
    word += "\u{301}"    // COMBINING ACUTE ACCENT, U+0301
     
    print("the number of characters in \(word) is \(word.count)")
    // Prints "the number of characters in café is 4"
    

    27.字符串的索引

    • 字符串不能直接通过整数值索引来访问 需要借助几个特殊的属性和函数
    • .startIndex返回字符串第一个Character的位置,.endIndex返回字符串最后一个Character之后的位置,也就是说.endIndex不是一个合法的索引
    • 使用index(before:)index(after:)方法来访问给定索引的前后。要访问给定索引更远的索引,你可以使用index(_:offsetBy:)方法而不是多次调用这两个方法
    let greeting = "Guten Tag!"
    greeting[greeting.startIndex]
    // G
    greeting[greeting.index(before: greeting.endIndex)]
    // !
    greeting[greeting.index(after: greeting.startIndex)]
    // u
    let index = greeting.index(greeting.startIndex, offsetBy: 7)
    greeting[index]
    // a
    

    28.字符串的插入

    • 想插入一个字符到指定的索引处,使用insert(_:at:)方法
    var welcome = "hello"
    welcome.insert("!", at: welcome.endIndex)
    // welcome now equals "hello!"
    
    • 想插入字符串到指定的索引处,使用insert(contentsOf:at:)方法
    welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex))
    // welcome now equals "hello there!"
    

    28.字符串的删除

    • 移除指定索引位置的字符,使用remove(at:)方法
    welcome.remove(at: welcome.index(before: welcome.endIndex))
    // welcome now equals "hello there"
    
    • 移除指定范围内的字符串,使用removeSubrange(_:)方法
    let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
    welcome.removeSubrange(range)
    // welcome now equals "hello"
    

    29.子字符串

    子字符串是是一个Substring的实例,不是另外一个字符串,他会复用父字符串的一部分内存,如果你想让这个子字符串保留的时间长一点,使用String方法将其转变为字符串类型

    30.集合类的不变性和可变性

    和字符串一样,集合类的可变性也是由声明它的关键字是let\var来决定的

    31.数组相关

    • 声明和初始化:
      完整写法Array[ElementType] 可简写为[ElementType] 数组
    var someInts = [Int]() //简写来初始化一个空数组
    let intsArray = [1, 2, 3] // 用字面量语法创建数组 存储的类型自动推断为Int
    
    • 获取元素的数目 使用count属性
    let intCount = intsArray.count
    
    • 检查是否为空 使用isEmpty属性
    if intsArray.isEmpty {
      print("This is an empty array")
    }
    
    • 增删查改
    someInts.append(6) // 给末尾增加一个元素
    someInts += [8, 10] // 可以使用+运算符或者+=运算符拼接数组
    someInts[0] = 0 // 使用下标语法修改某处索引的值
    someInts[1...3] = [1, 2, 3] // 使用下标语法还可以修改一定范围内的值
    someInts.insert(4, at:4) // 使用insert方法在指定索引处插入值
    let removedInt = someInts.remove(at:5) // 使用remove语法移除指定索引处的值 该方法会返回删除后的值
    let removedInt2 = someInts.removeLast() // 移除数组末尾的值 返回删除后的值
    
    • 使用普通的for-in语法可以遍历数组,但是如果想在遍历的同时获取到索引值,可以使用数组的enumerated()方法
    for (index, value) in intsArray.enumerated() {
      print("Item at index \(index) is \(value)")
    }
    

    32.合集相关

    • 被存入合集的元素必须是可哈希的,也就是必须实现Hashable协议(Hashable协议遵循Equalable协议),并让其hashValue属性返回一个合理的Int值
    • 声明和初始化,类型声明必须用尖括号而不是方括号,数组,合集,字典里只有合集没有简写语法
    var letters = Set<Character>() // 初始化一个存储Character类型的空的合集 
    var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"] // 使用字面量语法初始化 并且显式声明了类型信息 可以省略
    
    • 访问元素数量使用count属性 访问是否为空使用isEmpty属性 和数组一样
    • 增删查改
    favoriteGenres.insert("Jazz") // 由于合集是无序的 所以直接使用insert方法来添加一个新元素
    favoriteGenres.remove("Rock") // 使用remove方法来移除一个元素 被移除的元素同样会被方法返回 可以用 removeAll()来移除合集中的所有元素
    
    // 使用contains方法来检查集合中是否包含了某个元素
    if favoriteGenres.contains("Funk") {
        print("I get up on the good foot.")
    } else {
        print("It's too funky in here.")
    }
    
    // sorted()方法返回一个使用 < 运算符排序的数组
    for genre in favoriteGenres.sorted() {
        print("\(genre)")
    }
    

    33.字典

    • 声明和初始化 完整写法Dictionary<Key, Value>,简写为[Key, Value],注意简写是用方括号,而不是尖括号
    var namesOfIntegers = [Int: String]() // 使用简写初始化一个空字典
    var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"] // 使用字面量语法初始化一个字典 并显式声明类型 可以省略
    
    • 字典的Key和合集的元素一样,必须都遵循Hashable协议
    • 访问元素数量使用count属性 访问是否为空使用isEmpty属性 和数组一样
    • 增删查改 区别较大 分开说
      • 下标语法和数组不同 可以添加新元素或者更新值
    airports["LHR"] = "London" // 如果`LHR`这个Key已经存在 则更新这个值 否则添加这个值
    
    • 使用updateKey方法同样可以添加或者更新值 但是由于这个方法会返回一个可选项,当旧值被更新时,可选项返回旧值 因此可以用这个方法来检查旧值是否被更新了
    if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
        print("The old value for DUB was \(oldValue).")
    }
    
    • 使用下标语法从字典的特点键中取回值,返回类型为可选项
    if let airportName = airports["DUB"] {
        print("The name of the airport is \(airportName).")
    } else {
        print("That airport is not in the airports dictionary.")
    }
    
    • 使用removeValue(forKey:)来从字典里移除键值对,返回值为一个可选项,如果删除成功,返回删除的Value,否则返回nil
    if let removedValue = airports.removeValue(forKey: "DUB") {
       print("The removed airport's name is \(removedValue).")
    } else {
       print("The airports dictionary does not contain a value for DUB.")
    }
    
    • 使用(Key, Value)可以直接对字典进行遍历
    for (airportCode, airportName) in airports {
        print("\(airportCode): \(airportName)")
    }
    

    相关文章

      网友评论

          本文标题:Swift4.0官方文档学习笔记

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