{"id":15639090,"url":"https://github.com/jaywcjlove/swift-tutorial","last_synced_at":"2025-04-06T02:09:27.224Z","repository":{"id":14492637,"uuid":"76625923","full_name":"jaywcjlove/swift-tutorial","owner":"jaywcjlove","description":"Swift入门教程、读书笔记","archived":false,"fork":false,"pushed_at":"2024-10-07T22:00:56.000Z","size":328,"stargazers_count":105,"open_issues_count":1,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-29T10:38:48.694Z","etag":null,"topics":["ios","swift","swift5","swiftui"],"latest_commit_sha":null,"homepage":"https://jaywcjlove.github.io/swift-tutorial","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaywcjlove.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"jaywcjlove","buy_me_a_coffee":"jaywcjlove","custom":["https://www.paypal.me/kennyiseeyou","https://jaywcjlove.github.io/#/sponsor"]}},"created_at":"2016-12-16T05:55:34.000Z","updated_at":"2024-10-13T07:37:24.000Z","dependencies_parsed_at":"2022-08-07T08:00:18.437Z","dependency_job_id":"a347935a-7103-4a29-8349-55244e9e6de2","html_url":"https://github.com/jaywcjlove/swift-tutorial","commit_stats":{"total_commits":47,"total_committers":3,"mean_commits":"15.666666666666666","dds":"0.19148936170212771","last_synced_commit":"7795f16e7b189cbd579d10fda539c4f21dcc4a14"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaywcjlove%2Fswift-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaywcjlove%2Fswift-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaywcjlove%2Fswift-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaywcjlove%2Fswift-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaywcjlove","download_url":"https://codeload.github.com/jaywcjlove/swift-tutorial/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247423515,"owners_count":20936626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","swift","swift5","swiftui"],"created_at":"2024-10-03T11:24:42.673Z","updated_at":"2025-04-06T02:09:27.204Z","avatar_url":"https://github.com/jaywcjlove.png","language":null,"funding_links":["https://ko-fi.com/jaywcjlove","https://buymeacoffee.com/jaywcjlove","https://www.paypal.me/kennyiseeyou","https://jaywcjlove.github.io/#/sponsor"],"categories":["miscellaneous"],"sub_categories":[],"readme":"\u003c!--idoc:ignore:start--\u003e\nSwift入门教程、读书笔记\n===\n\u003c!--idoc:ignore:end--\u003e\n\n[![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor)\n[![CI](https://github.com/jaywcjlove/swift-tutorial/actions/workflows/ci.yml/badge.svg)](https://github.com/jaywcjlove/swift-tutorial/actions/workflows/ci.yml)\n\n如果你已经掌握了一些 Swift 语法基础了，可以通过 [SwiftUI Example](https://github.com/jaywcjlove/swiftui-example) 来练习一些示例进行技术的提升。\n\n✦ 欢迎下载我的 [macOS/iOS](https://wangchujiang.com/#app) 应用程序来支持我，谢谢 ✦\n\n\u003cdiv style=\"display: inline_block\"\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/videoer/\" title=\"Videoer for macOS\"\u003e\u003cimg align=\"center\" alt=\"Videoer\" height=\"52\" width=\"52\" src=\"https://github.com/user-attachments/assets/12c02a7a-109e-4048-91f4-ab2dfd1e264e\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/key-clicker/\" title=\"KeyClicker for macOS\"\u003e\u003cimg align=\"center\" alt=\"KeyClicker\" height=\"50\" width=\"50\" src=\"https://github.com/user-attachments/assets/5a19fcb9-cb81-4855-b4ea-31c604d9612a\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/daybar/\" title=\"DayBar for macOS\"\u003e\u003cimg align=\"center\" alt=\"DayBar\" height=\"50\" width=\"50\" src=\"https://github.com/user-attachments/assets/b67d4a2e-92e2-4d8c-8c6f-2a1eb3e2fa93\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/iconed/\" title=\"Iconed for macOS\"\u003e\u003cimg align=\"center\" alt=\"Iconed\" height=\"50\" width=\"50\" src=\"https://github.com/user-attachments/assets/8a35dc7b-4faf-4e2a-9311-f66d6844a896\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/rightmenu-master/\" title=\"RightMenu Master for macOS\"\u003e\u003cimg align=\"center\" alt=\"RightMenu Master\" height=\"50\" width=\"50\" src=\"https://github.com/user-attachments/assets/39a76541-71bf-4de7-a01c-c62f0557dff5\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/paste-quick/\" title=\"Paste Quick for macOS\"\u003e\u003cimg align=\"center\" alt=\"Quick RSS\" height=\"50\" width=\"50\" src=\"https://github.com/user-attachments/assets/bdaad5b7-9810-44ce-8f17-8410864465d2\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/quick-rss/\" title=\"Quick RSS for macOS/iOS\"\u003e\u003cimg align=\"center\" alt=\"Quick RSS\" height=\"50\" width=\"50\" src=\"https://github.com/user-attachments/assets/374106b5-a448-4d1d-9ccb-b04b6bc681ed\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/web-serve/\" title=\"Web Serve for macOS\"\u003e\u003cimg align=\"center\" alt=\"Web Serve\" height=\"50\" width=\"50\" src=\"https://github.com/user-attachments/assets/e1d9f76f-0f3d-4ba5-8a15-253ee173bb1c\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/copybook-generator/\" title=\"Copybook Generator for macOS/iOS\"\u003e\u003cimg align=\"center\" alt=\"Copybook Generator\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/b90e42ff-158b-4534-82ca-5898fd0e8d73\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/devtutor/\" title=\"DevTutor for macOS/iOS\"\u003e\u003cimg align=\"center\" alt=\"DevTutor for SwiftUI\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/f15c154d-0192-48eb-8e0e-9e245ffd974a\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/regex-mate/\" title=\"RegexMate for macOS/iOS\"\u003e\u003cimg align=\"center\" alt=\"RegexMate\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/aabe5aa9-9a96-4390-8bed-c3e4023d0dea\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/time-passage/\" title=\"Time Passage for macOS/iOS\"\u003e\u003cimg align=\"center\" alt=\"Time Passage\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/time-passage/assets/1680273/6f30e429-e6f3-4dbe-9921-a5effe2a05e9\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/IconizeFolder/\" title=\"IconizeFolder for macOS\"\u003e\u003cimg align=\"center\" alt=\"Iconize Folder\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/fa9d8b9c-1e51-4ded-877c-fa5b21c47220\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/TextSoundSaver/\" title=\"Textsound Saver for macOS/iOS\"\u003e\u003cimg align=\"center\" alt=\"Textsound Saver\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/0595e842-980b-4574-8891-a8ba853a08be\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/create-custom-symbols/\" title=\"Create Custom Symbols for macOS\"\u003e\u003cimg align=\"center\" alt=\"Create Custom Symbols\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/8cd022ce-a3f1-4e89-b7c6-6fbd0d4db77c\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/DevHub/\" title=\"DevHub for macOS\"\u003e\u003cimg align=\"center\" alt=\"DevHub\" height=\"50\" width=\"50\" src=\"https://github.com/user-attachments/assets/4a44a4fd-67ce-430b-af0a-72f18feaa47d\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/ResumeRevise/\" title=\"Resume Revise for macOS\"\u003e\u003cimg align=\"center\" alt=\"Resume Revise\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/c9954a20-1905-48de-bdf8-d71837974aa2\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/palette-genius/\" title=\"Palette Genius for macOS\"\u003e\u003cimg align=\"center\" alt=\"Palette Genius\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/27340413-d355-45b2-8f6f-6ac37682d957\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/symbol-scribe/\" title=\"Symbol Scribe for macOS\"\u003e\u003cimg align=\"center\" alt=\"Symbol Scribe\" height=\"50\" width=\"50\" src=\"https://github.com/jaywcjlove/jaywcjlove/assets/1680273/c7249f05-fa70-4def-a1e9-571d5f171fc9\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n\u003c!--idoc:ignore:start--\u003e\n\n## 示例目录\n\n- [准备环境](#准备环境)\n- [swiftc命令](#swiftc命令)\n- [print](#print)\n- [字符串拼接](#字符串拼接)\n- [注释](#注释)\n- [常量、变量](#常量变量)\n- [运算符](#运算符)\n- [数据类型](#数据类型)\n  - [数值类型](#数值类型)\n  - [数值范围](#数值范围)\n  - [类型别名](#类型别名)\n  - [类型安全](#类型安全)\n  - [类型推断](#类型推断)\n  - [元组和集合](#元组和集合)\n- [可选和隐式可选类型](#可选和隐式可选类型)\n  - [可选类型](#可选类型)\n- [问题解决](#问题解决)\n- [工具](#工具)\n- [Web框架](#web框架)\n- [参考教程](#参考教程)\n\n\u003c!--idoc:ignore:end--\u003e\n\n## 准备环境\n\n在 Mac 上学习 Swift 非常简单，你只需在 App Store 中安装 [Xcode](https://itunes.apple.com/cn/app/xcode/id497799835) 即可。接下来，你有两种方法来学习 Swift 基础语法。\n\n**方法一：通过命令行**  \n\n你只需打开 Terminal 运行 swift 命令即可：\n\n```\n$ swift\nWelcome to Apple Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1). Type :help for assistance.\n  1\u003e var str = \"Hello Siwft!\"\nstr: String = \"Hello Siwft!\"\n  2\u003e:q   //:q是推出命令\n```\n\n运行 Swift 文件，在学习过程中，可以把一些存成 .swift 后缀的文件，通过 `swift filename.swift` 命令运行它输出结果。\n\n**方法二：通过Xcode运行**  \n\n打开 Xcode 软件，可以看到一个Xcode的欢迎界面，如果欢迎界面没有出来，你可以使用快捷键唤出 `⇧+⌘+1`(shift+command+1)，在欢迎界面上可以看到 **Get started with a playground** 菜单，点击它建立一个 playground 的文件。我们可以在上面写代码，实时运行 swift 代码打印出运行结果。\n\n## swiftc命令\n\n上面通过swift运行程序，同时我们可以通过swiftc编译命令，编译成一个可执行的文件，直接运行可执行文件，遐想一下，感觉我们用swift可以干好多活儿。下面来运行一个 Hello World。\n\n我们使用函数 print 来输出一个 Hello World 字符串。建立一个 [demo1.swift](examples/demo1.swift) 输入下面代码，放到了 examples 目录中：\n\n```\nprint(\"Hello world!\")\n```\n \n将 examples 目录中的 [demo1.swift](examples/demo1.swift) 文件，编译出的可执行文件输出到 examples 目录中 文件名为 demo\n\n```\nswiftc examples/demo1.swift -o examples/demo\n```\n\n通过 swift 运行 demo 并输出 Hello world!。\n\n```\n./examples/demo\n```\n\n## print\n\n它是一个输出函数，在 [demo1.swift](examples/demo1.swift) 中我们使用过这个函数，现在建立 [demo1.swift](examples/demo1.swift) 文件，通过print函数输出多个值，使用 print的参数separator将分隔符自定义一下。例如：\n\n```swift\nlet year = 1987\nvar month = 11\nvar day = 3\nprint(year,month,day,separator:\"-\")\n```\n\n运行测试它，我们将看到输出结果：\n\n```\n$ swift examples/demo2.swift\n1987-11-3\n```\n\n## 字符串拼接\n\n特别注意，在变量上面可以使用`+`来拼接字符串，常量拼接字符串会报错，常量和变量拼接同样报错。[demo12.swift](examples/demo12.swift)\n\n```swift\nvar version = 3\nlet tutorial = \"Swift \\(version) tutorial\"\nlet message = \"Hello \\(tutorial)!\"\nvar name = \"Hello !\" + \"sdsd\"\nprint(tutorial)\nprint(message)\n```\n\n## 注释\n\nSwift注释与JS注释一样。\n\n段落注释\n\n```swift\n/*\n 这里是段落注释\n */\n```\n\n单行注释\n\n```swift\n// 这里是单行注释\n```\n\n## 常量、变量\n\n- let常量，不能更改的值（immutable）\n- var变量，可以更改的值（mutable）\n\n声明一个名字叫做 constNumber 的常量，并给它一个值 1987 ，声明一个名字叫做 variableNumber 的变量，并给它一个值为 13，分别输出 constNumber 和 variableNumber 的值，将它保存到 [demo3.swift](examples/demo3.swift) 中：\n\n```swift\nlet constNumber = 1987\nvar variableNumber = 13\n\nprint(constNumber)\nprint(variableNumber)\n```\n\n运行测试它，我们将看到输出结果：\n\n```\n$ swift examples/demo3.swift\n1987\n13\n```\n\n通过上面的例子，我们来测试一下常量和变量的特性，下面代码保存到 [demo4.swift](examples/demo4.swift) 文件中\n\n```swift\nlet constNumber = 1987\nvar variableNumber = 13\nconstNumber = variableNumber + 1\nprint(constNumber)\n```\n\n上面这个错误的例子是，将变量 variableNumber 加 1 赋值给常量 constNumber。这是一个错误的演示，它运行会曝出错误信息，如果你使用 Xcode 将自动有个错误提示，你只需直接点击错误信息就可以自动修改错误，好智能的功能哦。\n\n```\n$ swift examples/demo4.swift\nexamples/demo4.swift:4:13: error: cannot assign to value: 'constNumber' is a 'let' constant\nconstNumber = variableNumber + 1\n~~~~~~~~~~~ ^\nexamples/demo4.swift:1:1: note: change 'let' to 'var' to make it mutable\nlet constNumber = 1987\n^~~\nvar\n```\n\n## 运算符\n\n用来做运算的，上面例子已经使用了运算符 `-`，其实就是跟数学运算是一样的\n\n- 加`+`\n- 减`-`\n- 乘`*`\n- 除`/`\n- 求余`%`\n- 相等`==`\n- 不等于`a != b`\n- 大于`a \u003e b`\n- 小于`a \u003c b`\n- 大于等于`a \u003e= b`\n- 小于等于`a \u003c= b`\n\n**赋值运算符** [demo5.swift](examples/demo5.swift)  \n\n```swift\nlet constNumber = 1987              // 声明常量 constNumber 值为 1987\nvar variableNumber = 13             // 声明变量 variableNumber 值为 13\nvariableNumber = constNumber - 1    // 这里赋值，常量 constNumber 减 1 赋值给变量 variableNumber\nprint(variableNumber)               // 将 variableNumber 最终的值输出\n```\n\n运行结果\n\n```bash\n$ swift examples/demo5.swift\n1986\n```\n\n**算数运算符** [demo6.swift](examples/demo6.swift)  \n\n算数运算符也就是我们常见到的数学运算了，加`+`、 减`-`、 乘`*`、 除`/`、 求余`%`。\n\n```swift\nprint(1 + 2 + 3)           //  输出 6\nprint(15 - 3)              //  输出 12\nprint(23 * 3)              //  输出 69\nprint(100.0 / 2.5)         //  输出 40.0\nprint(90 % 4)              //  输出 2\nprint(\"Hello \" + \"Swift!\") //  输出 Hello Swift!\n```\n\n运行结果\n\n```bash\n$ swift examples/demo6.swift\n6\n12\n69\n40.0\n2\nHello Swift!\n```\n\n**组合赋值运算符**  \n\n比如下面这样的代码，我们完全可以使用组合赋值运算符简写。\n\n```swift\nvar variableNumber = 13\n\n// 这句是可以使用组合赋值运算符简写\nvariableNumber = variableNumber + 1\n\n// 简写\nvariableNumber += 1\n```\n\n来个各种合赋值运算符例子 [demo7.swift](examples/demo7.swift)\n\n```swift\nvar example = 13\n\nprint(\"输出结果：\",example)\nexample += 1\nprint(\"输出结果：\",example)\nexample -= 1\nprint(\"输出结果：\",example)\nexample *= 2\nprint(\"输出结果：\",example)\nexample /= 1\nprint(\"输出结果：\",example)\nexample %= 1\nprint(\"输出结果：\",example)\n```\n\n**比较运算符**  \n\n可以通过 相等`==`、 不等于`a != b`、 大于`a \u003e b`、 小于`a \u003c b`、 大于等于`a \u003e= b`、 小于等于`a \u003c= b`进行比较运算。\n\n例如：`print(12 != 1)` 将会返回一个布尔值 ture\n\n\n**三目运算符**[demo8.swift](examples/demo8.swift)  \n\n三目运算符也就是三元运算符 `判断条件 ? 答案 1 : 答案 2`\n\n```swift\nvar a = 86\nvar b = a != 86 ? \"歪果仁\" : \"中国人\"\nprint( b )\n```\n\n**区间运算符**  \n\n- 闭区间运算符（`a...b`）定义一个包含从 a 到 b（包括 a 和 b）的所有值的区间。a 的值不能超过 b。\n- 半开区间（`a..\u003cb`）定义一个从 a 到 b 但不包括 b 的区间。之所以称为半开区间，是因为该区间包含第一个值而不包括最后的值。\n\n```swift\n1...5\n1..\u003c5\n// 分别表示 1 到 5 和 1 到 4。\n```\n\n关于它的使用，可以配合 for-in 语句，看到下面代码对于 `...` 和 `..\u003c` 之间的不同[demo9.swift](examples/demo9.swift)：\n\n```swift\nprint(\"将输出 1 到 5\")\nfor i in 1...5 {\n    print(i)\n}\nprint(\"只输出 1 到 4\")\nfor i in 1..\u003c5 {\n    print(i)\n}\n```\n\n**逻辑运算符**[demo10.swift](examples/demo10.swift)  \n\n三个标准的逻辑运算，非`!`、与`\u0026\u0026`、或`||`\n\n```swift\nvar a = true\nvar b = false\nprint(!a)           // 输出 false\nprint(a \u0026\u0026 b)       // 输出 false\nprint(a || b)       // 输出 true\n```\n\n\n## 数据类型\n\n在前面的例子中使用了`let` 和 `var` 声明常量和变量，并给这个常量或者变量赋值，Swift 默认情况直接根据后面的赋值，来确定这个变量或者常量的类型，这个是Swift的一个简写方式。那么完整的一个声明变量或常量，是下面的样子[demo11.swift](examples/demo11.swift)\n\n```swift\nlet constNumber: Int = 1987\nvar name : String = \"我是调调！\"\n\nprint(constNumber)\nprint(name)\n```\n\n### 数值类型\n\nSwift 提供了非常丰富的数据类型\n\n**整数类型**\n\n\u003e (Int)\n\n一般来说，你不需要专门指定整数的长度。Swift 提供了一个特殊的整数类型Int，长度与当前平台的原生字长相同[demo13.swift](examples/demo13.swift)：\n\n- 在32位平台上，Int和Int32长度相同。\n- 在64位平台上，Int和Int64长度相同。\n\n```swift\nvar version :Int32 = 3\nvar version2 :Int64 = 30\n\nprint(version)\nprint(version2)\n```\n\n**浮点数**\n\n- Double表示64位浮点数。当你需要存储很大或者很高精度的浮点数时请使用此类型。\n- Float表示32位浮点数。精度要求不高的话可以使用此类型。\n\n\u003e 注意：\n\u003e Double精确度很高，至少有15位数字，而Float最少只有6位数字。选择哪个类型取决于你的代码需要处理的值的范围。\n\n**无符号类型**\n\n\u003e (UInt)\n\nSwift 也提供了一个特殊的无符号类型UInt。\n\n\u003e 注意：\n\u003e 尽量不要使用UInt，除非你真的需要存储一个和当前平台原生字长相同的无符号整数。除了这种情况，最好使用Int，即使你要存储的值已知是非负的。统一使用Int可以提高代码的可复用性，避免不同类型数字之间的转换，并且匹配数字的类型推断。\n\n\n**布尔类型**\n\n\u003e (Bool)\n\nSwift 有一个基本的布尔（Boolean）类型，叫做Bool。布尔值指逻辑上的值，因为它们只能是真或者假。Swift 有两个布尔常量，true和false。\n\n**字符和字符串类型**\n\n\u003e (Character/String)\n\n只包含一个字符的时候，我们也可以把它作为字符类型，Character 只是 String 的一种特殊情况，一般来说，我们都使用 String 就好了[demo19.swift](examples/demo19.swift)：\n\n```swift\nvar ch: Character = \"a\"\nvar emptyString = \"\"               // 空字符串字面量\nvar anotherEmptyString = String()  // 初始化 String 实例\n// 两个字符串均为空并等价。\n// 通过检查其Boolean类型的isEmpty属性来判断该字符串是否为空\nif emptyString.isEmpty {\n    print(\"什么都没有\")\n}\n// 打印输出：\"什么都没有\"\nlet unusualMenagerie = \"Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪\"\nprint(\"unusualMenagerie has \\(unusualMenagerie.characters.count) characters\")\n// 打印输出：\"unusualMenagerie has 40 characters\"\n\n// +相加在一起（或称“串联”)\nvar str1 = \"hello\";\nvar str2 = \" there\";\nvar str = str1 + str2;\nprint(str);\n// welcome 现在等于 \"hello there\"\n\nlet normal = \"Could you help me, please?\"\n// 转化大写\nlet shouty = normal.uppercaseString\n// shouty 值为 \"COULD YOU HELP ME, PLEASE?\"\n// 转化小写\nlet whispered = normal.lowercaseString\n// whispered 值为 \"could you help me, please?\"\n```\n\n- 一个字符串中并不一定占用相同的内存空间\n\n字符串常量可以包括下面这些特殊字符：\n\n- 空字符`\\0`，反斜杠`\\`，制表符`\\t`，换行符`\\n`，回车符`\\r`，双引号`\\\"`和单引号`\\'`\n- 单字节Unicode字符，`\\xnn`，其中nn是两个十六进制数\n- 双字节Unicode字符，`\\unnnn`，其中nnnn是四个十六进制数\n- 四字节Unicode字符，`\\Unnnnnnnn`，其中nnnnnnnn是八个十六进制数\n\n\n**数组和字典**\n\n数组和字典是两种非常长常见的数据类型，在刚才介绍的类型中，一个量通常只能包含一个值。而数组这种类型，就可以容纳相同类型的的多个值；而字典这种类型，可以容纳多个对应关系（一个值唯一对应另一个值）\n\n```swift\nvar stringArray: [String] = [\"This\", \"is\", \"github\"]\n\n// 并通过下面的方式可以访问数组和字典中的值\nprint(stringArray[0])   // 访问第0个值, 数组的元素是从0开始记的\n```\n\n### 数值范围\n\n下表显示了不同变量类型内存的存储空间，及变量类型的最大最小值：\n\n| 类型 | 大小（字节） | 区间值 |\n| ---- | ---- | ---- |\n| Int8    | 1 字节    | -127 到 127  |\n| UInt8   | 1 字节    | 0 到 255  |\n| Int32   | 4 字节    | -2147483648 到 2147483647  |\n| UInt32  | 4 字节    | 0 到 4294967295  |\n| Int64   | 8 字节    | -9223372036854775808 到 9223372036854775807  |\n| UInt64  | 8 字节    | 0 到 18446744073709551615  |\n| Float   | 4 字节    | 1.2E-38 到 3.4E+38 (~6 digits)  |\n| Double  | 8 字节    | 2.3E-308 到 1.7E+308 (~15 digits)  |\n\n### 类型别名\n\n类型别名对当前的类型定义了另一个名字，类型别名通过使用 typealias 关键字来定义。语法格式如下：\n\n\u003e typealias 类型名字 = type\n\n```swift\n// 例如以下定义了 Int 的类型别名为 Feet：\ntypealias Feet = Int\n\n// 由于前面已经定义了类型别名，那么这里使用Feet也相当于使用Int\n// 所以AudioSample.min = Int.min,也就是0.  \nvar maxAmplitudeFound = Feet.min;\n// 几面输出 maxAmplitudeFound: Int = -9223372036854775808\n\n// 现在，我们可以通过别名来定义变量：\ntypealias:Feet = Intvar \ndistance: Feet = 100\nprint(distance)\n// 我们使用 playground 执行以上程序，输出结果为：\n// 100·\n```\n\n### 类型安全\n\nSwift 是一个类型安全（type safe）的语言。由于 Swift 是类型安全的，所以它会在编译你的代码时进行类型检查（type checks），并把不匹配的类型标记为错误。这可以让你在开发的时候尽早发现并修复错误。[demo16.swift](examples/demo16.swift)\n\n```swift\nimport Cocoa\nvar A = 42\nA = \"This is hello\"\nprint(A)\n```\n\n```bash\n$ swift examples/demo16.swift\nexamples/demo16.swift:3:5: error: cannot assign value of type 'String' to type 'Int'\nA = \"This is hello\"\n    ^~~~~~~~~~~~~~~\n```\n\n### 类型推断\n\n如果你没有显式指定类型，Swift 会使用类型推断（type inference）来选择合适的类型。[demo17.swift](examples/demo17.swift)\n\n```swift\n// a 会被推测为 Int 类型\nlet a = 42  \n\n// pi 会被推测为 Double 类型\nlet pi = 3.14159\n\n// anotherPi 会被推测为 Double 类型\n// 原始值3没有显式声明类型，而表达式中出现了一个浮点字面量，\n// 所以表达式会被推断为Double类型。\nlet anotherPi = 3 + 0.14159\n\nprint(anotherPi)\n//上面输出 3.14159\n```\n\n### 元组和集合\n\n元组不是一种类型，但是却是一种可以表示数据的结构。数组保存多个相同类型的值，而元组则可以保存多个不同类型的值，它的用法如下[demo15.swift](examples/demo15.swift)：\n\n```swift\nlet awesome = (\"Swift\", 3, \"awesome.\")\nlet (a, b, c) = awesome\nprint(a)    // 输出 Swift\nprint(b)    // 输出 3\nprint(c)    // 输出 awesome.\n\n// 和数组、字典不同的是，你不能通过[] 的方式来访问元组中的内容，但你可以像这样\nprint(awesome.0)\n```\n\n集合的声明和数组非常类似，都是通过 [] 进行，不同的地方在于集合只能容纳不同的值，而数组可以容纳相同的值：\n\n```swift\nlet sets: Set\u003cInt\u003e = [1, 2, 3, 4]\nlet arrays: Array\u003cInt\u003e = [1, 1, 1, 1]\n```\n\n上面定义了 sets 是一个 Set 集合类型，容纳的是 Int 类型的值，数组同理\n\n默认情况下，如果你不做显式声明，Swift 会默认将其推断为数组类型\n关于集合、数组、字典之间的关系，下面这张图很好的展示了这一切：[画图工具](http://asciiflow.com/)\n\n```bash\n      Array           Set                   Dictionary\n┏--------------┓ ┏---------------┓ ┏-------------------------┓\n┆ Index Value  ¦ ¦     Value     ¦ ¦  Keys          Values   ¦\n¦ ┌---┬------┐ ¦ ¦               ¦ ¦ ┌----┐        ┌-------┐ ¦\n¦ ¦0  ¦Six   ¦ ¦ ¦ ┌----┐        ¦ ¦ ¦YYZ ├-------▷¦Toronto¦ ¦\n¦ ├---┼------┤ ¦ ¦ ¦Rock¦ ┌----┐ ¦ ¦ ├----┤        └-------┘ ¦\n¦ ¦1  ¦Milk  ¦ ¦ ¦ └----┘ ¦Jazz¦ ¦ ¦ ¦DUB ├---┐              ¦\n¦ ├---┼------┤ ¦ ¦        └----┘ ¦ ¦ ├----┤   ¦    ┌-------┐ ¦\n¦ ¦2  ¦Flour ¦ ¦ ¦ ┌-----┐       ¦ ¦ ¦LHR ├---┼---▷¦London ¦ ¦\n¦ ├---┼------┤ ¦ ¦ ¦Class¦ ┌---┐ ¦ ¦ └----┘   ¦    └-------┘ ¦\n¦ ¦3  ¦Powder¦ ¦ ¦ └-----┘ ¦Cat¦ ¦ ¦          ¦              ¦\n¦ ├---┼------┤ ¦ ¦         └---┘ ¦ ¦          ¦    ┌-------┐ ¦\n¦ ¦4  ¦Hello ¦ ¦ ¦               ¦ ¦          └---▷¦Dubin  ¦ ¦\n¦ └---┴------┘ ¦ ¦               ¦ ¦               └-------┘ ¦\n┗--------------┛ ┗---------------┛ ┗-------------------------┛\n```\n\n## 可选和隐式可选类型\n\n- 类型后面用问号 `?` 表示可选类型；\n- 类型后面用感叹号 `!` 表示隐式可选类型；\n\n### 可选类型\n\n当基础类型（整形、浮点、布尔等）没有值时，是不能使用的。Swift 为了表达这种状态，对类型提供了可选的概念。在某个类型后面添加 ? 可以表示一个可选类型，这个可选类型有两种状态：1. 有值；2. 没值\n\n```swift\nvar optionalInteger: Int?\noptionalInteger = 404\n\nif optionalInteger != nil {   // 确定可选类型包含值后可以在变量名后加!强制解析\n    print(optionalInteger!)   // 404\n}\n\nvar errorCode: Int? = 404  // 在类型后面添加一个?\nprint(errorCode)           // Optional(404)  // 会打印警告\nerrorCode = nil            // 对非可选类型赋值为nil会报错\nprint(errorCode)           // nil            // 会打印警告\n\n// 确定可选类型包含值后可以在变量名后加!强制解析\nif errorCode != nil {\n    print(errorCode!)// 404\n}\n```\n\n## 问题解决\n\n- [swift NameError: name 'run_one_line' is not defined](https://github.com/Homebrew/homebrew-core/issues/2712)\n\n## 工具\n\n- [Carthage](https://github.com/Carthage/Carthage) 一个简单的，分散的Cocoa依赖管理器\n- [CocoaPods](https://github.com/CocoaPods/CocoaPods) Swift和Objective-C Cocoa项目的依赖管理器。\n\n## Web框架\n\n- [apple/swift-nio](https://github.com/apple/swift-nio)\n- [Vapor](https://github.com/vapor/vapor)\n- [Perfect](https://github.com/PerfectlySoft/Perfect)\n- [Kitura](https://github.com/IBM-Swift/Kitura)\n- [Zewo](https://github.com/Zewo/Zewo)\n- [Smoke](https://github.com/amzn/smoke-framework)\n\n## 参考教程\n\n- [The Swift Programming Language 中文版](http://special.csdncms.csdn.net/the-swift-programming-language-in-chinese/Introduction.shtml)\n- [官方文档The Swift Programming Language](https://swift.org/documentation/#the-swift-programming-language)\n- [官方文档的中文版The Swift Programming Language中文版](https://github.com/numbbbbb/the-swift-programming-language-in-chinese)\n- [Swift3.0语法速查手册](https://darielchen.github.io/SwiftManual/)\n- [戴铭的 Swift 小册子](https://ming1016.github.io/2021/11/23/daiming-swift-pamphlet/)\n- [探索函数式编程和 Swift 的视频系列](https://github.com/pointfreeco/episode-code-samples)\n- [SwiftUI 相关文章](https://serialcoder.dev/category/text-tutorials/swiftui/)\n- [深入浅出 Swift 3](https://www.shiyanlou.com/courses/611)\n- [Swift教程](http://c.biancheng.net/cpp/swift/jiaocheng/)\n- [慕课网Swift教程](http://www.imooc.com/search/course?words=swift)\n- [Swift 必备 tips](http://swifter.tips)\n- [Swift 学习指引](http://www.swiftguide.cn)\n- [swiftcafe](http://swiftcafe.io)\n- [SwiftGG](http://swift.gg)\n- [swiftweekly](http://swiftweekly.cn)\n- [dianqk](http://blog.dianqk.org)\n\n## Contributors\n\nAs always, thanks to our amazing contributors!\n\n\u003ca href=\"https://github.com/jaywcjlove/swift-tutorial/graphs/contributors\"\u003e\n  \u003cimg src=\"https://jaywcjlove.github.io/swift-tutorial/CONTRIBUTORS.svg\" /\u003e\n\u003c/a\u003e\n\nMade with [action-contributors](https://github.com/jaywcjlove/github-action-contributors).\n\n## License\n\nLicensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaywcjlove%2Fswift-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaywcjlove%2Fswift-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaywcjlove%2Fswift-tutorial/lists"}