Swift4.0官方文档学习笔记

2018-07-24  本文已影响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
}
userNames.sort{ name1, name2 in
  return name1 < name2
}
userNames.sort{ name1, name2 in name1 < name2 }
userNames.sort{ $0 < $1 }
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

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

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.错误处理

func canThrowError() throws {
  // statements
}
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.字符串的索引

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.字符串的插入

var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome now equals "hello!"
welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there!"

28.字符串的删除

welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"

29.子字符串

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

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

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

31.数组相关

var someInts = [Int]() //简写来初始化一个空数组
let intsArray = [1, 2, 3] // 用字面量语法创建数组 存储的类型自动推断为Int
let intCount = intsArray.count
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 (index, value) in intsArray.enumerated() {
  print("Item at index \(index) is \(value)")
}

32.合集相关

var letters = Set<Character>() // 初始化一个存储Character类型的空的合集 
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"] // 使用字面量语法初始化 并且显式声明了类型信息 可以省略
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.字典

var namesOfIntegers = [Int: String]() // 使用简写初始化一个空字典
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"] // 使用字面量语法初始化一个字典 并显式声明类型 可以省略
airports["LHR"] = "London" // 如果`LHR`这个Key已经存在 则更新这个值 否则添加这个值
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.")
}
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.")
}
for (airportCode, airportName) in airports {
    print("\(airportCode): \(airportName)")
}
上一篇下一篇

猜你喜欢

热点阅读