我們知道classes是引用類型峦剔,structs屬于值類型档礁。這就意味著,當(dāng)你傳遞一個(gè)class,Swift傳遞的是對(duì)象的引用吝沫,而當(dāng)你傳遞一個(gè)struct,Swift傳遞的是對(duì)象的值呻澜。
在playground寫(xiě)下如下代碼,看看它的輸出及其效果惨险。
上面分別定義了一個(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的值。也就是說(shuō)盒蟆,structB=structA踏烙,不會(huì)立即進(jìn)行拷貝,因?yàn)槠鹗紩r(shí)候structA,structB值是相同的历等。只有你開(kāi)始改變值了讨惩,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的原因之一唇辨。