swift的简介
Swift 是一种新的编程语言,用于编写 iOS,MacOS, watchOS 和tvOS 的应用程序。Swift 结合了 C 和 Object ive-C 的优点并且不受 C 兼容性的限制。Swift 采用安全的编程模式并添加了很多新特性,这将使编程更简 单,更灵活,也更有趣。Swift 是基于成熟而且倍受喜爱的 Cocoa 和 Cocoa Touch 框架,它的降临将重新定义 软件开发。
Swift 的开发从很久之前就开始了。为了给 Swift 打好基础,苹果公司改进了编译器,调试器和框架结构。我们 使用自动引用计数(Automatic Reference Counting, ARC)来简化内存管理。我们在 Foundation 和 Cocoa 的 基础上构建框架栈使其完全现代化和标准化。 Objective-C 本身支持块、集合语法和模块,所以框架可以轻松支 持现代编程语言技术。正是得益于这些基础工作,我们现在才能发布这样一个用于未来苹果软件开发的新语言。
Objective-C 开发者对 Swift 并不会感到陌生。它采用了 Objective-C 的命名参数以及动态对象模型,可以无 缝对接到现有的 Cocoa 框架,并且可以兼容 Objective-C 代码。在此基础之上,Swift 还有许多新特性并且支 持过程式编程和面向对象编程。
Swift 对于初学者来说也很友好。它是第一个既满足工业标准又像脚本语言一样充满表现力和趣味的系统编程语 言。它支持代码预览(playgrounds),这个革命性的特性可以允许程序员在不编译和运行应用程序的前提下运行 S wift 代码并实时查看结果。
Swift 将现代编程语言的精华和苹果工程师文化的智慧结合了起来。编译器对性能进行了优化,编程语言对开发 进行了优化,两者互不干扰,鱼与熊掌兼得。Swift 既可以用于开发 “hello, world” 这样的小程序,也可以 用于开发一套完整的操作系统。所有的这些特性让 Swift 对于开发者和苹果来说都是一项值得的投资。
Swift 是编写 iOS,MacOS,watchOS 和 tvOS 应用的极佳手段,并将伴随着新的特性和功能持续演进。我们对 S wift 充满信心,你还在等什么!
直接进入正题......
一.基础部分
- swift除了我们熟悉的类型,还增加了oc没有的高阶数据类型比如
元祖
。元祖
可以让你创建或者传递一组数据,比如作为函数的返回值时,你可以用一个元祖可以返回多个值 - swift还增加了
可选类型
,用于处理值缺失的情况,可选表示“那有一个值,并且它等于x
”,或者“那没有值”。可选有点像oc中使用nil
,但是他可以用在任何类型上,不仅仅是类,可选类型比oc中的nil
指针更加安全也更具表现力,他是swift许多强大特性的重要组成部分。 - swift是一门类型安全的语言,这意味着swift可以让你清楚地知道值得类型,如果你的代码期望得到一个
string
,类型安全会阻止你不小心传入一个int
。同样的,如果你期望得到一个string
,类型安全会阻止你意外传入一个可选的string
。类型安全可以帮助你在开发阶段尽早发现并修正错误。
1. 常量和变量
常量和变量把一个名字(比如 maximumNumberOfLoginAttempts
或者 welcomeMessage
)和一个指定类型的 值(比如数字 10
或者字符串 "Hello"
)关联起来。常量的值一旦设定就不能改变,而变量的值可以随意更改。
声明常量和变量
常量和变量必须在使用前声明,用 let
来声明常量,用 var
来声明变量。下面的例子展示了如何用常量和变量来记录用户尝试登录的次数:
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0```
你可以在一行中声明多个常量或者多个变量,用逗号隔开:
`var x = 0.0, y = 0.0, z = 0.0`
>注意:
如果你的代码中有不需要改变的值,请使用 let 关键字将它声明为常量。只将需要改变的值声明为变量。
###### 类型标注
当你声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类 型。如果要添加类型标注,需要在`常量或者变量名`后面加上一个`冒号`和`空格`,然后加上`类型名称`。
这个例子给 `welcomeMessage `变量添加了类型标注,表示这个变量可以存储 String 类型的值:
`var welcomeMessage: String`
声明中的冒号代表着“是...类型”,所以这行代码可以被理解为:
“声明一个类型为 `String` ,名字为 `welcomeMessage` 的变量。”
“类型为 `String `”的意思是“可以存储任意` String` 类型的值。”
`welcomeMessage` 变量现在可以被设置成任意字符串:
`welcomeMessage = "Hello"`
你可以在一行中定义多个同样类型的变量,用逗号分割,并在最后一个变量名之后添加类型标注:
`var red, green, blue: Double`
>注意: 一般来说你很少需要写类型标注。如果你在声明常量或者变量的时候赋了一个初始值,Swift可以推断出这个常 量或者变量的类型,请参考类型安全和类型推断 (页 0)。在上面的例子中,没有给 welcomeMessage 赋初始 值,所以变量 welcomeMessage 的类型是通过一个类型标注指定的,而不是通过初始值推断的。
###### 常量和变量的命名
你可以用任何你喜欢的字符作为常量和变量名,包括 Unicode 字符:
let π = 3.14159
let 你好 = "你好世界"
let ?? = "dogcow"```
常量与变量名不能包含数学符号,箭头,保留的(或者非法的)Unicode 码位,连线与制表符。也不能以数字开 头,但是可以在常量与变量名的其他地方包含数字。
一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类
型。同时,你也不能将常量与变量进行互转。
注意: 如果你需要使用与Swift保留关键字相同的名称作为常量或者变量名,你可以使用反引号(`)将关键字包围的方 式将其作为名字使用。无论如何,你应当避免使用关键字作为常量或变量名,除非你别无选择。
你可以更改现有的变量值为其他同类型的值,在下面的例子中, friendlyWelcome
的值从 "Hello!"
改为了 ur!"
:
var friendlyWelcome = "Hello!" friendlyWelcome = "Bonjour!"
// friendlyWelcome 现在是 "Bonjour!"```
与变量不同,常量的值一旦被确定就不能更改了。尝试这样做会导致编译时报错:
"Bonjo
let languageName = "Swift"
languageName = "Swift++"
// 这会报编译时错误 - languageName 不可改变```
输出常量和变量
print(friendlyWelcome) // 输出 "Bonjour!"
Swift 用字符串插值(string interpolation)
的方式把常量名或者变量名当做占位符
加入到长字符串中,Swift 会用当前常量或变量的值替换这些占位符。将常量或变量名放入圆括号中,并在开括号前使用反斜杠将其转义:
print("The current value of friendlyWelcome is \(friendlyWelcome)") // 输出 "The current value of friendlyWelcome is Bonjour!```
###### 数值型字面量
整数字面量可以被写作:
* 一个十进制数,没有前缀
*一个二进制数,前缀是 `0b`
* 一个八进制数,前缀是 `0o`
* 一个十六进制数,前缀是 `0x`
下面的所有整数字面量的十进制值都是 `17` :
let decimalInteger = 17
let binaryInteger = 0b10001 // 二进制的17
let octalInteger = 0o21 // 八进制的17
let hexadecimalInteger = 0x11 // 十六进制的17```
类型别名
类型别名(type aliases)就是给现有类型定义另一个名字。你可以使用 typealias
关键字来定义类型别名。
当你想要给现有类型起一个更有意义的名字时,类型别名非常有用。假设你正在处理特定长度的外部资源的数
据:
定义了一个类型别名之后,你可以在任何使用原始名的地方使用别名:
var maxAmplitudeFound = AudioSample.min // maxAmplitudeFound 现在是 0
本例中, AudioSample
被定义为 UInt16
的一个别名。因为它是别名, AudioSample.min
实际上是 UInt16.mi n
,所以会给 maxAmplitudeFound
赋一个初值0
。
布尔值
Swift 有一个基本的布尔(Boolean)类型,叫做 Bool
。布尔值指逻辑上的值,因为它们只能是真或者假。Swift 有两个布尔常量,true
和 false
:
let orangesAreOrange = true
let turnipsAreDelicious = false```
当你编写条件语句比如 `if ` 语句的时候,布尔值非常有用:
if turnipsAreDelicious {
print("Mmm, tasty turnips!")
} else {
print("Eww, turnips are horrible.")
}
// 输出 "Eww, turnips are horrible."```
如果你在需要使用 Bool 类型的地方使用了非布尔值,Swift 的类型安全机制会报错。下面的例子会报告一个编 译时错误:
let i = 1
if i {
// 这个例子不会通过编译,会报错 }
然而,下面的例子是合法的:
let i = 1
if i == 1 {
// 这个例子会编译成功 }```
`i == 1 `的比较结果是 `Bool `类型,所以第二个例子可以通过类型检查。
######元组
元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。
下面这个例子中,` (404, "Not Found") `是一个描述 HTTP 状态码(HTTP status code)的元组。HTTP 状态码是 当你请求网页的时候 web 服务器返回的一个特殊值。如果你请求的网页不存在就会返回一个 404 Not Found 状 态码。
let http404Error = (404, "Not Found")
// http404Error 的类型是 (Int, String),值是 (404, "Not Found")```
(404, "Not Found")
元组把一个int
值和一个string
值组合起来表示 HTTP 状态码的两个部分:一个数字 和一个人类可读的描述。这个元组可以被描述为“一个类型为 ( int,string)
的元组”。
你可以把任意顺序的类型组合成一个元组,这个元组可以包含所有类型。只要你想,你可以创建一个类型为(int,int,int)
或者 (int,int,bool)
或者其他任何你想要的组合的元组。
你可以将一个元组的内容分解(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"```
如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线( `_ `)标记:
let (justTheStatusCode, _) = http404Error
print("The status code is (justTheStatusCode)") // 输出 "The status code is 404"```
此外,你还可以通过下标来访问元组中的单个元素,下标从零开始:
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"```
你可以在定义元组的时候给单个元素命名:
`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"```
作为函数返回值时,元组非常有用。一个用来获取网页的函数可能会返回一个 (Int, String) 元组来描述是否 获取成功。和只能返回一个类型的值比较起来,一个包含两个不同类型值的元组可以让函数的返回信息更有 用。
注意:
元组在临时组织值的时候很有用,但是并不适合创建复杂的数据结构。如果你的数据结构并不是临时使用,请使
用类或者结构体而不是元组。
可选类型
使用可选类型(optionals)来处理值可能缺失的情况。可选类型表示:
- 有值,等于x
或者 - 没有值
C 和 Objective-C 中并没有可选类型这个概念。最接近的是 Objective-C 中的一个特性,一个方法要不返回一 个对象要不返回 nil , nil 表示“缺少一个合法的对象”。然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型,Objective-C 方法一般会返回一个特殊值(比如 NSNotFoun
d )来暗示值缺失。这种方法假设方法的调用者知道并记得对特殊值进行判断。然而,Swift 的可选类型可以让 你暗示任意类型的值缺失,并不需要一个特殊值。
来看一个例子。Swift 的Int
类型有一种构造器,作用是将一个String
值转换成一个Int
值。然而,并 不是所有的字符串都可以转换成一个整数。字符串"123"
可以被转换成数字123
,但是字符串"hello, wor ld"
不行。
下面的例子使用这种构造器来尝试将一个 String
转换成Int
:
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推测为类型 "Int?", 或者类型 "optional Int"```
因为该构造器可能会失败,所以它返回一个可选类型(optional) Int ,而不是一个 Int 。一个可选的 Int 被写作 Int? 而不是 Int 。问号暗示包含的值是可选类型,也就是说可能包含 Int 值也可能不包含值。(不 能包含其他任何值比如 Bool 值或者 String 值。只能是 Int 或者什么都没有。)
nil
你可以给可选变量赋值为 `nil` 来表示它没有值:
var serverResponseCode: Int? = 404
// serverResponseCode 包含一个可选的 Int 值 404 serverResponseCode = nil
// serverResponseCode 现在不包含值```
注意:
nil 不能用于非可选的常量和变量。如果你的代码中有常量或者变量需要处理值缺失的情况,请把它们声明成
对应的可选类型。
如果你声明一个可选常量或者变量但是没有赋值,它们会自动被设置为nil
:
var surveyAnswer: String?
// surveyAnswer 被自动设置为 nil```
>注意:
Swift 的 `nil `和 Objective-C 中的` nil` 并不一样。在 Objective-C 中, nil 是一个指向不存在对象的指 针。在 Swift 中, nil 不是指针——它是一个确定的值,用来表示`值缺失`。任何类型的可选状态都可以被设置为 `nil` ,不只是对象类型。
######if 语句以及强制解析
你可以使用 `if `语句和 `nil `比较来判断一个可选值是否包含值。你可以使用“相等”(`==`)或“不 等”( `!=` )来执行比较。
如果可选类型有值,它将不等于 `nil `:
if convertedNumber != nil {
print("convertedNumber contains some integer value.")
}
// 输出 "convertedNumber contains some integer value."```
当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号( !
)来获取值。这个惊叹号表 示“我知道这个可选有值,请使用它。”这被称为可选值的强制解析
(forced unwrapping):
if convertedNumber != nil {
print("convertedNumber has an integer value of \(convertedNumber!).")
}
// 输出 "convertedNumber has an integer value of 123."```
######可选绑定
使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变 量。可选绑定可以用在` if` 和 `while` 语句中,这条语句不仅可以用来判断可选类型中是否有值,同时可以将 可选类型中的值赋给一个常量或者变量。
像下面这样在 if 语句中写一个可选绑定:
你可以像上面这样使用可选绑定来重写 `possibleNumber` 这个例子
if let actualNumber = Int(possibleNumber) {
print("'(possibleNumber)' has an integer value of (actualNumber)")
} else {
print("'(possibleNumber)' could not be converted to an integer")
}
// 输出 "'123' has an integer value of 123"
这段代码可以被理解为:
“如果 `Int(possibleNumber)` 返回的可选` Int` 包含一个值,创建一个叫做 `actualNumber` 的新常量并将可选 包含的值赋给它。”
如果转换成功, `actualNumber` 常量可以在` if` 语句的第一个分支中使用。它已经被可选类型 包含的 值初始化 过,所以不需要再使用 ! 后缀来获取它的值。在这个例子中,`actualNumber `只被用来输出转换结果。
你可以在可选绑定中使用常量和变量。如果你想在`if`语句的第一个分支中操作 `actualNumber `的值,你可以改 成` if var actualNumber `,这样可选类型包含的值就会被赋给一个变量而非常量。
你可以包含多个可选绑定或多个布尔条件在一个 if 语句中,只要使用逗号分开就行。只要有任意一个可选绑定 的值为`nil`,或者任意一个布尔条件为`false`,则整个`if`条件判断为`false`,这时你就需要使用嵌套` if` 条 件语句来处理,如下所示:
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber <100{
print("(firstNumber) < (secondNumber) < 100")
}
// 输出 "4 < 42 < 100"
if let firstNumber = Int("4") {
if let secondNumber = Int("42") {
if firstNumber < secondNumber && secondNumber < 100 {
print("(firstNumber) < (secondNumber) < 100")
} }
}
// 输出 "4 < 42 < 100"
>注意: 在 if 条件语句中使用常量和变量来创建一个可选绑定,仅在 if 语句的句中( body )中才能获取到 值。相反,在 guard 语句中使用常量和变量来创建一个可选绑定,仅在 guard 语句外且在语句后才能获取 到值。
(欢迎大家对不合适的地方进行指正,看完觉得有帮到你给点个赞👍吧)