我們知道classes是引用類型,structs屬于值類型。這就意味著,當(dāng)你傳遞一個(gè)class,Swift傳遞的是對(duì)象的引用,而當(dāng)你傳遞一個(gè)struct,Swift傳遞的是對(duì)象的值。
在playground寫下如下代碼,看看它的輸出及其效果。
上面分別定義了一個(gè)結(jié)構(gòu)體一個(gè)類,它們都只有一個(gè)變量。代碼分別生成一個(gè)struct和class,并保存它們至相應(yīng)的變量中,然后分別賦值它們至第二個(gè)變量,最后代碼改變了第二個(gè)變量的屬性。
我們可以發(fā)現(xiàn),在struct示例中,只有第二個(gè)變量的foo屬性改變了,然而在class示例下,兩個(gè)變量的屬性都改變了。這就是引用類型與值類型的不同。當(dāng)你把classA賦值給classB,Swift使用同樣的引用,因此,classA與classB指向同一個(gè)實(shí)例的引用。而當(dāng)你將structA賦值給structB時(shí),Swift進(jìn)行了拷貝,所以現(xiàn)在存在兩個(gè)不同的struct。
注:Swift有copy-on-write機(jī)制,它可以機(jī)智到只有在需要的時(shí)候才拷貝struct的值。也就是說,structB=structA,不會(huì)立即進(jìn)行拷貝,因?yàn)槠鹗紩r(shí)候structA,structB值是相同的。只有你開始改變值了,runtime才進(jìn)行拷貝處理。
為進(jìn)一步描述,我們看下圖:
當(dāng)class、structs作為一個(gè)常量,它們有另一個(gè)細(xì)微、重要且不同的地方。
回顧我們以前學(xué)的知識(shí),我們知道,var 和let分別定義變量和常量。當(dāng)實(shí)例化為變量時(shí),class與struct擁有一樣的行為。你可以改變它們的屬性或者賦予它們新值。當(dāng)實(shí)例化為常量時(shí)候,class與structs有一些不同。下面讓我們一探究竟。
? class為常量時(shí),你可以改變它的屬性,但不能重新賦值該常量class到其它不同的或者新的class實(shí)例中。
? struct為常量時(shí),你不但不能賦值,就連它的屬性你也不能改變。
下圖可以演示給我們看看效果(你最好親自實(shí)踐一下,這樣印象會(huì)更深刻)
因?yàn)樵赟wift中常量structs是完全不可改變的,這是arrays以及dictionaries之所以是structs而不是classes的原因之一。