Swift学习笔记(9)—— 类和结构体

9.类和结构体

定义方法

跟C/JAVA基本一样。
类使用class关键字,结构体使用struct关键字。

实例

是java差不多,不过不需要new这个词。

var myClass = MyClass()
let myStruct = MyStruct()

属性访问

嗯,使用点.

myClass.value1

可以用这个方法获取值/修改值。

结构体类型的逐一构造器

所有的结构体都默认会有的一个构造器。
比如

struct MyStruct{
    var a = 0
    var b = 0
}

//使用逐一构造器
let myStruct = MyStruct(a:20,b:30);

类没有默认的逐一构造器!!!

结构体和枚举是值类型 & 类是引用类型

结构体和枚举是值类型

——在代码传递的时候会被复制。

类是引用类型

——在代码传递的时候默认是地址引用。
(相当于C语言中的指针)

恒等运算符

  • === 恒等于
  • !== 不恒等于

用以比较两个变量所引用的类实例地址是否是一样的。

集合类型的赋值和拷贝行为

字典会被拷贝

将一个字典类型的实例赋值给一个变量或常量时,或者传递给一个函数或方法,这个字典类型会在传递时被拷贝
如果字典的keyvalue是值类型,则会被拷贝;如果是引用类型,则会被拷贝引用。
—— 即, 与key和value的拷贝行为与结构体所存储的属性的拷贝行为相同。

class Name {
    var a :String = "Zhang"
    var b :String = "Wang"
}

var d1 : Dictionary<String, Name > = ["key":Name(), "key2":Name()]
var d2 = d1 // 把d1的值传递给d2,会发生拷贝
println(d2["key2"]!.a) // "Zhang"
println(d1["key2"]!.a) // "Zhang"

d2["key2"]!.a = "Zhang2"
println(d2["key2"]!.a) // 输出 "Zhang2"
println(d1["key2"]!.a) // 输出 "Zhang2",因为Name类是引用类型,所以拷贝的是地址,当修改d2["key2"]的值时候,d1["key2"]也会反映出其修改  

数组的赋值和拷贝

数组的行为要复杂一点咯。
数组类型的实例赋值给一个变量时,数组不会被拷贝,而仅仅传递引用。
但是当数组发生可能改变长度的行为时,数组会被拷贝(注意“可能发生”中的可能)——比如数组的插入、删除、范围赋值等操作。

var a = [1, 2, 3]
var b = a
var c = a

println(a[0]) // 1
println(b[0]) // 1
println(c[0]) // 1 

a[0] = 7 
println(a[0]) // 7
println(b[0]) // 7
println(c[0]) // 7 
// 以为默认为引用传递,所以改变a[0]的值,b[0],c[0]也会同样改变——指向同一地址。

b.append(4)
b[0] = 42
a[0] = 8
println(a[0]) // 8
println(b[0]) // 42
println(c[0]) // 8
// 因为给b数组执行的可能改变长度的操作(append),所以b数组产生了拷贝行为,不再跟a数组、c数组指向同一已地址。 所以 b[0]的修改不会再影响a[0]、c[0]的值;而a、c仍是同一地址,所以修改a[0]同样会影响c[0] 

确保数组的唯一性

.unshare()方法

调用数组的unshare()方法,确保其是唯一的。

var a = [1, 2, 3]
var b = a
var c = a
a.unshare() 
a[0] = 7
println(a[0]) // 7
println(b[0]) // 1
println(c[0]) // 1

a.unshare()被调用之后,a[0]的修改不会再影响b[0]跟c[0]

判断两个数组是否共用相同元素

嗯,不错使用恒等于===不恒等于!==
也可以使用范围判断:

var a = [1, 2, 3]
var b = a
println(a===b) //false 因为a和b指向的地址一样,但a和b自身的地址不一样
println(a[0...2] === b[0...2]) // true 因为b[0...2]跟b[0...2]的地址是一样的(a到b时引用传递)

a.unshare()
println(a===b)
println(a[0...2] === b[0...2]) // false  因为调用unshare()之后,a、b指向的地址不再一样

强制复制数组: copy()方法

注意:
如果你仅需要确保你对数组的引用是唯一引用,请调用unshare方法,而不是copy方法。unshare方法仅会在确有必要时才会创建数组拷贝。copy方法会在任何时候都创建一个新的拷贝,即使引用已经是唯一引用。



这笔记只是给我自己看的,用以标记一些我觉得需要记的或者有意思的一些知识点,有很多我觉得没必须要赘述的东西就没记,所以是不系统的,只作提示用。
感谢 numbbbbb以及其他贡献者: https://github.com/numbbbbb/the-swift-programming-language-in-chinese
当然,还有英文页: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-XID_70


http://www.barryzhang.com/archives/258

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*