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)的拷貝。