@ -1,4 +1,3 @@
|
|||||||
# 欢迎使用 Swift
|
# 欢迎使用 Swift
|
||||||
|
|
||||||
在本章中您将了解 Swift 的特性和开发历史,并对 Swift 有一个初步的了解。
|
在本章中您将了解 Swift 的特性和开发历史,并对 Swift 有一个初步的了解。
|
||||||
|
|
||||||
|
|||||||
@ -185,6 +185,7 @@ print("The current value of friendlyWelcome is \(friendlyWelcome)")
|
|||||||
|
|
||||||
<a name="comments"></a>
|
<a name="comments"></a>
|
||||||
## 注释
|
## 注释
|
||||||
|
|
||||||
请将你的代码中的非执行文本注释成提示或者笔记以方便你将来阅读。Swift 的编译器将会在编译代码时自动忽略掉注释部分。
|
请将你的代码中的非执行文本注释成提示或者笔记以方便你将来阅读。Swift 的编译器将会在编译代码时自动忽略掉注释部分。
|
||||||
|
|
||||||
Swift 中的注释与 C 语言的注释非常相似。单行注释以双正斜杠(`//`)作为起始标记:
|
Swift 中的注释与 C 语言的注释非常相似。单行注释以双正斜杠(`//`)作为起始标记:
|
||||||
@ -212,6 +213,7 @@ Swift 中的注释与 C 语言的注释非常相似。单行注释以双正斜
|
|||||||
|
|
||||||
<a name="semicolons"></a>
|
<a name="semicolons"></a>
|
||||||
## 分号
|
## 分号
|
||||||
|
|
||||||
与其他大部分编程语言不同,Swift 并不强制要求你在每条语句的结尾处使用分号(`;`),当然,你也可以按照你自己的习惯添加分号。有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句:
|
与其他大部分编程语言不同,Swift 并不强制要求你在每条语句的结尾处使用分号(`;`),当然,你也可以按照你自己的习惯添加分号。有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
@ -727,6 +729,7 @@ if let definiteString = assumedString {
|
|||||||
|
|
||||||
<a name="error_handling"></a>
|
<a name="error_handling"></a>
|
||||||
## 错误处理
|
## 错误处理
|
||||||
|
|
||||||
你可以使用 *错误处理(error handling)* 来应对程序执行中可能会遇到的错误条件。
|
你可以使用 *错误处理(error handling)* 来应对程序执行中可能会遇到的错误条件。
|
||||||
|
|
||||||
相对于可选中运用值的存在与缺失来表达函数的成功与失败,错误处理可以推断失败的原因,并传播至程序的其他部分。
|
相对于可选中运用值的存在与缺失来表达函数的成功与失败,错误处理可以推断失败的原因,并传播至程序的其他部分。
|
||||||
@ -834,4 +837,3 @@ precondition(index > 0, "Index must be greater than zero.")
|
|||||||
> 注意:
|
> 注意:
|
||||||
> 如果你使用unchecked模式(-Ounchecked)编译代码,先决条件将不会进行检查。编译器假设所有的先决条件总是为true(真),他将优化你的代码。然而,`fatalError(_:file:line:)`函数总是中断执行,无论你怎么进行优化设定。
|
> 如果你使用unchecked模式(-Ounchecked)编译代码,先决条件将不会进行检查。编译器假设所有的先决条件总是为true(真),他将优化你的代码。然而,`fatalError(_:file:line:)`函数总是中断执行,无论你怎么进行优化设定。
|
||||||
>你能使用 `fatalError(_:file:line:)`函数在设计原型和早期开发阶段,这个阶段只有方法的声明,但是没有具体实现,你可以在方法体中写上fatalError("Unimplemented")作为具体实现。因为fatalError不会像断言和先决条件那样被优化掉,所以你可以确保当代码执行到一个没有被实现的方法时,程序会被中断。
|
>你能使用 `fatalError(_:file:line:)`函数在设计原型和早期开发阶段,这个阶段只有方法的声明,但是没有具体实现,你可以在方法体中写上fatalError("Unimplemented")作为具体实现。因为fatalError不会像断言和先决条件那样被优化掉,所以你可以确保当代码执行到一个没有被实现的方法时,程序会被中断。
|
||||||
|
|
||||||
|
|||||||
@ -334,6 +334,7 @@ colorNameToUse = userDefinedColorName ?? defaultColorName
|
|||||||
Swift 提供了几种方便表达一个区间的值的*区间运算符*。
|
Swift 提供了几种方便表达一个区间的值的*区间运算符*。
|
||||||
|
|
||||||
### 闭区间运算符
|
### 闭区间运算符
|
||||||
|
|
||||||
*闭区间运算符*(`a...b`)定义一个包含从 `a` 到 `b`(包括 `a` 和 `b`)的所有值的区间。`a` 的值不能超过 `b`。
|
*闭区间运算符*(`a...b`)定义一个包含从 `a` 到 `b`(包括 `a` 和 `b`)的所有值的区间。`a` 的值不能超过 `b`。
|
||||||
|
|
||||||
闭区间运算符在迭代一个区间的所有值时是非常有用的,如在 `for-in` 循环中:
|
闭区间运算符在迭代一个区间的所有值时是非常有用的,如在 `for-in` 循环中:
|
||||||
@ -511,5 +512,3 @@ if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword
|
|||||||
```
|
```
|
||||||
|
|
||||||
这括号使得前两个值被看成整个逻辑表达中独立的一个部分。虽然有括号和没括号的输出结果是一样的,但对于读代码的人来说有括号的代码更清晰。可读性比简洁性更重要,请在可以让你代码变清晰的地方加个括号吧!
|
这括号使得前两个值被看成整个逻辑表达中独立的一个部分。虽然有括号和没括号的输出结果是一样的,但对于读代码的人来说有括号的代码更清晰。可读性比简洁性更重要,请在可以让你代码变清晰的地方加个括号吧!
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -818,5 +818,3 @@ for scalar in dogString.unicodeScalars {
|
|||||||
// ‼
|
// ‼
|
||||||
// 🐶
|
// 🐶
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -815,4 +815,3 @@ if #available(platform name version, ..., *) {
|
|||||||
APIs 不可用,语句将不执行
|
APIs 不可用,语句将不执行
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -39,12 +39,13 @@ Swift 统一的函数语法非常的灵活,可以用来表示任何函数,
|
|||||||
|
|
||||||
<a name="Defining_and_Calling_Functions"></a>
|
<a name="Defining_and_Calling_Functions"></a>
|
||||||
## 函数的定义与调用
|
## 函数的定义与调用
|
||||||
|
|
||||||
当你定义一个函数时,你可以定义一个或多个有名字和类型的值,作为函数的输入,称为*参数*,也可以定义某种类型的值作为函数执行结束时的输出,称为*返回类型*。
|
当你定义一个函数时,你可以定义一个或多个有名字和类型的值,作为函数的输入,称为*参数*,也可以定义某种类型的值作为函数执行结束时的输出,称为*返回类型*。
|
||||||
|
|
||||||
每个函数有个*函数名*,用来描述函数执行的任务。要使用一个函数时,用函数名来“调用”这个函数,并传给它匹配的输入值(称作 *实参* )。函数的实参必须与函数参数表里参数的顺序一致。
|
每个函数有个*函数名*,用来描述函数执行的任务。要使用一个函数时,用函数名来“调用”这个函数,并传给它匹配的输入值(称作 *实参* )。函数的实参必须与函数参数表里参数的顺序一致。
|
||||||
|
|
||||||
|
|
||||||
下面例子中的函数的名字是`greet(person:)`,之所以叫这个名字,是因为这个函数用一个人的名字当做输入,并返回向这个人问候的语句。为了完成这个任务,你需要定义一个输入参数——一个叫做 `person` 的 `String` 值,和一个包含给这个人问候语的 `String` 类型的返回值:
|
下面例子中的函数的名字是`greet(person:)`,之所以叫这个名字,是因为这个函数用一个人的名字当做输入,并返回向这个人问候的语句。为了完成这个任务,你需要定义一个输入参数——一个叫做 `person` 的 `String` 值,和一个包含给这个人问候语的 `String` 类型的返回值:
|
||||||
|
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
@ -87,6 +88,7 @@ print(greetAgain(person: "Anna"))
|
|||||||
|
|
||||||
<a name="Function_Parameters_and_Return_Values"></a>
|
<a name="Function_Parameters_and_Return_Values"></a>
|
||||||
## 函数参数与返回值
|
## 函数参数与返回值
|
||||||
|
|
||||||
函数参数与返回值在 Swift 中非常的灵活。你可以定义任何类型的函数,包括从只带一个未名参数的简单函数到复杂的带有表达性参数名和不同参数选项的复杂函数。
|
函数参数与返回值在 Swift 中非常的灵活。你可以定义任何类型的函数,包括从只带一个未名参数的简单函数到复杂的带有表达性参数名和不同参数选项的复杂函数。
|
||||||
|
|
||||||
<a name="functions_without_parameters"></a>
|
<a name="functions_without_parameters"></a>
|
||||||
@ -168,6 +170,7 @@ printWithoutCounting(string: "hello, world")
|
|||||||
|
|
||||||
<a name="functions_with_multiple_return_values"></a>
|
<a name="functions_with_multiple_return_values"></a>
|
||||||
### 多重返回值函数
|
### 多重返回值函数
|
||||||
|
|
||||||
你可以用元组(tuple)类型让多个值作为一个复合值从函数中返回。
|
你可以用元组(tuple)类型让多个值作为一个复合值从函数中返回。
|
||||||
|
|
||||||
下例中定义了一个名为 `minMax(array:)` 的函数,作用是在一个 `Int` 类型的数组中找出最小值与最大值。
|
下例中定义了一个名为 `minMax(array:)` 的函数,作用是在一个 `Int` 类型的数组中找出最小值与最大值。
|
||||||
@ -499,7 +502,6 @@ let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
|
|||||||
|
|
||||||
现在,`moveNearerToZero`指向了正确的函数,它可以被用来数到零:
|
现在,`moveNearerToZero`指向了正确的函数,它可以被用来数到零:
|
||||||
|
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
print("Counting to zero:")
|
print("Counting to zero:")
|
||||||
// Counting to zero:
|
// Counting to zero:
|
||||||
|
|||||||
@ -456,4 +456,3 @@ for customerProvider in customerProviders {
|
|||||||
```
|
```
|
||||||
|
|
||||||
在上面的代码中,`collectCustomerProviders(_:)` 函数并没有调用传入的 `customerProvider` 闭包,而是将闭包追加到了 `customerProviders` 数组中。这个数组定义在函数作用域范围外,这意味着数组内的闭包能够在函数返回之后被调用。因此,`customerProvider` 参数必须允许“逃逸”出函数作用域。
|
在上面的代码中,`collectCustomerProviders(_:)` 函数并没有调用传入的 `customerProvider` 闭包,而是将闭包追加到了 `customerProviders` 数组中。这个数组定义在函数作用域范围外,这意味着数组内的闭包能够在函数返回之后被调用。因此,`customerProvider` 参数必须允许“逃逸”出函数作用域。
|
||||||
|
|
||||||
|
|||||||
@ -267,6 +267,7 @@ let sunsetDirection = CompassPoint.west.rawValue
|
|||||||
|
|
||||||
<a name="initializing_from_a_raw_value"></a>
|
<a name="initializing_from_a_raw_value"></a>
|
||||||
### 使用原始值初始化枚举实例
|
### 使用原始值初始化枚举实例
|
||||||
|
|
||||||
如果在定义枚举类型的时候使用了原始值,那么将会自动获得一个初始化方法,这个方法接收一个叫做`rawValue`的参数,参数类型即为原始值类型,返回值则是枚举成员或`nil`。你可以使用这个初始化方法来创建一个新的枚举实例。
|
如果在定义枚举类型的时候使用了原始值,那么将会自动获得一个初始化方法,这个方法接收一个叫做`rawValue`的参数,参数类型即为原始值类型,返回值则是枚举成员或`nil`。你可以使用这个初始化方法来创建一个新的枚举实例。
|
||||||
|
|
||||||
这个例子利用原始值`7`创建了枚举成员`uranus`:
|
这个例子利用原始值`7`创建了枚举成员`uranus`:
|
||||||
|
|||||||
@ -142,6 +142,7 @@ print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
|
|||||||
|
|
||||||
<a name="memberwise_initializers_for_structure_types"></a>
|
<a name="memberwise_initializers_for_structure_types"></a>
|
||||||
### 结构体类型的成员逐一构造器
|
### 结构体类型的成员逐一构造器
|
||||||
|
|
||||||
所有结构体都有一个自动生成的*成员逐一构造器*,用于初始化新结构体实例中成员的属性。新实例中各个属性的初始值可以通过属性的名称传递到成员逐一构造器之中:
|
所有结构体都有一个自动生成的*成员逐一构造器*,用于初始化新结构体实例中成员的属性。新实例中各个属性的初始值可以通过属性的名称传递到成员逐一构造器之中:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
|
|||||||
@ -281,5 +281,3 @@ if player.tracker.advance(to: 6) {
|
|||||||
}
|
}
|
||||||
// 打印 "level 6 has not yet been unlocked"
|
// 打印 "level 6 has not yet been unlocked"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -403,12 +403,15 @@ convenience init(parameters) {
|
|||||||
为了简化指定构造器和便利构造器之间的调用关系,Swift 采用以下三条规则来限制构造器之间的代理调用:
|
为了简化指定构造器和便利构造器之间的调用关系,Swift 采用以下三条规则来限制构造器之间的代理调用:
|
||||||
|
|
||||||
##### 规则 1
|
##### 规则 1
|
||||||
|
|
||||||
指定构造器必须调用其直接父类的的指定构造器。
|
指定构造器必须调用其直接父类的的指定构造器。
|
||||||
|
|
||||||
##### 规则 2
|
##### 规则 2
|
||||||
|
|
||||||
便利构造器必须调用*同*类中定义的其它构造器。
|
便利构造器必须调用*同*类中定义的其它构造器。
|
||||||
|
|
||||||
##### 规则 3
|
##### 规则 3
|
||||||
|
|
||||||
便利构造器最后必须调用指定构造器。
|
便利构造器最后必须调用指定构造器。
|
||||||
|
|
||||||
一个更方便记忆的方法是:
|
一个更方便记忆的方法是:
|
||||||
|
|||||||
@ -257,5 +257,3 @@ func processFile(filename: String) throws {
|
|||||||
|
|
||||||
> 注意
|
> 注意
|
||||||
> 即使没有涉及到错误处理,你也可以使用`defer`语句。
|
> 即使没有涉及到错误处理,你也可以使用`defer`语句。
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -694,4 +694,3 @@ extension Container {
|
|||||||
|
|
||||||
综合一下,这些约束意味着,传入到 `indices` 下标,是一个整型的序列.
|
综合一下,这些约束意味着,传入到 `indices` 下标,是一个整型的序列.
|
||||||
(译者:原来的 `Container` 协议,`subscript` 必须是 `Int` 型的,扩展中新的 `subscript`,允许下标是一个的序列,而非单一的值。)
|
(译者:原来的 `Container` 协议,`subscript` 必须是 `Int` 型的,扩展中新的 `subscript`,允许下标是一个的序列,而非单一的值。)
|
||||||
|
|
||||||
|
|||||||
@ -215,4 +215,3 @@ func someFunction() {
|
|||||||
|
|
||||||
> 4.0
|
> 4.0
|
||||||
> 翻译:[kemchenj](https://kemchenj.github.io/) 2017-09-21
|
> 翻译:[kemchenj](https://kemchenj.github.io/) 2017-09-21
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,7 @@ Swift 不仅提供了多种不同的访问级别,还为某些典型场景提
|
|||||||
|
|
||||||
<a name="modules_and_source_files"></a>
|
<a name="modules_and_source_files"></a>
|
||||||
## 模块和源文件
|
## 模块和源文件
|
||||||
|
|
||||||
Swift 中的访问控制模型基于模块和源文件这两个概念。
|
Swift 中的访问控制模型基于模块和源文件这两个概念。
|
||||||
|
|
||||||
模块指的是独立的代码单元,框架或应用程序会作为一个独立的模块来构建和发布。在 Swift 中,一个模块可以使用 `import` 关键字导入另外一个模块。
|
模块指的是独立的代码单元,框架或应用程序会作为一个独立的模块来构建和发布。在 Swift 中,一个模块可以使用 `import` 关键字导入另外一个模块。
|
||||||
@ -56,6 +57,7 @@ Swift 中的访问控制模型基于模块和源文件这两个概念。
|
|||||||
|
|
||||||
<a name="access_levels"></a>
|
<a name="access_levels"></a>
|
||||||
## 访问级别
|
## 访问级别
|
||||||
|
|
||||||
Swift 为代码中的实体提供了五种不同的*访问级别*。这些访问级别不仅与源文件中定义的实体相关,同时也与源文件所属的模块相关。
|
Swift 为代码中的实体提供了五种不同的*访问级别*。这些访问级别不仅与源文件中定义的实体相关,同时也与源文件所属的模块相关。
|
||||||
|
|
||||||
- *Open* 和 *Public* 级别可以让实体被同一模块源文件中的所有实体访问,在模块外也可以通过导入该模块来访问源文件里的所有实体。通常情况下,你会使用 Open 或 Public 级别来指定框架的外部接口。Open 和 Public 的区别在后面会提到。
|
- *Open* 和 *Public* 级别可以让实体被同一模块源文件中的所有实体访问,在模块外也可以通过导入该模块来访问源文件里的所有实体。通常情况下,你会使用 Open 或 Public 级别来指定框架的外部接口。Open 和 Public 的区别在后面会提到。
|
||||||
@ -426,5 +428,3 @@ extension SomeStruct: SomeProtocol {
|
|||||||
|
|
||||||
> 注意
|
> 注意
|
||||||
这条规则也适用于为满足协议一致性而将类型别名用于关联类型的情况。
|
这条规则也适用于为满足协议一致性而将类型别名用于关联类型的情况。
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -396,5 +396,3 @@ let eFloat: Float = 2.71828 // eFloat 的类型为 Float
|
|||||||
```
|
```
|
||||||
|
|
||||||
Swift 中的类型推断在单独的表达式或语句上进行。这意味着所有用于类型推断的信息必须可以从表达式或其某个子表达式的类型检查中获取到。
|
Swift 中的类型推断在单独的表达式或语句上进行。这意味着所有用于类型推断的信息必须可以从表达式或其某个子表达式的类型检查中获取到。
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
<a name="declaration_attributes"></a>
|
<a name="declaration_attributes"></a>
|
||||||
##声明特性
|
##声明特性
|
||||||
|
|
||||||
声明特性只能应用于声明。
|
声明特性只能应用于声明。
|
||||||
|
|
||||||
`available`
|
`available`
|
||||||
@ -180,6 +181,7 @@ NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
|
|||||||
|
|
||||||
<a name="declaration_attributes_used_by_interface_builder"></a>
|
<a name="declaration_attributes_used_by_interface_builder"></a>
|
||||||
###Interface Builder 使用的声明特性
|
###Interface Builder 使用的声明特性
|
||||||
|
|
||||||
`Interface Builder` 特性是 `Interface Builder` 用来与 Xcode 同步的声明特性。`Swift` 提供了以下的 `Interface Builder` 特性:`IBAction`,`IBOutlet`,`IBDesignable`,以及`IBInspectable` 。这些特性与 Objective-C 中对应的特性在概念上是相同的。
|
`Interface Builder` 特性是 `Interface Builder` 用来与 Xcode 同步的声明特性。`Swift` 提供了以下的 `Interface Builder` 特性:`IBAction`,`IBOutlet`,`IBDesignable`,以及`IBInspectable` 。这些特性与 Objective-C 中对应的特性在概念上是相同的。
|
||||||
|
|
||||||
`IBOutlet` 和 `IBInspectable` 用于修饰一个类的属性声明,`IBAction` 特性用于修饰一个类的方法声明,`IBDesignable` 用于修饰类的声明。
|
`IBOutlet` 和 `IBInspectable` 用于修饰一个类的属性声明,`IBAction` 特性用于修饰一个类的方法声明,`IBDesignable` 用于修饰类的声明。
|
||||||
@ -188,6 +190,7 @@ NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
|
|||||||
|
|
||||||
<a name="type_attributes"></a>
|
<a name="type_attributes"></a>
|
||||||
##类型特性
|
##类型特性
|
||||||
|
|
||||||
类型特性只能用于修饰类型。
|
类型特性只能用于修饰类型。
|
||||||
|
|
||||||
`autoclosure`
|
`autoclosure`
|
||||||
|
|||||||
@ -661,5 +661,3 @@ if #available(平台名称 版本, ..., *) {
|
|||||||
> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits)
|
> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits)
|
||||||
> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits)
|
> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits)
|
||||||
> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits)
|
> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -17,10 +17,12 @@
|
|||||||
|
|
||||||
<a name="prefix_expressions"></a>
|
<a name="prefix_expressions"></a>
|
||||||
####自定义原型
|
####自定义原型
|
||||||
|
|
||||||
接下老码根据Bool的思想来创建一个OCBool类型,来让小伙伴们了解一下Swift中到底是怎么玩儿的。
|
接下老码根据Bool的思想来创建一个OCBool类型,来让小伙伴们了解一下Swift中到底是怎么玩儿的。
|
||||||
来我们先看一下OCBool的定义。
|
来我们先看一下OCBool的定义。
|
||||||
|
|
||||||
#####代码示例如下:
|
#####代码示例如下:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
enum OCBool{
|
enum OCBool{
|
||||||
case ocTrue
|
case ocTrue
|
||||||
@ -35,6 +37,7 @@ case ocFalse
|
|||||||
|
|
||||||
<a name="imp-default"></a>
|
<a name="imp-default"></a>
|
||||||
####实现默认值
|
####实现默认值
|
||||||
|
|
||||||
行,我们给了一个漂亮的定义,不过按照传统语言的经验,Bool值默认情况下是假, 所以我们的OCBool也应该如此,我们使用类型扩展技术增加这个默认特性:
|
行,我们给了一个漂亮的定义,不过按照传统语言的经验,Bool值默认情况下是假, 所以我们的OCBool也应该如此,我们使用类型扩展技术增加这个默认特性:
|
||||||
```swift
|
```swift
|
||||||
extension OCBool{
|
extension OCBool{
|
||||||
@ -45,11 +48,13 @@ extension OCBool{
|
|||||||
```
|
```
|
||||||
|
|
||||||
#####注意:
|
#####注意:
|
||||||
|
|
||||||
- 代码中第1行:extension关键字,非常强大,小伙伴们可以通过此创造出许多好玩的东西,建议各位去Github上看一个名为“Swiftz”的项目,它将扩展用到了极致。
|
- 代码中第1行:extension关键字,非常强大,小伙伴们可以通过此创造出许多好玩的东西,建议各位去Github上看一个名为“Swiftz”的项目,它将扩展用到了极致。
|
||||||
- 代码中第3行:self = .ocFalse语法,刚入门的小伙伴们很迷糊,为什么会有奇怪的点语法,因为大牛Chris在Swift中增加了类型智能推断功能,在苹果Blog中,提到了“Context”概念,就是这个意思,因为这行语句是在枚举OCBool中的,其上下文就是OCBool的定义体,编译器当然知道.ocFalse就是OCBool.ocFalse了,所以这里直接点语法,非常整齐。
|
- 代码中第3行:self = .ocFalse语法,刚入门的小伙伴们很迷糊,为什么会有奇怪的点语法,因为大牛Chris在Swift中增加了类型智能推断功能,在苹果Blog中,提到了“Context”概念,就是这个意思,因为这行语句是在枚举OCBool中的,其上下文就是OCBool的定义体,编译器当然知道.ocFalse就是OCBool.ocFalse了,所以这里直接点语法,非常整齐。
|
||||||
现在我们可以使用如下方法使用这个Bool类型。
|
现在我们可以使用如下方法使用这个Bool类型。
|
||||||
|
|
||||||
#####代码示例如下:
|
#####代码示例如下:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
var result:OCBool = OCBool()
|
var result:OCBool = OCBool()
|
||||||
var result1:OCBool = .ocTrue
|
var result1:OCBool = .ocTrue
|
||||||
@ -57,6 +62,7 @@ var result1:OCBool = .ocTrue
|
|||||||
|
|
||||||
<a name="init-by-bool"></a>
|
<a name="init-by-bool"></a>
|
||||||
####支持基本布尔型初始化
|
####支持基本布尔型初始化
|
||||||
|
|
||||||
正如上述代码所述,我们只能通过类型或者枚举项目赋值,这是组合类型的用法,但是编码的日子里,我们总是希望和true,false直接打交道,也就是说,我们希望这么做,
|
正如上述代码所述,我们只能通过类型或者枚举项目赋值,这是组合类型的用法,但是编码的日子里,我们总是希望和true,false直接打交道,也就是说,我们希望这么做,
|
||||||
代码示例如下:
|
代码示例如下:
|
||||||
```swift
|
```swift
|
||||||
@ -91,6 +97,7 @@ var isSuccess:OCBool = true
|
|||||||
```
|
```
|
||||||
|
|
||||||
#####注意:
|
#####注意:
|
||||||
|
|
||||||
- 代码中的第11行是重点,我的类型OCBool支持了BooleanLiteralConvertible协议,这个协到底是干什么的呢,小伙伴们在Xcode代码编辑器,按住Command键,然后点击第11行中的BooleanLiteralConvertible协议名,则会进入它的定义,
|
- 代码中的第11行是重点,我的类型OCBool支持了BooleanLiteralConvertible协议,这个协到底是干什么的呢,小伙伴们在Xcode代码编辑器,按住Command键,然后点击第11行中的BooleanLiteralConvertible协议名,则会进入它的定义,
|
||||||
#####其定义如下:
|
#####其定义如下:
|
||||||
```swift
|
```swift
|
||||||
@ -104,8 +111,11 @@ protocol BooleanLiteralConvertible {
|
|||||||
|
|
||||||
<a name="condition-by-bool"></a>
|
<a name="condition-by-bool"></a>
|
||||||
####支持Bool类型判断
|
####支持Bool类型判断
|
||||||
|
|
||||||
小伙伴们不安分, 肯定想着我怎么用它实现逻辑判断,所以如果你这么写,
|
小伙伴们不安分, 肯定想着我怎么用它实现逻辑判断,所以如果你这么写,
|
||||||
|
|
||||||
#####代码示例如下:
|
#####代码示例如下:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
var isSuccess:OCBool = true
|
var isSuccess:OCBool = true
|
||||||
|
|
||||||
@ -121,6 +131,7 @@ if isSuccess {
|
|||||||
OCBool现在只能用bool类型初始化,而不能直接返回bool型,小火把们还记得在《老码说编程之白话Swift江湖》中,老码多次提到,妈妈再也不担心我们 if a = 1{}的写法了, 因为等号不支持值返回了, 所以在if判断是后面的条件必须有返回值,OCBool没有,所以编译器哭了。我们解决这个问题。
|
OCBool现在只能用bool类型初始化,而不能直接返回bool型,小火把们还记得在《老码说编程之白话Swift江湖》中,老码多次提到,妈妈再也不担心我们 if a = 1{}的写法了, 因为等号不支持值返回了, 所以在if判断是后面的条件必须有返回值,OCBool没有,所以编译器哭了。我们解决这个问题。
|
||||||
|
|
||||||
#####代码示例如下:
|
#####代码示例如下:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@ -161,21 +172,26 @@ if isSuccess {
|
|||||||
```
|
```
|
||||||
|
|
||||||
####运行结果如下:
|
####运行结果如下:
|
||||||
|
|
||||||
```
|
```
|
||||||
Hello, World!
|
Hello, World!
|
||||||
老码请你吃火锅!
|
老码请你吃火锅!
|
||||||
Program ended with exit code: 0
|
Program ended with exit code: 0
|
||||||
```
|
```
|
||||||
|
|
||||||
#####注意:
|
#####注意:
|
||||||
|
|
||||||
- 如果小伙伴们现在用的是Beta版的Xcode,注意苹果官方Blog中,在代码第17行如果在Xcode Beta4下是错误的,这里的协议是,LogicValue而不是BooleanVue,所以记得看错误提示才是好习惯。
|
- 如果小伙伴们现在用的是Beta版的Xcode,注意苹果官方Blog中,在代码第17行如果在Xcode Beta4下是错误的,这里的协议是,LogicValue而不是BooleanVue,所以记得看错误提示才是好习惯。
|
||||||
- 注意代码第34行,完美支持if判断,且输出结果为“老码请你吃火锅”,老码也是说说而已,请不要当真。
|
- 注意代码第34行,完美支持if判断,且输出结果为“老码请你吃火锅”,老码也是说说而已,请不要当真。
|
||||||
|
|
||||||
<a name="support-all-type"></a>
|
<a name="support-all-type"></a>
|
||||||
|
|
||||||
####支持兼容各们各派的类型
|
####支持兼容各们各派的类型
|
||||||
|
|
||||||
小伙伴们,江湖风险,门派众多,老码有自己的OCBool类型,可能嵩山少林有自己的SSBool类型,甚至连郭美美都可能有自己的MMBool类型,所以OCBool必须能够识别这些类型,这些各门各派的类型,只要支持LogicValue协议,就应该可以被识别,看老码怎么做,
|
小伙伴们,江湖风险,门派众多,老码有自己的OCBool类型,可能嵩山少林有自己的SSBool类型,甚至连郭美美都可能有自己的MMBool类型,所以OCBool必须能够识别这些类型,这些各门各派的类型,只要支持LogicValue协议,就应该可以被识别,看老码怎么做,
|
||||||
|
|
||||||
#####代码示例如下:
|
#####代码示例如下:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
extension OCBool{
|
extension OCBool{
|
||||||
init( _ v: LogicValue )
|
init( _ v: LogicValue )
|
||||||
@ -200,6 +216,7 @@ if ocResult {
|
|||||||
```
|
```
|
||||||
|
|
||||||
#####代码运行结果如下:
|
#####代码运行结果如下:
|
||||||
|
|
||||||
```
|
```
|
||||||
Hello, World!
|
Hello, World!
|
||||||
老码没钱,郭美美请你吃火锅!
|
老码没钱,郭美美请你吃火锅!
|
||||||
@ -208,10 +225,12 @@ Program ended with exit code: 0
|
|||||||
漂亮!我们的OCBool类型现在支持了所有的逻辑变量初始化。
|
漂亮!我们的OCBool类型现在支持了所有的逻辑变量初始化。
|
||||||
|
|
||||||
#####注意:
|
#####注意:
|
||||||
|
|
||||||
- 代码中第2行:“_”下横杠的用法,这是一个功能强大的小强,在此的目的是屏蔽外部参数名,所以小伙伴们可以直接:var ocResult:OCBool = OCBool(mmResult)而不是:var ocResult:OCBool = OCBool(v: mmResult),小伙伴们惊呆了!这个init函数中本来就没有外部参数名啊,还记得老码在书里说过没,Swift的初始化函数会默认使用内部参数名,作为外部参数名。
|
- 代码中第2行:“_”下横杠的用法,这是一个功能强大的小强,在此的目的是屏蔽外部参数名,所以小伙伴们可以直接:var ocResult:OCBool = OCBool(mmResult)而不是:var ocResult:OCBool = OCBool(v: mmResult),小伙伴们惊呆了!这个init函数中本来就没有外部参数名啊,还记得老码在书里说过没,Swift的初始化函数会默认使用内部参数名,作为外部参数名。
|
||||||
|
|
||||||
<a name="make-up-type"></a>
|
<a name="make-up-type"></a>
|
||||||
####完善OCBool的布尔基因体系:
|
####完善OCBool的布尔基因体系:
|
||||||
|
|
||||||
小伙伴们,bool类型的价值就是在于各种判断,诸如==,!=, &,|,^,!,以及各种组合逻辑运算,我们OCBool也要具备这些功能,否则就会基因缺陷,且看老码如何实现:
|
小伙伴们,bool类型的价值就是在于各种判断,诸如==,!=, &,|,^,!,以及各种组合逻辑运算,我们OCBool也要具备这些功能,否则就会基因缺陷,且看老码如何实现:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
Objective-C和C的API常常会需要用到指针。Swift中的数据类型都原生支持基于指针的Cocoa API,不仅如此,Swift会自动处理部分最常用的将指针作为参数传递的情况。这篇文章中,我们将着眼于在Swift中让C语言指针与变量、数组和字符串共同工作。
|
Objective-C和C的API常常会需要用到指针。Swift中的数据类型都原生支持基于指针的Cocoa API,不仅如此,Swift会自动处理部分最常用的将指针作为参数传递的情况。这篇文章中,我们将着眼于在Swift中让C语言指针与变量、数组和字符串共同工作。
|
||||||
|
|
||||||
####用以输入/输出的参数指针
|
####用以输入/输出的参数指针
|
||||||
|
|
||||||
C和Objective-C并不支持多返回值,所以Cocoa API中常常将指针作为一种在方法间传递额外数据的方式。Swift允许指针被当作`inout`参数使用,所以你可以用符号`&`将对一个变量的引用作为指针参数传递。举例来说:`UIColor`中的`getRed(_:green:blue:alpha:)`方法需要四个`CGFloat*`指针来接收颜色的组成信息,我们使用`&`来将这些组成信息捕获为本地变量:
|
C和Objective-C并不支持多返回值,所以Cocoa API中常常将指针作为一种在方法间传递额外数据的方式。Swift允许指针被当作`inout`参数使用,所以你可以用符号`&`将对一个变量的引用作为指针参数传递。举例来说:`UIColor`中的`getRed(_:green:blue:alpha:)`方法需要四个`CGFloat*`指针来接收颜色的组成信息,我们使用`&`来将这些组成信息捕获为本地变量:
|
||||||
```swift
|
```swift
|
||||||
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
|
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
|
||||||
@ -32,6 +33,7 @@ if let contents = NSFileManager.defaultManager()
|
|||||||
为了安全性,Swift要求被使用`&`传递的变量已经初始化。因为无法确定这个方法会不会在写入数据前尝试从指针中读取数据。
|
为了安全性,Swift要求被使用`&`传递的变量已经初始化。因为无法确定这个方法会不会在写入数据前尝试从指针中读取数据。
|
||||||
|
|
||||||
####作为数组使用的参数指针
|
####作为数组使用的参数指针
|
||||||
|
|
||||||
在C语言中,数组和指针的联系十分紧密,而Swift允许数组能够作为指针使用,从而与基于数组的C语言API协同工作更加简单。一个固定的数组可以使用一个常量指针直接传递,一个变化的数组可以用`&`运算符将一个非常量指针传递。就和输入/输出参数指针一样。举例来说:我们可以用Accelerate框架中的`vDSP_vadd`方法让两个数组`a`和`b`相加,并将结果写入第三个数组`result`。
|
在C语言中,数组和指针的联系十分紧密,而Swift允许数组能够作为指针使用,从而与基于数组的C语言API协同工作更加简单。一个固定的数组可以使用一个常量指针直接传递,一个变化的数组可以用`&`运算符将一个非常量指针传递。就和输入/输出参数指针一样。举例来说:我们可以用Accelerate框架中的`vDSP_vadd`方法让两个数组`a`和`b`相加,并将结果写入第三个数组`result`。
|
||||||
```swift
|
```swift
|
||||||
import Accelerate
|
import Accelerate
|
||||||
@ -45,7 +47,8 @@ vDSP_vadd(a, 1, b, 1, &result, 1, 4)
|
|||||||
// result now contains [1.5, 2.25, 3.125, 4.0625]
|
// result now contains [1.5, 2.25, 3.125, 4.0625]
|
||||||
```
|
```
|
||||||
|
|
||||||
#用作字符串参数的指针
|
## 用作字符串参数的指针
|
||||||
|
|
||||||
C语言中用`cont char*`指针来作为传递字符串的基本方式。Swift中的`String`可以被当作一个无限长度UTF-8编码的`const char*`指针来传递给方法。举例来说:我们可以直接传递一个字符串给一个标准C和POSIX库方法
|
C语言中用`cont char*`指针来作为传递字符串的基本方式。Swift中的`String`可以被当作一个无限长度UTF-8编码的`const char*`指针来传递给方法。举例来说:我们可以直接传递一个字符串给一个标准C和POSIX库方法
|
||||||
```swift
|
```swift
|
||||||
puts("Hello from libc")
|
puts("Hello from libc")
|
||||||
@ -60,7 +63,8 @@ if fd < 0 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#指针参数转换的安全性
|
## 指针参数转换的安全性
|
||||||
|
|
||||||
Swift很努力地使与C语言指针的交互更加便利,因为它们广泛地存在于Cocoa之中,同时保持一定的安全性。然而,相比你的其他Swift代码与C语言的指针交互具有潜在的不安全性,所以务必要小心使用。其中特别要注意:
|
Swift很努力地使与C语言指针的交互更加便利,因为它们广泛地存在于Cocoa之中,同时保持一定的安全性。然而,相比你的其他Swift代码与C语言的指针交互具有潜在的不安全性,所以务必要小心使用。其中特别要注意:
|
||||||
- 如果被调用者为了在其返回值之后再次使用而保存了C指针的数据,那么这些转换使用起来并不安全。转换后的指针仅在调用期间保证有效。甚至你将同样的变量、数组或字符串作为多指针参数再次传递,你每次都会收到一个不同的指针。这个异常将全局或静态地储存为变量。你可以安全地将这段地址当作永久唯一的指针使用。例如:作为一个KVO上下文参数使用的时候。
|
- 如果被调用者为了在其返回值之后再次使用而保存了C指针的数据,那么这些转换使用起来并不安全。转换后的指针仅在调用期间保证有效。甚至你将同样的变量、数组或字符串作为多指针参数再次传递,你每次都会收到一个不同的指针。这个异常将全局或静态地储存为变量。你可以安全地将这段地址当作永久唯一的指针使用。例如:作为一个KVO上下文参数使用的时候。
|
||||||
|
|
||||||
|
|||||||
@ -74,4 +74,3 @@
|
|||||||
本章节不是老码的原创,老码认真的阅读了苹果的官方博客,且自己的练习总结,如果小伙伴们费了吃奶的劲还是看不懂,请找度娘谷歌,还是看不懂请到老码[官方微博](http://weibo.com/u/5241713117)咆哮。
|
本章节不是老码的原创,老码认真的阅读了苹果的官方博客,且自己的练习总结,如果小伙伴们费了吃奶的劲还是看不懂,请找度娘谷歌,还是看不懂请到老码[官方微博](http://weibo.com/u/5241713117)咆哮。
|
||||||
|
|
||||||
##### 本文由翻译自Apple Swift Blog :[Value and Reference Types](https://developer.apple.com/swift/blog/?id=10)
|
##### 本文由翻译自Apple Swift Blog :[Value and Reference Types](https://developer.apple.com/swift/blog/?id=10)
|
||||||
|
|
||||||
|
|||||||
@ -33,8 +33,3 @@ Swift的访问控制等级和继承无关,是单维度、非常清楚明了的
|
|||||||
本章节不是老码的原创,是老码认真的阅读了苹果的官方博客,自己的练习总结,如果小伙伴们费了吃奶的劲还是看不懂,请找度娘谷歌。还是看不懂?请到老码[官方微博](http://weibo.com/u/5241713117)咆哮。
|
本章节不是老码的原创,是老码认真的阅读了苹果的官方博客,自己的练习总结,如果小伙伴们费了吃奶的劲还是看不懂,请找度娘谷歌。还是看不懂?请到老码[官方微博](http://weibo.com/u/5241713117)咆哮。
|
||||||
|
|
||||||
##### 本文由翻译自Apple Swift Blog :[Access Control and Protected](原文地址:https://developer.apple.com/swift/blog/?id=11)
|
##### 本文由翻译自Apple Swift Blog :[Access Control and Protected](原文地址:https://developer.apple.com/swift/blog/?id=11)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user