Tải bản đầy đủ
Bài 3. CĂN BẢN VỀ LẬP TRÌNH SWIFT (P3)

Bài 3. CĂN BẢN VỀ LẬP TRÌNH SWIFT (P3)

Tải bản đầy đủ

1 iflet convertedRank = Rank(rawValue: 11) {
2 let threeDescription = convertedRank.simpleDescription()
3}

Giá trị 11 đã được chuyển đổi thành giá trị enum .Jack. Như vậy, giá trị threeDescription sẽ có
giá trị là “jack”.
Khi khai báo kiểu enum thì bạn không cần nhất thiết phải khai báo theo kiểu giá trị thô (raw
value) của những thành viên. Đoạn code sau đây sẽ minh hoạ điều này:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

enum Suit {
case Spades, Hearts, Diamonds, Clubs
func simpleDescription() -> String {
switch self {
case .Spades:
return "spades"
case .Hearts:
return "hearts"
case .Diamonds:
return "diamonds"
case .Clubs:
return "clubs"
}
}
}
let hearts = Suit.Hearts
let heartsDescription = hearts.simpleDescription()

Code đoạn code phía trên rồi chạy trên 1 playground, bạn có thể được giá trị “hearts” cho hằng
heartsDescription.
Một điểm rất đặc biệt trong kiểu enum của Swift đó là nó sẽ cho phép khai báo thành viên như
một macro trong C++. Cùng xem qua đoạn code sau:

1
2
3
4
5
6
7
8

enum ServerResponse {
case Result(String, String)
case Error(String)
}
let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Error("Out of cheese.")

12

9
10 switchfailure {
11 caselet .Result(sunrise, sunset):
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
12
13 caselet .Error(error):
let serverResponse = "Failure... \(error)"
14
}

Trong playground, đoạn code phía trên sẽ in ra kết quả “Failure… Out of cheese”. Lý do là vì
error (trong dấu ngoặc) được thay thế bằng chuỗi “Out of cheese.” ở câu lệnh switch.
2. Structures.
Mỗi cấu trúc (structure) trong Swift rất giống với một lớp (class). Mọi thành phần của một
structure có thể gồm những biến thành viên (property) và hàm (method). Điểm khác biệt khá là
quan trọng giữa 1 cấu trúc và 1 lớp là khi sử dụng thì instance của cấu trúc sẽ được truyền bằng
cách sao chép, còn instance của lớp sẽ được truyền bằng tham trị (reference).
Để có thể khai báo một cấu trúc, bạn hãy dùng từ khoá “struck” như sau:

1
2
3
4
5
6
7
8
9

struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

3. Protocols và Extensions.
Giống như trong Objective C, chúng ta dùng từ khoá “protocol” để khai báo 1 Protocol:

1 protocol ExampleProtocol {
2 var simpleDescription: String { get }
3 mutating func adjust()
4}

Protocol khai báo method tuy nhiên nó lại không thưc hiện chúng. Những method này sẽ được
thực hiện trong lớp (class), cấu trúc (struct) hay enum. Giả dụ:

13

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {
simpleDescription += " Now 100% adjusted.”
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription.

Chú ý rằng trong cấu trúc SimpleStructure thì chúng ta dùng từ khoá “mutating” để có thể cho
phép method “adjust” thay đổi giá trị của biến thành viên của cấu trúc đó, trong khi đó class
“SimpleClass” không cần sử dụng tới từ khoá này. Nguyên nhân là do instance của cấu trúc
luôn luôn được copy khi truyền, cò class thì luôn được truyền bằng tham trị (reference).
Extension chính là cách thêm chức năng tới 1 kiểu đang tồn tại (tương tự như category trong
Objective C). Ví dụ sau đây thêm method “simpleDescription” và “adjust” cho kiểu Int:

1 extension Int: ExampleProtocol {
2 var simpleDescription: String {
3
return "The number \(self)"
4 }
5 mutating func adjust() {
6
self += 42
7 }
8}
9 8.simpleDescription

Một điều khá là thú vị đó là bạn hoàn toàn có thể khai báo 1 biến/hằng với kiểu là 1 protocol. Ở
ví dụ trước chúng ta đã khai báo protocol tên là “ExampleProtocol”. Giờ thì bạn có thể viết:

14

1 let protocolValue: ExampleProtocol = a
2 protocolValue.simpleDescription

Giá trị “a” ở đây thông thường sẽ là instance của class hay structure đã thực hiện protocol
“ExampleProtocol”. Nhưng “protocolValue” chỉ có thể gọi được những hàm đã được khai báo
trong “ExampleProtocol” mà không thể gọi được những hàm riêng của class hay structure.
4. Generics
Giống với Java và C++, Swift cũng đưa ra khái niệm về Generic. Để khai báo Generic chúng ta
sẽ dùng dấu <> như sau:

1 func repeat(item: ItemType, times: Int) -> [ItemType] {
2 var result = [ItemType]()
3 for i in 0..4
result.append(item)
5 }
6 return result
7}
8 repeat("knock", 4)

Hàm trên nhận 2 tham số input, trong đó tham số item sẽ có kiểu Generic là “ItemType”. Hàm
trả về mảng bao gồm các đối tượng có kiểu “ItemType”.
Generic có thể được dùng cho class, tructure, enum. Sau đây là minh hoạ cho việc dùng enum:

1
2
3
4
5
6

enum OptionalValue {
case None
case Some(T)
}
var possibleInteger: OptionalValue = .None
possibleInteger = .Some(100)

Đến đây mình đã cùng bạn nắm được những khái niệm cơ bản của Swift gồm có enum,
tructure, protoco, extension và generic. Bài viết hôm nay chỉ mang tính giới thiệu do đó mình
không đi sâu vào chi tiết việc sử dụng chúng, nếu các bạn quan tâm có thể tìm hiểu thêm trong
những bài viết sau.

15

BÀI 4. SỬ DỤNG KIỂU ENUM TRONG LẬP TRÌNH SWIFT
So với các kiểu enum truyền thống trong Java, C++ hay Objective-C thì kiểu enum trong Swift
có rất nhiều đổi thay. Qua bài viết hôm nay, chúng ta sẽ tìm hiểu sâu hơn về kiểu enum qua đó
chúng ta có thể áp dụng nó một cách hiệu quả nhất.
1. Khai báo kiểu enum
Để khai báo 1 kiểu enum thì bạn sử dụng từ khoá “enum” cùng với những dấu ngoặc nhọn. Giả
dụ:

1
2
3
4
5
6

enum Direction {
case East
case West
case South
case North
}

Sự khác biệt với những kiểu enum truyền thống đó là ở chỗ những giá trị như East, West, South
và North không tương xứng với những số nguyên. Trái lại, các bạn sẽ thấy ở phần sau rằng
chúng ta hoàn toàn có thể chỉ định được giá trị đơn (raw value) hay giá trị liên hợp cho chúng.
Bạn cũng cần để ý rằng dấu phẩy cũng đã được bỏ đi trong khai báo enum của Swift.
Những thành viên của kiểu enum hoàn toàn có thể nằm phía trên cùng một dòng và ngăn cách
nhau bằng dấu phẩy:

1 enum Direction {
2 case East, West, South, North
3}
Sau khi đã khai báo 1 kiểu enum thì chúng ta có thể khai báo biến hay hằng cho kiểu enum
này:

1 var onedirection = Direction.East

16

Sau đó do kiểu của onedirection đã biết, chúng ta có thể viết:

1 onedirection = .West
2. Sử dụng kiểu enum cùng với câu lệnh Swift
Tiếp tục ví dụ trên, khi biến onedirection đã được suy luận kiểu hoặc khi sử dụng trong câu
lệnh Switch, chúng ta hoàn toàn có thể lược bớt phần tên kiểu enum và chỉ giữ lại tên của thành
viên (member) của kiểu enum đó:

1
2
3
4
5
6
7
8
9
10

switch onedirection {
case .East:
println(“The East”)
case .West:
println(“The West”)
case .South:
println(“The South”)
case .North:
println(“The North”)
}

Trong câu lệnh Switch thì mọi trường hợp đều phải được xem xét. Do vậy nếu như thiếu bạn
không liệt kê đầy đủ mọi trường hợp, cần phải thêm “default”:

1
2
3
4
5
6

switch onedirection {
case .West:
println(“This is the West”)
default:
println(“Other cases”)
}

3. Giá trị liên hợp trong kiểu enum
Như ở phần 3 chúng ta đã đề cập thì trong kiểu enum ta có thể khai báo 1 loại cú pháp giống
như Macro trong C++. Đây cũng chính là kiểu giá trị liên hợp (associated value) sử dụng trong
enum Swift. Mục đích của nó chính là khai báo mỗi thành viên như là một tập các giá trị có
mối quan hệ với nhau. Cùng theo dõi ví dụ sau:

17