哈啰,我们又见面了,上个月我们完成了 初学后端 的系列文章,这次我们开始了新的奇幻冒险旅程,要来 iOS
的世界杀怪练等了 !
1. 基础使用
最一开始,要先熟悉的就是程式语言的 语法,有点像是你进入到一个新的游戏世界之后,你最先要做的,就是去知道游戏世界的人在讲些什么,听懂、看懂他们说的话之后,才能跟 NPC 说话、解任务。
1.1 宣告变数 (Variable Declaration)
用 var
宣告可变的变数,用 let
宣告不可变的常数。
// 变数,这点跟 Kotlin 是一样的var justme = "我是 RS 唷~"// 常数,不可变// 在 Kotlin 是使用 `val constant = "我不可以被变更"`let constant = "我不可以被变更"// 也可以用 显式(Explicit) 直接讲明变数的型别let name : String = "RS"var age : Int = 25// 跨型别输出的串接,可以用加号 `+`,但要自己转字串// 也可以用 `\(variable)` 来串接print(name + "'s age is " + String(age))print("After ten years, " + name + "'s age is \(age + 10)")/*输出为RS's age is 25After ten years, RS's age is 35*/
在 Swift 的世界中,可以用
\(variable)
安插变数在字串里,
和Python
的$(variable)
概念相似
1.2 变数範围
print("int max: \(Int.max) to min: \(Int.min)")/* 输出为 * int min: -9223372036854775808 to max: 9223372036854775807 */ print(pow(2, 63))/* 输出为 * 9223372036854775808 */ print(9223372036854775808)/* * Overflow Error */// 可以观察出,Int 的最大值是 2 的 63 次方 - 1
其他 primitives 的範围,就交给大家自己去找出来了。
1.3 流程控制
// if else,比较可惜的是还没支援範围运算符号(range operator)// 也就是以下的写法是 `错` 的if statusCode in 200...208 || statusCode == 226{...}// 以下是 `正确` 的if (200...208).contains(statusCode) || statusCode == 226 {print("Good, \(statusCode) \(status), get \(payload)")}else if(400...429).contains(statusCode) || statusCode == 431 || statusCode == 451 { print("Bad, \(statusCode) \(status), get \(payload)")}else {print("I don't know others, \(statusCode) \(status), get \(payload)")}// 如此一来,我就包含了 200~208、226 的範围// 觉得总有一天,会改成比较直觉的方式的~// -----------------------------------------------// switch case,预设不用写 break,// 需要继续执行到下一个 case 的话,// 就加 `callthrough` 关键字。// 如果是判断 tuple 的话,可以变得很弹性func testSwitch(data: (statusCode: Int, status: String, payload: Array<Int>)) { let statusCode = data.statusCode let status = data.status let payload = data.payload switch data { case (200, "OK", _): // `_`底线,代表的是那个栏位不限制值 print("Good, \(statusCode) \(status), get \(payload)") case (404, "NotFound", _): print("Bad, \(statusCode) \(status), get \(payload)") default: print("不能理解") }}// 执行看看testSwitch(data: (200, "OK", [9527, 9487, 9453, 5201314]))/* 输出为 * Good, 200 OK, get [9527, 9487, 9453, 5201314] */
先不要怕什么是 tuple
,等等就会提到了,它是其中一种资料而已。
Swift
的if else
和Kotlin
的if else
很像,差在条件句可以不用括号,要括号也是可以,和Python
的if else
概念一样,Python
可括号、也可不括号
Swift
的switch case
就保留了Java
式的switch case
,而且不用写break
关键字,相比之下,Python
拿掉了switch case
、Kotlin
改用when
,从这点可以感觉到Swift
身上,还看得到一点点旧式语言的影子,同时又改掉不方便的部分
摄影师:JESHOOTS.com,连结:Pexels
2. 资料结构
熟悉了 基本语法,还要再搭配 资料结构 才行,如果你觉得一次看这么多太吃力,可以先在这里休息一下,把上面的基础语法练熟,在 Xcode
的 Playground
自己多试试不同的组合,再进行到资料结构的阶段。
2.1 阵列 (Array
)
在 Swift
没有 List
,但 Swift
的 Array
的概念,就是跟 Python
的 List
和 Java
、Kotlin
的 ArrayList
很像。因为这个资料结构最常使用,所以特别讲多一点。
怎么创建 Array
?
// 一般的纯 Int arrayvar intArray = [9, 5, 2, 7]print(intArray)/* 输出为 * [9, 5, 2, 7] */// 如果要在 array 里放入多型别// 则必须 显式 宣告你的阵列var anyArray: [Any] = [0, 100, 3.14159, "Hi"]print(anyArray)/* 输出为 * [0, 100, 3.14159, "Hi"] */// 如果是要创建空 Array 的话,不能直接用空的中括号//var emptyArray = [] // Error// 需要 显式 宣告 Array,有三种显示宣告方式var firstArrayCreationMethod = [Int]()var secondArrayCreationMethod: [String] = []var thirdArrayCreationMethod: Array<String> = []
在
Swift
的Array
中,值得注意的是创建空Array
的方法,其中三种都可以,知道有这三种方法之后,就可以挑一个自己喜欢的方法,来作为固定使用
怎么取用 Array
内的值 ?
// 範围取值,拿 index 1~3print(anyArray[1...3])/* 输出为 * [100, 3.14159, "Hi"] */// 想知道 array 的长度// 在 Python 是 len(anyArray)// 在 Kotlin 是 anyArray.sizeprint(anyArray.count)/* 输出为 * 4 */// 从 0 到 anyArray 的长度-1// `..<` 对右边的数值 是 `不包含`print(anyArray[0..<anyArray.count])/* 输出为 * [0, 100, 3.14159, "Hi"] */// 从 0 到 anyArray 的长度-1// `...` 对右边的数值是 `包含`print(anyArray[0...anyArray.count-1])/* 输出为 * [0, 100, 3.14159, "Hi"] */// 单边的也可以print(anyArray[0...])/* 输出为 * [0, 100, 3.14159, "Hi"] */
在 Swift 的範围运算符号(range operator),是使用
...
、..<
来进行有包含/没包含的範围取值
怎么增/改/删 Array
内的值 ?
// 增,可以在 array 里面,再加入一个 arrayanyArray.append([10, 9, 8])print(anyArray)/* 输出为 * [0, 100, 3.14159, "Hi", [10, 9, 8]] */// 但如果要从 anyArray 拿出里面的 Array 的话// 拿出来的 array 会是 Any 型别// 取用之后还要强制转型回 Array,非常麻烦print((anyArray[4] as! [Int])[0])/* 输出为 * 10 */// 也可以针对 index 来插入anyArray.insert("插入!", at: 2)print(anyArray)/* 输出为 * [0, 100, "插入!", 3.14159, "Hi", [10, 9, 8]] */// 改,把 array 第一个值从 0 改成 字串// (注意:因为我的 array 是 Any 型别才可以这样做)anyArray[0] = "嘿嘿看我改你"print(anyArray)/* 输出为 * ["嘿嘿看我改你", 100, "插入!", 3.14159, "Hi", [10, 9, 8]] */// 删,针对某个 index 移除 arrayanyArray.remove(at: 1)print(anyArray)/* 输出为 * ["嘿嘿看我改你", "插入!", 3.14159, "Hi", [10, 9, 8]] */
在
Swift
的array
操作,用insert
插入值、用remove
移除值,修改值就直接用=
改值
2.2 Tuple
适合用来存放一些杂乱、临时产生的数值
// Tuple 是用小括号包住 (跟 Python 的 Tuple 一样)let tuple = ("这是", "iOS系列文章", "tuple还可包含多型别的变数哦", 9527, [94.87, 94, 87])print(tuple)/* 输出为 * ("这是", "iOS系列文章", "tuple还可包含多型别的变数哦", 9527, [94.87, 94.0, 87.0]) */// 显式 宣告 tuple,会让拿资料时更直觉let explicitTuple: (statusCode: Int, status: String, payload: [Int]) = (200, "OK", [1,2,3,4,5])print("GET \(explicitTuple.statusCode) \(explicitTuple.status): \(explicitTuple.payload)")/* 输出为 * GET 200 OK: [1, 2, 3, 4, 5] */
Swift
的Tuple
,和Kotlin
的Pair
、Python
的Tuple
概念相似
2.3 Dictionary
适合用来放有对应性的资料
// Dictionary 也是用中括号包住// 值得注意的是,Key 只能用同一种型别// Value 也是同一种型别// 而 Key 和 Value 可以不同型别let dictionary = [200: "OK", 404: "NotFound"]print(dictionary)/* 输出为 * [200: "OK", 404: "NotFound"] */// 增dic[500] = "InternalServerError"print(dic)/* 输出为 * [200: "OK", 404: "Error", 500: "InternalServerError"] */// 删,有两种方法dic[200] = nilprint(dic)/* 输出为 * [404: "Error", 500: "InternalServerError"] */dic.removeValue(forKey: 404)print(dic)/* 输出为 * [500: "InternalServerError"] */
Swift
的Dictionary
用起来的感觉,和Python
的dict
很像,但差别是在Python
的dict
是 大括号,而Swift
是 中括号
2.4 Set
适合用来放不要重複且顺序不重要的资料
// 用中括号包起来// 需要 显式 宣告,不然会变成 array// (Python 的 Set 是用大括号包起来)var set: Set = [9527, 9527, 9453, 5201314]print(set)/* 输出为 * [9527, 5201314, 9453] */ set.insert(12345)set.remove(9453)print(set)/* 输出为 * [9527, 5201314, 12345] */
Swift
的Set
,需要标明是Set
型别(显式),insert
和remove
则用起来跟上面几个很像
3. 总结
这次把 基本语法 和 资料结构 放在同一篇,是因为我等不及要赶快进入到下一个阶段了,所以略过了一些在 Python篇 有提到的细节,像是怎么宣告 primitive(Int
, Float
, Double
, String
等等)、各个 primitive 的範围、primitive 之间的转型之类的议题,我打算边实作边学,不在一开始就挖太深,可能之后有看到什么,觉得值得纪录的,再回来充实这篇文章。
到目前为止,接触 iOS
算是已经三天左右,还是被一堆术语跟语法搞混,像是我刚刚才发现,原来 「Swift
的 Protocol
就是 Java/Kotlin
的 Interface
」,还有「为什么 Swift
同时保留了 Struct
和 Class
?」、「Swift
的 Closure
跟 Java/Kotlin
的 Lambda
差在哪 ?」等等的问号疯狂冒出来,要一件一件是去釐清,真的是挺累的,不过就是需要走过这条路,才能把各程式语言之间的隔阂抹平,才不会各说各话,我说的术语你听不懂、你说的术语我也听不懂,造成沟通上的阻碍。
我是 RS,这是我的 不做怎么知道系列 文章,我们 下次见。
喜欢我的文章吗? 赶快来看看我都发了什么文章吧:我的文章目录欢迎阅读我的上一篇: [不做怎么知道系列之Android开发者偷学iOS的奇幻冒险 Day1] - 转生,重练 #新世界 #换颗脑袋 #目标欢迎阅读我的下一篇: [不做怎么知道系列之Android开发者偷学iOS的奇幻冒险 Day3] - 中离登出 #这么突然就GameOver的吗!? #系列暂停 #Android跨iOS好跨吗?