From 151049f46c0ab5cd47686f9f30a2df5dbce1dfe3 Mon Sep 17 00:00:00 2001 From: JaySurplus Date: Tue, 10 Jun 2014 02:46:42 -0500 Subject: [PATCH] Done Assignment and Copy Behavior for Dictionaries Starting Assignment and Copy Behavior for Arrays --- source/chapter2/09_Classes_and_Structures.md | 49 +++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/source/chapter2/09_Classes_and_Structures.md b/source/chapter2/09_Classes_and_Structures.md index 39dac583..b8c3d304 100644 --- a/source/chapter2/09_Classes_and_Structures.md +++ b/source/chapter2/09_Classes_and_Structures.md @@ -103,7 +103,7 @@ Swift 中类和结构体有很多共同点。共同处在于: 值类型被赋予给一个变量,常数或者本身被传递给一个函数的时候,实际上操作的是其的拷贝。 -在之前的章节中,我们已经大量使用了值类型。实际上,在Swift 中,所有的基本类型:整数(Integer)、浮点数(floating-point)、布尔值(Booleans)、字符串(string)、阵列(array)和字典(dictionaries),都是值类型,并且都是以结构体的形式在后台所实现。 +在之前的章节中,我们已经大量使用了值类型。实际上,在Swift 中,所有的基本类型:整数(Integer)、浮点数(floating-point)、布尔值(Booleans)、字符串(string)、数组(array)和字典(dictionaries),都是值类型,并且都是以结构体的形式在后台所实现。 在Swift中,所有的结构体和枚举都是值类型。这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。 @@ -197,5 +197,52 @@ Swift 中类和结构体有很多共同点。共同处在于: 当你在定义你的自定义类和结构体的时候,你有义务来决定判定两个实例“相等”的标准。在章节[Equivalence Operators](http://)中将会详细介绍实现自定义“等于”和“不等于”运算符的流程。 +### 指针 +如果你有C,C++或者Objective-C语言的经验,那么你也许会知道这些语言使用指针来引用内存中的地址。一个Swift 常量或者变量引用一个引用类型的实例与C语言中的指针类似,不同的是并不直接指向内存中的某个地址,而且也不要求你使用星号(*)来表明你在创建一个引用。Swift 中这些引用与其它的常量或变量的定义方式相同。 +### 类和结构体的选择 +在你的代码中,你可以使用类和结构体来定义你的自定义数据类型。 + +然而,结构体实例总是通过值传递,类实例总是通过引用传递。这意味两者适用不同的任务。当你的在考虑一个工程项目的数据构造和功能的时候,你需要决定每个数据构造是定义成类还是结构体。 + +按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体: + +* 结构体的主要目的是用来封装少量相关简单数据值。 +* 有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。 +* 任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。 +* 结构体不需要去继承另一个已存在类型的属性或者行为。 + +合适的结构体候选者包括: + +* 几何形状的大小,封装一个`width`属性和`height`属性,两者均为`Double`类型。 +* 一定范围内的路径,封装一个`start`属性和`length`属性,两者均为`Int`类型。 +* 三维坐标系内一点,封装`x`,`y`和`z`属性,三者均为`Double`类型。 + +在所有其它案例中,定义一个类,生成一个它的实例,并通过引用来管理和传递。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。 + +### 集合(Collection)类型的赋值和拷贝行为 +Swift 中`数组(Array)`和`字典(Dictionary)`类型均以结构体的形式实现。然而当数组被赋予一个常量或变量,或被传递给一个函数或方法时,其拷贝行为与字典和其它结构体有些许不同。 + +以下对`数组`和`结构体`的行为描述与对`NSArray`和`NSDictionary`的行为描述在本质上不同,后者是以类的形式实现,前者是以结构体的形式实现。`NSArray`和`NSDictionary`实例总是以对已有实例引用,而不是拷贝的方式被赋值和传递。 + +>以下是对于数组,字典,字符串和其它值的`拷贝`的描述。 +在你的代码中,拷贝好像是确实是在有拷贝行为的地方产生过。然而,在Swift 的后台中,只有确有必要,`实际(actual)`拷贝才会被执行。Swift 管理所有的值拷贝以确保性能最优化的性能,所以你也没有必要去避免赋值以保证最优性能。(实际赋值由系统管理优化) + +### 字典类型的赋值和拷贝行为 +无论何时将一个`字典`实例赋给一个常量或变量,或者传递给一个函数或方法,这个字典会即会在赋值或调用发生时被拷贝。在章节[Structures and Enumerations Are Value Types](http://)将会对此过程进行详细介绍。 + +如果`字典`实例中所储存的键(keys)和/或值(values)是值类型(结构体或枚举),当赋值或调用发生时,它们都会被拷贝。相反,如果键(keys)和/或值(values)是引用类型,被拷贝的将会是引用,而不是被它们引用的类实例或函数。`字典`的键和值的拷贝行为与结构体所储存的属性的拷贝行为相同。 + +下面的示例定义了一个名为`ages`的字典,其中储存了四个人的名字和年龄。`ages`字典被赋予了一个名为`copiedAges`的新变量,同时`ages`在赋值的过程中被拷贝。赋值结束后,`ages`和`copiedAges`成为两个相互独立的字典。 + + var ages = ["Peter": 23, "Wei": 35, "Anish": 65, "Katya": 19] + var copiedAges = ages + +这个字典的键(keys)是`字符串(String)`类型,值(values)是`整(Int)`类型。这两种类型在Swift 中都是值类型(value types),所以当字典被拷贝时,两者都会被拷贝。 + +我们可以通过改变一个字典中的年龄值(age value),检查另一个字典中所对应的值,来证明`ages`字典确实是被拷贝了。如果在`copiedAges`字典中将`Peter`的值设为`24`,那么`ages`字典仍然会返回修改前的值`23`: + + copiedAges["Peter"] = 24 + println(ages["Peter"]) + // prints "23"