[不做怎么知道系列之Android开发者偷学iOS的奇幻冒险 Day2] - 解新手主线任务 #耐住性子不越级打怪 #S

http://img2.58codes.com/2024/20124548twI607Ye59.png

哈啰,我们又见面了,上个月我们完成了 初学后端 的系列文章,这次我们开始了新的奇幻冒险旅程,要来 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,等等就会提到了,它是其中一种资料而已。

Swiftif elseKotlinif else 很像,差在条件句可以不用括号,要括号也是可以,和 Pythonif else 概念一样,Python 可括号、也可不括号

Swiftswitch case 就保留了 Java 式的 switch case,而且不用写 break 关键字,相比之下,Python 拿掉了 switch caseKotlin 改用 when,从这点可以感觉到 Swift 身上,还看得到一点点旧式语言的影子,同时又改掉不方便的部分

https://images.pexels.com/photos/442576/pexels-photo-442576.jpeg?cs=srgb&amp;dl=ps4-442576.jpg&amp;fm=jpg

摄影师:JESHOOTS.com,连结:Pexels


2. 资料结构

熟悉了 基本语法,还要再搭配 资料结构 才行,如果你觉得一次看这么多太吃力,可以先在这里休息一下,把上面的基础语法练熟,在 XcodePlayground 自己多试试不同的组合,再进行到资料结构的阶段。

2.1 阵列 (Array)

Swift 没有 List,但 SwiftArray 的概念,就是跟 PythonListJavaKotlinArrayList 很像。因为这个资料结构最常使用,所以特别讲多一点。

怎么创建 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> = []

SwiftArray 中,值得注意的是创建空 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]] */

Swiftarray 操作,用 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] */

SwiftTuple,和 KotlinPairPythonTuple 概念相似

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"] */

SwiftDictionary 用起来的感觉,和 Pythondict 很像,但差别是在 Pythondict 是 大括号,而 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] */

SwiftSet,需要标明是 Set 型别(显式),insertremove 则用起来跟上面几个很像

3. 总结

这次把 基本语法 和 资料结构 放在同一篇,是因为我等不及要赶快进入到下一个阶段了,所以略过了一些在 Python篇 有提到的细节,像是怎么宣告 primitive(Int, Float, Double, String 等等)、各个 primitive 的範围、primitive 之间的转型之类的议题,我打算边实作边学,不在一开始就挖太深,可能之后有看到什么,觉得值得纪录的,再回来充实这篇文章。

到目前为止,接触 iOS 算是已经三天左右,还是被一堆术语跟语法搞混,像是我刚刚才发现,原来 「SwiftProtocol 就是 Java/KotlinInterface」,还有「为什么 Swift 同时保留了 StructClass ?」、「SwiftClosureJava/KotlinLambda 差在哪 ?」等等的问号疯狂冒出来,要一件一件是去釐清,真的是挺累的,不过就是需要走过这条路,才能把各程式语言之间的隔阂抹平,才不会各说各话,我说的术语你听不懂、你说的术语我也听不懂,造成沟通上的阻碍。

我是 RS,这是我的 不做怎么知道系列 文章,我们 下次见。


喜欢我的文章吗? 赶快来看看我都发了什么文章吧:我的文章目录欢迎阅读我的上一篇: [不做怎么知道系列之Android开发者偷学iOS的奇幻冒险 Day1] - 转生,重练 #新世界 #换颗脑袋 #目标欢迎阅读我的下一篇: [不做怎么知道系列之Android开发者偷学iOS的奇幻冒险 Day3] - 中离登出 #这么突然就GameOver的吗!? #系列暂停 #Android跨iOS好跨吗?

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章