Swift 3 学习-01

Swift 3.png

在iOS 10 和微信小程序的大浪潮下,Swift 3 却少有人提及,前不久,iOS开发者翘首以盼的Swift 3终于来了, 就像很多人预测的一样,Swift 3的API基本趋于稳定,不会像以前一样改动的太大,让你无从下手,此时是最好的学习机会。尽管以前学习过部分,但决定重新梳理一下,从头开始,不积跬步无以至千里。入门学习资料,应该没有比官方更靠谱的吧。The Swift Programming Language (Swift 3)

  • 1 . 常量 let

如果你的代码存储的值不会改变,用let关键字声明为常量。let声明的值是不会再改变的,再次赋值会编译不过

let maximumNumberOfLoginAttempts = 10
  • 2 . 变量 var

声明变量的关键值,如果你代码中的值需要改变,请用var关键字声明为变量。

var currentLoginAttempt = 0
  • 3 . 打印 print()

和OC中的NSLog()类似,print("打印这个值 \\\\(值)")

  • 4 .分号 ;

不像许多其他语言,Swift并不要求你写一个分号(;代码中的每个语句后),当然你也可以这样做。然而,分号在Swift中的用法是如果你想要在一行上写多个独立的语句时需要:let cat = ""; print(cat)

  • 5 .整数

整数全是数字,没有小数部分,如42和-23。整数有符号类型(正,零或负的)或无符号类型(正或零)。Swift在8,16,32位和64位的形式提供有符号和无符号整数。这些整数遵循类似于C的命名约定,在一个8位的无符号整数的类型为UInt8,一个32位带符号整数的类型为Int32。

    • 5.1 .整数边界

可以访问整数类型的最小值和最大值min与max属性:

let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8
    • 5.2 .INT类型

在大多数情况下,你不需要挑整数的特定大小在代码中使用。Int,其具有的范围与当前平台的位数相同:
在32位的平台上,Int其大小与相同Int32。
在64位的平台上,Int其大小与相同Int64。
除非你有特殊的要求去限制整数的值,不然就不用特殊设置范围。在32位平台上,Int可以是-2,147,483,648和2,147,483,647的任意值,满足大多数要求,所以官方推荐直接使用Int,不自己区分位数。

    • 5.3 .UINT类型

与INT类型一致,只是无符号类型而已,不能表达负数。官方推荐使用Int

  • 6 .浮点型 Double,Float

浮点数是具有小数部分的数字,例如3.14159,0.1,和-273.15。在未声明类型时,Swift默认为Double.
Double 代表一个64位浮点数。
Float 表示32位浮点数。


6.0.png
  • 7 .类型安全和类型推断

Swift是一个类型安全的语言。类型安全的语言可以让你清楚地知道代码要处理的值的类型。如果你的代码的一部分需要一个String,你传递一个Int会直接报错。因为它会在编译你的代码时进行类型检查,并把不匹配的类型标记为错误。这可以让你在开发的时候尽早发现并修复错误。


7.0.png
let meaningOfLife = 42  //类型推断为int
let pi = 3.14159               //类型推断为double
let anotherPi = 3 + 0.14159  //类型推断为double
  • 8 . 数字表示

十进制数,没有前缀 let decimalInteger = 17
二进制数,用0b前缀 let binaryInteger = 0b10001
八进制数,有0o前缀 let octalInteger = 0o21
十六进制数,用0x前缀 let hexadecimalInteger = 0x11
当然你也可以这样写 let oneMillion = 1_000_000let oneMillion = 1000000等价

  • 9 .数字类型转换

在Swift中不同类型的数字不能直接运算,在编译期就会提示错误信息给你,防止隐藏的转换错误

let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
错误示例:let twoThousandAndOne = twoThousand + one   
正确写法:let twoThousandAndOne = twoThousand + UInt16(one)
 let three = 3
 let pointOneFourOneFiveNine = 0.14159  
错误示例:let pi = three + pointOneFourOneFiveNine
正确写法: let pi = Double(three) + pointOneFourOneFiveNine
9.0.png
  • 10 .类型别名 typealias

类型别名即给现有的类型起个别的名字。关键字为typealias。

typealias AudioSample = UInt16     //给UInt16起个别名AudioSample
var maxAmplitudeFound = AudioSample.min    //AudioSample.min等价于UInt16.min。
  • 11.布尔值 true false

提供了两个布尔常量值,true和false,如果你在需要使用 Bool 类型的地方使用了非布尔值,Swift 的类型安全机制会报错。


11.0.png

但是你可以这样写,i == 1 的比较结果是 Bool 类型,可以通过类型检查

let i = 1
if i == 1 {
// this example will compile successfully
}
  • 12 .元组

元组做的事情就是把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。和OC中的数组类似

    • 12.1 组合

你可以把任意顺序的类型组合成一个元组,这个元组可以包含所有类型。只要你想,你可以创建一个类型为 (Int, Int, Int) 或者 (String, Bool) 或者其他任何你想要的组合的元组。

let http404Error = (404, "Not Found")
// http404Error 的类型是 (Int, String),值是 (404, "Not Found")
    • 12.2 分解

你可以将一个元组的内容分解(decompose)成单独的常量和变量,然后你就可以正常使用它们了

let (statusCode, statusMessage) = http404Error
print("The status code is \\\\(statusCode)")
// 输出 "The status code is 404"
print("The status message is \\\\(statusMessage)")
// 输出 "The status message is Not Found"
    • 12.3 忽略

如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_)标记:

let (justTheStatusCode, _) = http404Error
print("The status code is \\\\(justTheStatusCode)")
// 输出 "The status code is 404"
    • 12.4 下标访问

此外,你还可以通过下标来访问元组中的单个元素,下标从零开始:

print("The status code is \\\\(http404Error.0)")
// 输出 "The status code is 404"
print("The status message is \\\\(http404Error.1)")
// 输出 "The status message is Not Found"
    • 12.5 命名获取

你可以在定义元组的时候给单个元素命名,给元组中的元素命名后,你可以通过名字来获取这些元素的值:

let http200Status = (statusCode: 200, description: "OK")
print("The status code is \\\\(http200Status.statusCode)")
// 输出 "The status code is 200"
print("The status message is \\\\(http200Status.description)")
// 输出 "The status message is OK"

可变元祖是可以赋值的,但在赋值时,可变元组虽然可以修改数据,但却不能改变其数据的数据类型:如下


12.5.png
  • 13 .可选类型 optionals

C 和 Objective-C 中并没有可选类型这个概念。最接近的是 Objective-C 中的一个特性,一个方法要么返回一个对象要么返回nil,nil表示“缺少一个合法的对象”。然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型,Objective-C 方法一般会返回一个特殊值(比如NSNotFound)来暗示值缺失。这种方法假设方法的调用者知道并记得对特殊值进行判断。然而,Swift 的可选类型可以让你暗示任意类型的值缺失,并不需要一个特殊值。
来看一个例子。Swift 的 Int 类型有一种构造器,作用是将一个 String 值转换成一个 Int 值。然而,并不是所有的字符串都可以转换成一个整数。字符串 "123" 可以被转换成数字 123 ,但是字符串 "hello, world" 不行。下面的例子使用这种构造器来尝试将一个 String 转换成 Int:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推测为类型 "Int?", 或者类型 "optional Int"
13.0.png
  • 14 .nil

Swift 的 nil 和 Objective-C 中的 nil 并不一样。在 Objective-C 中,nil 是一个指向不存在对象的指针。在 Swift 中,nil 不是指针——它是一个确定的值,用来表示值缺失。任何类型的可选状态都可以被设置为 nil,不只是对象类型。

  • 14.1 赋值

你可以给可选变量赋值为nil来表示它没有值,但nil不能用于非可选的常量和变量。

var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value
  • 14.2 声明

如果你声明一个可选常量或者变量但是没有赋值,它们会自动被设置为 nil:

var surveyAnswer: String?
// surveyAnswer is automatically set to nil
  • 15 .if 语句以及强制解析

你可以使用 if 语句和 nil 比较,来判断一个可选值是否包含值。你可以使用“相等”(==)或“不等”(!=)来执行比较。

if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
}
// Prints "convertedNumber contains some integer value."

当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(!)来获取值。这个惊叹号表示你知道这个可选有值,称为可选值的强制解析(官方文档的forced unwrapping):

if convertedNumber != nil {
print("convertedNumber has an integer value of \\\\(convertedNumber!).")
}
// Prints "convertedNumber has an integer value of 123."
  • 16 . 可选绑定 optional binding

使用可选绑定来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在 if 和 while 语句中,这种用法不仅可以用来判断可选类型中是否有值,同时可以将可选类型中的值赋给一个常量或者变量。

if let constantName = someOptional {
    statements
}

使用可选绑定来重写 possibleNumber

if let actualNumber = Int(possibleNumber) {
    print("\\\\"\\\\(possibleNumber)\\\\" has an integer value of \\\\(actualNumber)")
} else {
    print("\\\\"\\\\(possibleNumber)\\\\" could not be converted to an integer")
}

解读:如果Int(possibleNumber)返回的可选 Int 包含一个值,就创建一个叫做 actualNumber 的新常量并将可选包含的值赋给它。
如果转换成功,actualNumber 常量可以在 if 语句的第一个分支中使用。它已经被可选类型 包含的 值初始化过,所以不需要再使用 ! 后缀来获取它的值。在这个例子中,actualNumber 只被用来输出转换结果。
你可以在可选绑定中使用常量和变量。如果你想在if语句的第一个分支中操作 actualNumber 的值,你可以改成if var actualNumber,这样可选类型包含的值就会被赋给一个变量而非常量。

  • 17 .隐式解析可选类型implicitly unwrapped optionals

如上所述,可选类型暗示了常量或者变量可以“没有值”。可选可以通过 if 语句来判断是否有值,如果有值的话可以通过可选绑定来解析值。
有时候在程序架构中,第一次被赋值之后,可以确定一个可选类型总会有值。在这种情况下,每次都要判断和解析可选值是非常低效的,因为可以确定它总会有值。这种类型的可选状态被定义为隐式解析可选类型。把想要用作可选类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选类型。
当可选类型被第一次赋值之后就可以确定之后一直有值的时候,隐式解析可选类型非常有用。隐式解析可选类型主要被用在 Swift 中类的构造过程中。一个隐式解析可选类型其实就是一个普通的可选类型,但是可以被当做非可选类型来使用,并不需要每次都使用解析来获取可选值。下面的例子展示了可选类型 String 和隐式解析可选类型 String 之间的区别:

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
/*****下面是隐式解析可选类型 String *****/
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark

如果你在隐式解析可选类型没有值的时候尝试取值,会触发运行时错误。和你在没有值的普通可选类型后面加一个惊叹号一样。
所以你可以把隐式解析可选类型当做普通可选类型来判断它是否包含值:

if assumedString != nil {
print(assumedString)
}
// Prints "An implicitly unwrapped optional string."

你也可以在可选绑定中使用隐式解析可选类型来检查并解析它的值:

if let definiteString = assumedString {
print(definiteString)
}
// Prints "An implicitly unwrapped optional string."

如果一个变量之后可能变成nil的话请不要使用隐式解析可选类型。如果你需要在变量的生命周期中判断是否是nil的话,请使用普通可选类型。

可选类型 | 解读
----|------|----
普通可选类型 | 可选类型可以让你暗示任意类型的值缺失,并不需要一个特殊值。当你不确定你所赋予的那个值时,就用(String?)即 (类型?)。
隐式解析可选类型 | 在第一次被赋值之后,可以确定一个可选类型总会有值,把想要用作可选类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选类型。本质是普通可选类型,只是当做当做非可选类型来使用。

  • 17 .断言assert()

可选类型可以让你判断值是否存在,你可以在代码中处理值缺失的情况。然而,在某些情况下,如果值缺失或者值并不满足特定的条件,你的代码可能没办法继续执行。这时,你可以在你的代码中触发一个 断言 来结束代码运行并通过调试来找到值缺失的原因。给你一个代码调试工具 ,看个人喜好使用。不满足条件时会断点打印,会定位到具体错误行数,仅为DEBUG模式。


17.0.png

控制台需要断言信息

let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// this causes the assertion to trigger, because age is not >= 0

控制台不需要断言信息

let age = -3
assert(age >= 0)

以上只是一些简单的概念说(fan)明(yi),如有错误请指正,谢谢。Swift 3 学习 ,后续会不断更新。
如果你觉得我的文章对你有帮助请点喜欢哦,也可以关注我,每周至少一篇技术更新。
或者关注 我的专题 每周至少5篇高质量文章收录,多谢支持。
一起学习,一起进步。

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

推荐阅读更多精彩内容