Swift4.0官方文档学习笔记

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

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)")
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • 86.复合 Cases 共享相同代码块的多个switch 分支 分支可以合并, 写在分支后用逗号分开。如果任何模式...
    无沣阅读 1,327评论 1 5
  • 标签(空格分隔): 未分类 基础(相关概念) 1.元祖 元组(tuples)把多个值组合成一个复合值。元组内的值可...
    一生信仰阅读 588评论 0 0
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,710评论 2 9
  • 这是你不管是乘机还是乘车冲出草原时,在这个巨大农区盆地第一个扑面而来的,在阳光下金光闪烁的美丽寺庙,让人心情...
    山神山神阅读 1,225评论 0 0
  • 有句成语兼俗语叫做“事不过三”,指有些事情不可反复多次做。比如,你欠人钱不还,还要再去借,脾气好人品正心地善的人...
    Kitekiss阅读 953评论 1 4