Swift 笔记:闭包


Apple-Swift-logo

闭包是自包含的函数代码块,可以在代码中被传递和使用。闭包可以捕获和存储其所在上下文中任意常量和变量的引用,被称为包裹常量和变量。

闭包采取如下三种形式之一:

  • 全局函数是一个有名字但不会捕获任何值的闭包
  • 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包
  • 闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的匿名闭包

继续阅读 “Swift 笔记:闭包”

Swift 笔记:函数


Apple-Swift-logo

函数是一段完成特定任务的独立代码片段。在 Swift 中,每个函数都有一个由函数的参数值类型和返回值类型组成的类型。函数的定义可以写在其他函数定义中,这样可以在嵌套函数范围内实现功能封装。

函数的定义与调用

定义一个函数时,可以定义一个或多个有名字和类型的值,作为函数的输入,称为参数,也可以定义某种类型的值作为函数执行结束时的输出,称为返回类型。要使用一个函数时,用函数名来“调用”这个函数,并传给它匹配的输入值(称作实参),函数的实参必须与函数参数表里参数的顺序一致。

func sayHello(name: String) -> String {
    return "Hello, " + name + "!"
}
print(sayHello(name: "Ryan"))

继续阅读 “Swift 笔记:函数”

Swift 笔记:控制流


Apple-Swift-logo

Swift提供了多种流程控制结构,包括 for-in 循环、while 循环、if 语句、guard 语句、switch 语句、break 语句、continue 语句等。

For-In 循环

for-in 循环可以遍历一个集合中的所有元素:

let names = ["Anna", "Brain", "Jack", "Ryan"]
for name in names {
    print("Hello, \(name)!")
}

for-in 循环也可通过遍历一个字典来访问它的键值对:

let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
    print("\(animalName)s have \(legCount) legs")
}

for-in 循环可以使用数字范围:

for index in 1...5 {
    print("\(index) times 5 is \(index*5)")
}

如果不需要区间序列内每一项的值,可以使用下划线(_)替代变量名来忽略这个值。

继续阅读 “Swift 笔记:控制流”

Swift 笔记:集合类型


Apple-Swift-logo

Swift 语言提供数组(Arrays)、集合(Sets)和字典(Dictionaries)三种基本的集合类型来存储数据。数组是有序数据的集,集合是无序无重复数据的集,字典是无序的键值对的集。

CollectionTypes-intro

Arrays、Sets、Dictionaries 中存储的数据值类型必须明确,不能把不正确的数据类型插入其中。如果创建一个集合并分配为变量,那么这个集合将会是可变的;如果分配成变量,那么这个集合就是不可变的,它的大小和内容都不能被改变。 继续阅读 “Swift 笔记:集合类型”

Swift 笔记:字符串与字符


Apple-Swift-logo

字符串(String)是有序的字符(Character)类型的值的集合。Swift 中 String 和 Character 类型提供了快速和兼容 Unicode 的方式供代码使用。

字符串字面量

字符串字面量是由一对双引号包裹着的具有固定顺序的字符集:

let someStr = "Hello, Swift!"
var someStr2:String = "Hello, Swift!"
var someStr3 = String("Hello, Swift!")

多行字符串字面量是由一对三个双引号包裹着的具有固定顺序的文本字符集:

let quotation = """
This is a multiline string.
This is a multiline string, too.
"""

初始化空字符串

要创建一个空字符串作为初始值,可以将空的字符串字面量赋值给变量:

var emptyStr = ""
var anotherEmptyStr = String()

可以使用 isEmpty 属性来检查字符串是否为空:

if emptyStr.isEmpty {
    print("Nothing to see here")
}

继续阅读 “Swift 笔记:字符串与字符”

Swift 笔记:基础运算符


Apple-Swift-logo

Swift 支持大部分标准 C 语言的运算符,且改进许多特性来减少常规编码错误。Swift 中赋值运算(=)不能返回值,以防止与判断相等运算符(==)混淆。

运算符分为一元、二元和三元运算符。一元运算符对单一对象操作,分前置运算符和后置运算符,运算符与操作对象间不能加空格,必须紧密相连;二元运算符操作两个对象,是中置的;Swift 三元运算符只有一个,即三目运算符 a ? b : c

赋值运算符

赋值运算符(a = b),表示用 b 的值来初始化或更新 a 的值。需要注意的是 Swift 的赋值不返回值,不能做如下的判断:

if a = b {
    // 此句错误, 因为 x = y 并不返回任何值
}

算术运算符

Swift 中所有数值类型都支持基本的四则算术运算和求余运算:

  • 加法(+)
  • 减法(-)
  • 乘法(*)
  • 除法(/)
  • 求余(%)

加法运算符也可用于 String 的拼接。

组合赋值运算符

Swift 也提供把其他运算符和赋值运算(=)组合的组合赋值运算符,组合加运算(+=)是其中一个例子: 继续阅读 “Swift 笔记:基础运算符”

Swift 笔记:可选类型与 nil


可选类型

使用可选类型(Optionals)来处理值可能缺失的情况。可选类型表示:

  • 有值,等于 x

或者

  • 没有值
let pNum = "123"
let cNum = Int(pNum)
// cNum 被推测类型为 "Int?",或类型 "Optional Int"

问号暗示包含的值是可选类型,也就是说可能包含 Int 值也可能不包含值

nil

可选变量赋值为 nil 来表示它没有值。
nil 不能用于非可选有常量和变量。
如果在声明一个可选常量或变量时没有赋值,它们会自动被设置为 nil

if 语句以及强制解析

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

当确定可选类型确实包含值时,可以在可选值的名字后面加一个感叹号(!)来获取值。这被称为可选值的**强制解析(Forced Unwrapping):

let possibleNum = "123"
let convertedNum = Int(possibleNum)

if convertedNum != nil {
    print("convertedNum has an integer value of \(convertedNum!).")
}

可选绑定

使用可选绑定(Optional Binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时变量或者变量:

if let constantName = someOptional {
    statements
}

隐式解析可选类型

可选类型第一次被赋值后,可以确定总会有值,这种类型的可选状态被定义为隐式解析可选类型(Implicitly Unwrapped Optionals)。把想要用作可选的类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选类型。

Swift 笔记:数据类型


常用数据类型

  • Int: 整数型
  • Float: 32 位浮点数
  • Double: 64 位浮点数
  • Boolean: 布尔值
  • String: 字符串
  • Tuples: 元组

Int

一般来说,不需要专门指定整数的长度。Swift 提供了一个特殊的整数类型 Int,长度与当前平台的原生字长相同:

  • 在32位平台上,IntInt32 长度相同。
  • 在64位平台上,IntInt64 长度相同。

除非需要特定长度的整数,一般来说使用 Int 就够了,这可以提高代码一致性和可复用性。

对于比较大的数值,Swift 可以使用下划线 _ 来分隔位数:

let a = 1_000_000
let b = 1_000_000

UInt

Swift 也提供了一个特殊的无符号类型 UInt,长度与当前平台的原生字长相同。

注意:
尽量不要使用UInt,除非你真的需要存储一个和当前平台原生字长相同的无符号整数。除了这种情况,最好使用Int,即使你要存储的值已知是非负的。统一使用Int可以提高代码的可复用性,避免不同类型数字之间的转换,并且匹配数字的类型推断。

浮点数

Double 表示 64 位浮点数,Float 表示 32 位浮点数。Double 精确度很高,至少有 15 位数字,而 Float 只有 6 位数字,在两种类型都匹配的情况下,优先选择 Double

类型转换

值不能被隐式转换,如果需要转换为其他类型,必须进行显式转换:

let label = "The width is "
let width = 90
let widthLabel = label + String(width)

也可把值写到括号中,同时在括号之前写一个反斜杠来进行类型转换:

let widthLabel = label + "\(width)"

布尔值

Swift 有两个布尔常量,truefalse

元组

元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。

let http404Error = ( 404 , "Not Found!" )

元组可以在常量或变量名后使用冒号加括号的形式标注数据类型:

let http200Status: ( Int , String ) = ( 200 , "OK!" )

可以将一个元组的内容分解(decompose)成单独的常量和变量:

let ( errorCode , errorMessage ) = http404Error

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

let point = ( 5 , 2 )
point.0
point.1

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

let point = ( x: 5 , y: 2)
point.x
point.y

也可以在标注数据类型时给单个元素命名:

let point: ( x:Int , y:Int ) = ( 6 , 2 )
point.x
point.y

元组分解时需要忽略的元素使用下划线 _ 来标记:

let loginResult = ( true , "Ryan" )
let ( isLoginSuccess , _ ) = loginResult
if isLoginSuccess {
    print("Login Success!")
    }
else{
    print("Login Failed!")
    }

输出函数:print

使用函数 print(_:separator:terminator:) 来输出当前常量或者变量的值。

var x = 1 , y = 2 , z = 3

print ( x , y , z , separator:"---")
// 输出结果为 1---2---3

print ( x , terminator:":)")
// 输出结果为 1:)

separatorterminator 参数具有默认值,调用时可以忽略。默认情况下,separator 使用空格作为间隔符,terminator 使用换行符来结束当前行。如果不想换行,可以传递一个空字符串给 terminator 函数:

print ( someValue , terminator:"" )

Swift 笔记:常量与变量


使用 let 声明常量,使用 var 声明变量。常量的值一旦设定就不能改变,而变量的值可以随意更改。

命名

可以使用任意字符作为常量或变量名称,包括 Unicode 字符。为保证代码的可读性,通常情况下常量或变量名称使用除首单词外其余单词首字母大写的方式命名:

let 😀 = "smile"
let myWebsite = "https://iiiryan.com"

常量与变量名不能包含数学符号,箭头,保留的(或者非法的)Unicode 码位,连线与制表符。也不能以数字开头,但是可以在常量与变量名的其他地方包含数字。

一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类型。同时,你也不能将常量与变量进行互转。

分号

单行语句末尾可以不添加分号 ;,但有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句:

let a = 5 ; print(a)
// 输出 a

单行语句可以同时声明多个变量或常量,使用 , 分隔。

var myVariable = 10
let myConstant = 8

var a = 1 , b = 2 , c = 3

类型标注

Swift 是一种强类型语言,编译器会根据声明赋值自动推断数据类型。如果要添加类型标注,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称。

var str = "Hello, Swift!"
var myWebsite: String = "https://iiiryan.com"

注释代码

单行注释以双正斜杠 // 作为起始标记,多行注释以 /* 开始,以 */ 结束。
多行注释可以嵌套在其它的多行注释之中