Wednesday, 28 December 2016

[Swift] Phân biệt let và var - giữa struct và class - [phần 1]

Để bắt đầu serial Kiến thức phỏng vấn cho lập trình viên iOS, mình xin đề cập đến hai khái niệm let và var trong ngôn ngữ Swift mà các bạn khi phỏng vấn sẽ rất hay hỏi.

Mình sẽ dùng phiên bản mới nhất đó là Swift 3 và mới hơ

I - Khái niệm:

var vs let - sẽ tương ứng với hai khái niệm biến số và hằng số

VD:
let wife = "Joana"
var darling = "Beautiful Girl"
Hai dòng code trên có ý nghĩa như sau:
"Khai báo một hằng số tên là wife, có giá trị là Joana. Tiếp theo, khai báo một biến số tên là darling và cho nó một giá trị khởi tại là  Beautiful Girl."

Tiếp theo,

wife = "New wife"
compile thấy xuất hiện lỗi:
note: change 'let' to 'var' to make it mutable
Nghĩa là bạn không thể thay đổi giá trị của let.
cannot assign to value: 'wife' is a 'let' constant

Value type vs Reference type - Kiểu giá trị và kiểu tham chiếu:

Value type là loại biến có giá trị được sao chép khi thực hiện phép gán với một biến hoặc hằng số khác, hoặc khi nó được truyền vào function.

VD:


struct GirlFriend:CustomStringConvertible {
   var name:String
   var character:String
   var description:String {
       return "Her name is \(name), she is a \(character) girl."
   }
}
// It's the automatically-generated memberwise initializerlet joana = GirlFriend(name: "joana", character: "So crazy")
var otherGirl = joanaotherGirl.name = "Miss World"
print(joana)
// Print: Her name is joana, she is a So crazy girl.
print(otherGirl)
// Print: Her name is Miss World, she is a So crazy girl.


Ngược lại với value type, reference type là loại biến có giá trị không bị sao chép khi thực hiện phép gán với biến hoặc hằng số, hoặc khi nó được truyền vào một hàm. Nghĩa là một tham chiếu từ một thực thể(instance) của class đã tồn tại sẽ được thay thế.

VD: 
class BestFriend:CustomStringConvertible {
    var name:String
    var character:String
    init(_ name:String,_ character:String? = nil) {
     self.name = name
     if character != nil {
         self.character = character!
     } else {
         self.character = ""
     }
   }
    var description:String { return "The name of she/he is \(name), he/she is a \(character) girl/boy." }
}
let anonymous = BestFriend("Anonymous")let someone = anonymoussomeone.name = "Chung"
print(someone)// Print: The name of she/he is Chung, he/she is a  girl/boy.
print(anonymous)// Print: The name of she/he is Chung, he/she is a  girl/boy.
II - Ví dụ và những câu hỏi thực thế:

1.
let anonymous = BestFriend("Anonymous")
let someone = anonymous
someone.name = "Chung"

thì anonymous có thay đổi ko? Giải thích tại sao?

Một câu hỏi tương tự đối với class.

2. vậy có thể so sánh khác nhau giữa đối tượng giữa các thực thể ko?
Answer: Mình xin nói tại đây đó là sự khác nhau được hiểu là hai thực thể đó có tham chiếu về cùng một thực thể hay ko? VD như anonymous vs someone, chúng cùng tham chiếu về một thực thể.

Chúng ta sẽ có khái niệm: Identity Operators for class
Ex:
if anonymous !== someone {    
     print("true") 
} 
if anonymous === someone {    
     print("true") 
}


Với struct, các bạn sẽ phải sử dụng kiến thức Overloading on operators. Tham khảo tại http://nshipster.com/swift-operators/

3. Chúng ta có ví dụ như sau:

let anonymous = BestFriend("Anonymous") 
let arrayWithClassItem = [anonymous] 
let classItem = arrayWithClassItem[0]
classItem.name = "Benjamin" 
let classItem1 = arrayWithClassItem[0]


classItem1.name = ???

let joana = GirlFriend(name: "joana", character: "So crazy") 
let arrayWithStructItem = [joana] 
var structItem = arrayWithStructItem[0] 
structItem.name = "Anonymous" 
let structItem1 = arrayWithStructItem[0]

structItem1.name = ???


III - Sum up:

Trên chỉ là một vài điểm cơ bản khi nói với về var và let, thông thường khi đi phỏng vấn, bạn sẽ được hỏi sang những kiến thức class và struct như ví dụ trên.

Có thể  trong lúc phỏng vấn, bạn được khai thác hết ví dụ như trên, bạn sẽ bị hỏi về class vs struct về mặt What?How?When? mình sẽ viết thêm về vào chương sau.

Xin nhận góp ý từ mọi người,
Chung.