Swift結構體和枚舉是值類型
結構體和枚舉是值類型
值類型被賦予給一個變量,常數或者本身被傳遞給一個函數的時候,實際上操作的是其的拷貝。
在之前的章節中,我們已經大量使用了值類型。實際上,在 Swift 中,所有的基本類型:整數(Integer)、浮點數(floating-point)、布爾值(Booleans)、字符串(string)、數組(array)和字典(dictionaries),都是值類型,並且都是以結構體的形式在後台所實現。
在 Swift 中,所有的結構體和枚舉都是值類型。這意味著它們的實例,以及實例中所包含的任何值類型屬性,在代碼中傳遞的時候都會被複製。
請看下麵這個示例,其使用了前一個示例中Resolution
結構體:
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
在以上示例中,聲明了一個名為hd
的常量,其值為一個初始化為全高清視頻分辨率(1920 像素寬,1080 像素高)的Resolution
實例。
然後示例中又聲明了一個名為cinema
的變量,其值為之前聲明的hd
。因為Resolution
是一個結構體,所以cinema
的值其實是hd
的一個拷貝副本,而不是hd
本身。儘管hd
和cinema
有著相同的寬(width)和高(height)屬性,但是在後台中,它們是兩個完全不同的實例。
下麵,為了符合數碼影院放映的需求(2048 像素寬,1080 像素高),cinema
的width
屬性需要作如下修改:
cinema.width = 2048
這裡,將會顯示cinema
的width
屬性確已改為了2048
:
println("cinema is now \(cinema.width) pixels wide")
// 輸出 "cinema is now 2048 pixels wide"
然而,初始的hd
實例中width
屬性還是1920
:
println("hd is still \(hd.width ) pixels wide")
// 輸出 "hd is still 1920 pixels wide"
在將hd
賦予給cinema
的時候,實際上是將hd
中所儲存的值(values)
進行拷貝,然後將拷貝的數據儲存到新的cinema
實例中。結果就是兩個完全獨立的實例碰巧包含有相同的數值。由於兩者相互獨立,因此將cinema
的width
修改為2048
並不會影響hd
中的寬(width)。
枚舉也遵循相同的行為準則:
enum CompassPoint {
case North, South, East, West
}
var currentDirection = CompassPoint.West
let rememberedDirection = currentDirection
currentDirection = .East
if rememberDirection == .West {
println("The remembered direction is still .West")
}
// 輸出 "The remembered direction is still .West"
上例中rememberedDirection
被賦予了currentDirection
的值(value),實際上它被賦予的是值(value)的一個拷貝。賦值過程結束後再修改currentDirection
的值並不影響rememberedDirection
所儲存的原始值(value)的拷貝。