2016-05-15 100 views
2

我創建了下面的類爲什麼我可以更改/從

class Person { 
    var firstName: String 
    var lastName: String 

    init(firstName: String, lastName: String) { 
     self.firstName = firstName 
     self.lastName = lastName 
    } 


    func fullName() -> String { 
     return "\(firstName) \(lastName)" 
    } 
} 

然後一類重新分配恆定值實例化我從類

let john = Person(firstName: "Johnny", lastName: "Applessed") 

問題實例化一個恆定值:爲什麼我可以更改變量john的內容?這不是一個常數嗎?有人能爲我解釋這一點,非常感謝。

john.firstName = "John" 

print(john.firstName) // -> John 

回答

3

由於@Wain has said - 這是由於引用類型的本質。這個常量只是一個let意味着你不能爲它分配一個新的引用 - 但沒有提到實例本身的實際可變性。

如果你改變你的類的結構,你會看到的行爲與價值有何不同類型,更改屬性改變你Person的實際價值 - 因此你不能這樣做,如果它是一個let不變。但是我有些懷疑你會想讓你的Person成爲一個結構,因爲兩個同名的人不應該被認爲是同一個人。

如果你只希望你的屬性在初始化時被賦值(然後只讀實例的生命期),那麼我會建議將它們設爲let常量(而不是使它們的setter私有)。這將確保你一旦分配完畢,甚至不能從班內改變他們的價值。

規則是隻要你給一個屬性super.init()調用之前的值 - 你可以把它let常數(在這種情況下,你就必須使用self前爲它們分配在初始化器)。

class Person { 
    let firstName: String 
    let lastName: String 

    init(firstName: String, lastName: String) { 
     self.firstName = firstName 
     self.lastName = lastName 
    } 

... 
+0

非常感謝您的幫助,非常好的解釋! – SLN

+0

@SLN高興地幫助:) – Hamish

2

類的實例本身是一個常數,所以你不能改變它引用另一個實例,但該實例是可變的,因爲它的屬性爲var小號創建。

變化firstName有一個私人二傳手,看看你能做些什麼:

private(set) var firstName: String 
+0

我開始明白了,我創建了另一個類'Animals',我嘗試將它分配給'john',然後編譯器發出了一個錯誤消息。 – SLN

1

當您在swift中使用類的常量實例時,並不意味着您無法更改類屬性。這意味着你不能在這個不斷

let person = Person(firstName: "Johnny", lastName: "Appleseed") 
person = Person(firstName: "John", lastName: "Appleseed") //--->It gets error: Cannor assign to value: 'person' is a 'let' constant 

實例化一個新的對象,但你可以創建一個恆定的內部類,並在init設置這個值

class Person { 
    let firstName: String 
    let lastName: String 

    init(firstName: String, lastName: String) { 
     self.firstName = firstName 
     self.lastName = lastName 
    } 


    func fullName() -> String { 
     return "\(firstName) \(lastName)" 
    } 
} 

//Tip: Don't init the class constants in declaration time or will get the same above error. Just init this constants at constructor/initialization of class. 

,現在你有預期的結果你想,即使創建該對象

var person = Person(firstName: "Johnny", lastName: "Appleseed") 
person.firstName = "John" //--->It gets error: Cannor assign to value: 'person' is a 'let' constant 

person = Person(firstName: "John", lastName: "Snow") 
person.firstName = "Johnny" //--->It gets error: Cannor assign to value: 'person' is a 'let' constant 

你的想法是沒有錯的「變種」的實例,但有點迷惑,因爲你是完全正確的,如果它是一個結構,而不是一類。

+0

@ ded.exe非常感謝您的幫助,非常好的代碼示例。 – SLN

+0

不客氣,@SLN –

相關問題