Tải bản đầy đủ (.docx) (46 trang)

Lập trình SWIFT cho IOS

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (413.66 KB, 46 trang )

LẬP TRÌNH SWIFT
BÀI 1. SƠ LƯỢC VỀ NGÔN NGỮ LẬP TRÌNH SWIFT
Swift là một ngôn ngữ lập trình để phát triển app trên nền tảng iOS và Mac OS X. Nó được xây
dựng dựa trên nền tảng C và Objective C tuy nhiên không hề bị rằng buộc về mặt phải được
tương thích với C. Swift cũng tuân theo những pattern lập trình an toàn, nó cũng có những tính
năng hiện đại có thể giúp cho việc lập trình với Swift trở nên dễ dàng và linh hoạt hơn.
Swift được Apple giới thiệu vào tháng 6 năm ngoái. Ngôn ngữ này kế thừa những điểm mạnh
của Objective C. Và hơn thế nữa, Swift có rất nhiều cải tiến về quản lý bộ nhớ, trình biên dịch
và cú pháp lệnh. Nếu bạn đã từng được học qua Python thì bạn có thể thấy Swift có những nét
tương đồng với Python (scripting language) dù Swift vẫn cần dùng tới trình biên dịch
(compiler).
Bài này mình sẽ hướng dẫn sơ lược về ngôn ngữ lập trình này. Các bài sau chúng sẽ đi vào ứng
dụng cụ thể của Swift.
1. Hàm main
Đối với Objective C, chúng ta luôn cần hàm main trong tất cả ứng dụng. Tuy nhiên đối với
swift (giống như một ngôn ngữ scripting) thì hàm main có thể được bỏ qua. Ví dụ, bạn có thể
viết:

1 Println(“Hello world”)
Đây hoàn toàn có thể là 1 chương trình hoàn thiện với chỉ một dòng lệnh duy nhất. Chú ý khác
với Objective C chúng ta sẽ cần ký tự @trước mỗi một String tuy nhiên đối với Swift ký tự này
đã bị bỏ qua.
2. Biến và hằng số
Để khai báo biến thì bạn dùng từ khoá var, còn đối với hằng bạn hãy dùng từ khoá let.

1 var myVariable = 42
2 myVariable = 50
3 let myConstant = 42


Hãy để ý rằng Swift sẽ không yêu cầu bạn phải khai báo các kiểu giá trị khi dịch chương trình.


Điều này cũng đồng nghĩa với việc các kiểu giá trị đều sẽ được xác định ở running time. Như
vậy nhiều khả năng Swift sẽ chạy không nhanh bằng Objective C vì Objective C đã xác định
kiểu giá trị lúc biên dịch chương trình.
Bạn cũng có thể chỉ định kiểu giá trị khi khai báo biến hay hằng như sau:

1 let explicitDouble: Double = 70
Để thêm value vào string, bạn có thể sử dụng cách sau:

1
2
3
4
5

let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit
print(fruitSummary)

3. Mảng và từ điển
Bạn có thể tạo ra mảng và từ điển bằng cách dùng ký tự [] như sau:

1
2
3
4
5
6
7


var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations

Hãy chú ý Objective C dùng ký hiệu {} để tạo ra Dictionary. Với cả hai ngôn ngữ này thì
chúng ta sử dụng chỉ số để truy cập thành phần mảng, dùng key để truy cập vào giá trị của
dictionary.
Để tạo ra được mảng rỗng hay dictionary rỗng, bạn có thể sử dụng ký tự dưới đây:

2


1 let emptyArray = [String]()
2 let emptyDictionary = [String: Float]()

Hay đơn giản hơn:

1 shoppingList = []
2 occupations = [:]
4. Điều khiển trong Swift.
Giống như những ngôn ngữ khác, Swift cũng có những điều khiển If, switch và những điều
khiển lặp như là while, do-while, và for. Điều đặc biệt hơn đó là các dấu ngoặc tròn hoàn toàn
có thể bỏ qua, tuy nhiên những dấu ngoặc nhọn là bắt buộc:

1

2
3
4
5
6
7
8
9
10

let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
if score > 50 {
teamScore += 3
} else {
teamScore += 1
}
}
print(teamScore)

Với vòng lặp for thì bạn có thể chỉ định dải giá trị lặp như dưới đây:

1 var firstForLoop = 0
2 for i in 0..<4 {
3
firstForLoop += i
4 }
5 println(firstForLoop)


3


Câu lệnh phía trên sẽ in ra giá trị 6 bởi vòng lặp chỉ chạy tới 3. Để cho vòng lặp chạy tới giá trị
cận trên của range, bạn có thể dùng ký hiệu (…) thay vì ..< Điều này có thể là sự mở rộng của
Python bởi Python không cho phép bạn bao gồm cận trên trong vòng lặp for.
Vòng lặp do-while và while trong Swift cũng gần giống như trong những ngôn ngữ lập trình
khác. Sau đây là ví dụ:

1
2
3
4
5
6
7
8
9

var n = 2
while n < 100 {
n=n*2
}
var m = 2
do {
m=m*2
} while m < 100

Để ý rằng ta không cần dùng dấu ngoặc tròn () bên trong biểu thức điều kiện của những vòng
lặp này.

Một khái niệm rất mới mẻ trong Swift đó là Optional. Optional có thể mang những giá trị thực
sự hay bằng nil. Để khai báo 1 biến là optional chúng ta cần thêm dấu hỏi chấm:

1 var optionalString: String? = "Hello"
2 optionalString == nil
Với mỗi giá trị Optional, ta hoàn toàn có thể hạn chế lỗi crash khi lập trình ứng dụng. Xem
đoạn code dưới đây:

1
2
3
4
5

var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
//-your code goes here
}

Ở đoạn code trên, nếu hằng “name” có giá trị là nil thì đoạn code trong dấu ngoặc nhọn sẽ
không thể được thực hiện. Như vậy nếu như bên trong bạn có một tham chiếu đến “name ” thì
ứng dụng sẽ không crash khi name=nil.

4


Switch trong Swift sẽ là một cải tiến khá lớn. Nó hỗ trợ rất nhiều kiểu dữ liệu (không chỉ là
integer như nhiều ngôn ngữ khác) và còn nhiều phép toán so sánh:


1 let vegetable = "red pepper"
2 switch vegetable {
3
case "celery":
4
let vegetableComment = "Add some raisins and make ants on a log."
5
case "cucumber", "watercress":
6
let vegetableComment = "That would make a good tea sandwich."
7
case let x where x.hasSuffix("pepper"):
8
let vegetableComment = "Is it a spicy \(x)?"
9
default:
10
let vegetableComment = "Everything tastes good in soup."
11 }

Để ý rằng ở đây ta không cần sử dụng lệnh break vì chương trình sẽ nhảy ra khỏi lệnh switch
khi nó thực hiện xong một case. Điều này trái ngược với các ngôn ngữ lập trình khác.
Trên đây là một số quy tắc cơ bản đối với Swift, một ngôn ngữ lập trình mới mẻ được phát
triển bởi Apple mà theo ý kiến chủ quan của mình làm ngôn ngữ lai giữa hai loại “Dynamic
Typing” (Python, PHP, etc.) và “Static Typing” (C/C++/Java, etc.) Chúng ta sẽ cùng tìm hiểu
tiếp về sức mạnh của Swift trong các phần tiếp theo.

5



BÀI 2. CƠ BẢN VỀ NGÔN NGỮ SWIFT (P2)
Ở bài trước chúng ta tìm hiểu khái niệm cơ bản của lập trình swift. Và hôm nay mình sẽ tìm
hiểu 1 số cái mới như hàm (function), closure và lớp (class). Kết thúc bài học hôm nay bạn sẽ
nắm được những điều căn bản của lập trình swift. Bước đầu cảm nhận được sức mạnh và tính
linh hoạt của ngôn ngữ lập trình này.
1. Hàm trong Swift
Hàm trong Swift đã có sự cải tiện cực lớn ,nếu bạn đã ngạc nhiên về cách khai báo hàm khi học
Objective-C thì bạn sẽ càng bất ngờ hơn khi học Swift. Để khai báo hàm bạn cần dùng từ khóa
“func” tương tự như từ khóa “def” trong Python. Và dùng dấu “->” để chỉ ra kiểu giá trị trả về:

1 func greet(name: String, day: String) -> String {
2 return "Hello \(name), today is \(day)."
3}
4 greet("Bob", "Tuesday")”

Còn một khái niệm mới trong Swift là “tuple”. Tuple chính là khái niệm trong lập trình để chỉ
cấu trúc dữ liệu bao gồm nhiều thành phần. Hàm trong Swift cho phép trả về 1 giá trị dưới
dạng Tuple. Và điều này cũng khá là linh hoạt nếu như bạn muốn 1 hàm trả về giá trị nhiều hơn
1:

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17

func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var min = scores[0]
var max = scores[0]
var sum = 0
for score in scores {
if score > max {
max = score
} else if score < min {
min = score
}
sum += score
}
return (min, max, sum)
}
let statistics = calculateStatistics([5, 3, 100, 3, 9])
statistics.sum statistics.2

Đặc biệt hơn, đối với tuple bạn hoàn toàn có thể truy cập những giá trị bằng 2 cách đó là sử
dụng chỉ số và sử dụng tên. Đây chính là 1 lợi thế lớn so với kiểu Array thông thường. Tương
tự với C++, Python và 1 số ngôn ngữ khác thì Swift cho phép hàm được khai báo với số lượng
tham số đầu vào có thể thay đổi được. Cụ thể như sau:


6


1
2
3
4
5
6
7
8
9

func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sumOf()
sumOf(42, 597, 12)

Ở hàm trên, numbers được trình biên dịch ngầm hiểu là có kiểu array, do đó để tìm được giá trị
tổng thì chúng ta có thể lặp qua tất cả giá trị thành viên của array.
Bạn có thể khai báo hàm bên trong bằng 1 hàm khác, hàm trong sẽ có thể truy cập biến được
khai báo ở hàm ngoài. Việc dùng hàm bên trong hàm có ích lợi trong trường hợp hàm của bạn
dài quá hay quá phức tạp. Bạn có thể tổ chức thành những hàm nhỏ và dễ đọc hơn.

1 func returnFifteen() -> Int {

2 var y = 10
3 func add() {
4
y += 5
5 }
6 add()
7 return y
8}
9 returnFifteen()

Trong Swift thì hàm vừa có thể nhận được giá trị đầu vào là hàm khác lại vừa có thể trả về giá
trị là 1 hàm khá. Ví dụ:
Trả về giá trị là 1 hàm

1
2
3
4
5
6
7
8

func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()

increment(7)

Nhận giá trị tham số là 1 hàm khác:

7


1
2
3
4
5
6
7
8
9
10
11
12
13

func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThanTen(number: Int) -> Bool {

return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, lessThanTen)

Swift có đưa ra khái niệm mới gọi là Closure. Bản chất của Closure chính là 1 đoạn code được
giới hạn bởi cặp dấu {}. Hàm thực chất chính là trường hợp đặc biệt của Closủe. Khi sử dụng
Closure bạn cũng có thể không cần dùng tên như bắt buộc dùng từ khóa “in” trong closure đó.
Ví dụ:

1 numbers.map({ (number: Int) -> Int in
2 let result = 3 * number
3 return result
4 })
Closure có thể được đơn giản hoá như thế này:

1 let mappedNumbers = numbers.map({ number in 3 * number })
Việc dùng Closure hiệu quả sẻ làm cho app của bạn ngắn gọn hơn nhưng bạn sẽ cần thêm thời
gian để làm quen với khái niệm này. Closure sẽ được bàn kỹ hơn ở những bài sau nhé.
2. Class trong Swift.
Giống với Java và C++ để có thể khai báo 1 lớp các bạn sử dụng từ khóa class. Những đặc tính
và Method thành viên được khai báo 1 cách bình thường.

8


1 class Shape {
2 var numberOfSides = 0
3 func simpleDescription() -> String {
4

return "A shape with \(numberOfSides) sides."
5 }
6}

Để truy cập biến và hàm, bạn phải dùng dấu chấm “.”

1 var shape = Shape()
2 shape.numberOfSides = 7
3 var shapeDescription = shape.simpleDescription()
Bạn có thể thêm vào đó hàm init để khởi tạo được giá trị cho biến thành viên của lớp như sau:

1 class NamedShape {
2
var numberOfSides: Int = 0
3
var name: String
4
5
init(name: String) {
6
self.name = name
7
}
8
9
func simpleDescription() -> String {
10
return "A shape with \(numberOfSides) sides."
11 }
12 }


Để kế thừa 1 lớp cha, bạn có thể dùng dấu “:”. Để override một method trong lớp cha bạn sử
dụng từ khoá “override”:

1 class Square: NamedShape {
2
var sideLength: Double
3
4
init(sideLength: Double, name: String) {
5
self.sideLength = sideLength

9


6
7
8
9
10
11
12
13
14
15
16
17
18
19

20

super.init(name: name)
numberOfSides = 4
}
func area() -> Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A square with sides of length \(sideLength)."
}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

Giống như trong Objective-C, bạn có thể viết setter & getter cho bất kỳ một property nào của
1 class. Bạn sử dụng từ khoá “set” cho setter & “get” cho getter. Bạn cũng có thể sử dụng
những method “willSet” và “didSet” để có thể chèn thêm vào 1 số đoạn code cần thiết trước &
sau khi set giá trị cho 1 property. Chi tiết về việc dùng setter và getter mình sẽ đề cập trong
những phần tiếp theo.
Một điểm bạn cần lưu ý đó là sự khác biệt giữa method được khai báo bên trong một lớp và
một hàm. Tham số đầu vào của hàm chỉ được dùng trong nội bộ hàm nhưng tham số của
method có thể được dùng khi gọi method đó. Mặt khác có thể khai báo thêm tên cho một tham
số như dưới đây:

1
2
3
4

5
6
7
8

class Counter {
var count: Int = 0
func incrementBy(amount: Int, numberOfTimes times: Int) {
count += amount * times
}
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)

Đến đây bạn đã nắm được thêm khá nhiều khái niệm và cách sử dụng trong lập trình với Swift.
Swift quả thực là một ngôn ngữ vô cùng linh hoạt và cung cấp cho bạn thêm nhiều tính năng
mới mẻ mà các ngôn ngữ lập trình khác không có. Chúc các bạn học tốt.

10


BÀI 3. CĂN BẢN VỀ LẬP TRÌNH SWIFT (P3)
Ở hai phần trước thì mình đã cùng các bạn tìm hiểu về hàm và class của Swift. Hôm nay mình
sẽ giới thiệu 2 khái niệm khá cơ bản gồm Enumerations, Structures, Protocols và Extensions.
Bài viết này sẽ là bài cuối cùng trong series bài giới thiệu về ngôn ngữ lập trình Swift. Những
bài sau chúng ta sẽ tập trung vào cách dùng chi tiết cùng với những framework trong lập trình
iOS.
1. Enumerations
Trong Java, C, C++, Objective C hay các ngôn ngữ lập trình khác, kiểu enum dùng để khai
báo một tập giá trị cho trước, trong đó thì mỗi giá trị sẽ tương ứng với một số nguyên. Trong

Swift thì khái niệm enum lại được mở rộng ra với việc cho phép khai báo hàm trong enum.
Hơn nữa, mỗi một giá trị trong enum đều không nhất thiết cần phải là số nguyên mà hoàn toàn
có thể là số thực, chuỗi (String), hoặc có thể không khai báo tường minh.
Để khai báo ta sử dụng từ khoá “enum”

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

enum Rank: Int {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten

case Jack, Queen, King
func simpleDescription() -> String {
switch self {
case .Ace:
return "ace"
case .Jack:
return "jack"
case .Queen:
return "queen"
case .King:
return "king"
default:
return String(self.toRaw())
}
}
}
let ace = Rank.Ace
let aceRawValue = ace.toRaw()

Ở ví du jtrên thì kiểu giá trị là Int. Vì vậy aceRawValue sẽ có giá trị là 1.
Hãy chú ý là bạn sử dụng hàm toRaw (hoặc rawValue) và fromRaw để convert giữa giá trị
enum và giá trị thực của nó (ở đây là Int).
Cùng xem đoạn code sau:

11


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<ItemType>(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<T> {
case None
case Some(T)
}
var possibleInteger: OptionalValue<Int> = .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


1
2
3

4

enum BarCode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}

Kiểu enum phía trên khai báo 2 thành viên tương ứng với bar code 1D và QR code (2D).
Thành viên thứ nhất chính là giá trị liên hợp bao gồm 4 số nguyên, trong khi đó thành viên thứ
2 cũng chính là giá trị liên hợp tuy nhiên lại chỉ bao gồm duy nhất 1 chuỗi ký tự.
Để có thể tạo ra một bar code mới, chúng ta sử dụng cú pháp sau:

1 var barcode = BarCode.UPCA(1, 59000, 10000, 8)
sau đó có thể gán:

1 barcode = BarCode.QRCode(“This is a URL”)
Khi sử dụng trong câu lệnh Switch, để dùng những giá trị liên hợp thì ta cần phải khai báo
hằng hay biến tương ứng:

1
2
3
4
5
6

switch barcode {
case BarCode.UPCA(let systemNum, let manufacturerNum, let productNum, let checkNum):
println(“Manufacture number is \(manufacturerNum)”)
case BarCode.QRCode(let codedStr):

println(codedStr)
}

Nếu như khai báo mọi giá trị liên hợp cùng là hằng hay biến, chúng ta có thể xài cú pháp rút
gọn như sau:

18


1
2
3
4
5
6

switch barcode {
case let BarCode.UPCA(systemNum, manufacturerNum, productNum, checkNum):
println(“Manufacture number is \(manufacturerNum)”)
case var BarCode.QRCode(codedStr):
println(codedStr)
}

4. Giá trị đơn trong kiểu enum
Khi khai báo theo kiểu enum có thể chỉ định giá trị default cho mọi thành viên (member) của
nó. Giá trị này được chỉ định cho member là những giá trị đơn (raw values). Giá trị đơn cũng
có thể là String, Int, Float, Character… Chẳng hạn:

1
2

3
4
5

enum ASCIIControlCharacter: Character {
case Tab = “\t”
case LineFeed = “\n”
case CarriageReturn = “\r”
}

Nếu như kiểu enum gồm những thành viên có kiểu Int thì những thành viên cách nhau một đơn
vị (hoàn toàn giống với kiểu enum truyền thống):

1 enum Planet: Int {
2 case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
3}

Với khai báo trên, Planet.Venus sẽ có giá trị là 2.
Để truy cập giá trị đơn, chúng ta sẽ sử dụng cú pháp sau:

1 let earthsOrder = Planet.Earth.rawValue
Để khởi tạo 1 biến hay hằng enum mới, chúng ta dùng hàm tạo mặc định với giá trị đơn:

19


1 let possiblePlanet = Planet(rawValue: 7)
Tuy nhiên chúng ta cũng cần lưu ý rằng kiểu trả về của hàm tạo này là optional vì dải giá trị
của kiểu enum không nhất thiết chứa tham số đầu vào của hàm này, do vậy cần lưu ý khi sử
dụng để tránh crash chương trình.

5. Khai báo hàm trong kiểu enum
Ở đây mình chỉ nhắc lại về việc khai báo hàm trong kiểu enum. Trong enum, chúng ta có thể
khai báo hàm, và hàm này cũng có thể được gọi từ những member của kiểu enum đó. Chẳng
hạn:

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

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()

6. Tổng kết.
Qua bài viết ngày hôm nay, chúng ta đã học được cách khai báo và sử dụng kiểu enum trong
lập trình Swift. So với kiểu các enum truyền thống thì enum trong Swift đã tiến hoá hơn và trở
nên mềm dẻo, hữu dụng và mạnh mẽ hơn. Đáng chú ý nhất chính là việc nó hỗ trợ kiểu giá trị
liên hợp và khai báo hàm. Trong những bài sau, các tính năng của Swift sẽ lần lượt được thảo
luận chi tiết.

20


Bài 5. [HÀM ĐIỀU KHIỂN] – CẤU TRÚC LẶP TRONG LẬP TRÌNH SWIFT
Chào các bạn, hôm nay chúng ta sẽ tìm hiểu về cấu trúc lặp trong lập trình Swift, cách hoạt
động và cách dùng của những hàm điều khiển căn bản trong Swift.
Vòng lặp là 1 mã lệnh mà trong đó chương trình sẽ được thực hiện lặp đi lặp lại nhiều lần cho
đến khi nó thỏa mãn 1 điều kiện nào đó.
1. Vòng lặp for
Cú pháp:


1 for <khai báo>;<biểu thức 1>;<biểu thức 2> {
2

<câu lệnh>

3}



<khai báo>: khai báo và gán thêm giá trị cho biến đếm



<biểu thức 1>: điều kiện để có thể dừng vòng lặp



<biểu thức 2>: thay đổi giá trị biến đếm

Ví dụ:

1 for var i = 0; i < 5; ++i { //khai báo biến đếm i có giá trị 0; điều kiện để vòng lặp thực hiện là biến i bé hơn 5; sau mỗi lần thực hiện, biến
2

println("i = \(i)") //in giá trị i ra màn hình sau mỗi lần vòng lặp thực hiện

3 }

2. Vòng lặp for-in
Vòng lặp for-in thường được dùng khi biết trước về số lần lặp. Vòng lặp for-in sẽ sử dụng một

biến đại diện cho từng vị trí tương ứng tại thời điểm lặp để có thể lấy ra giá trị bên trong của
đối tượng (mảng, từ điển…).

21


Cú pháp

1 for <biến> in <đối tượng> {
2

<câu lệnh>

3}

1
2



<biến>: sẽ đại diện cho phần tử có những vị trí tương ứng tại một thời điểm lặp



<đối tượng>: nó có thể là một mảng, một từ điển hay một dãy số cho trước. Giả dụ:

//In các số lần lượt từ 1 đến 9 ra màn hình
for i in 1...9 {
println("Số i = \(i)")


3
4

}

5
6 //In các giá trị trong mảng ra màn hình
7 var mang = [10,11,12,13,14,15]
8 for i in mang {
9

println(i)

10 }
11
12
13
14

//In giá trị các key trong từ điển
var tudien = ["Tháng 1": 3500, "Tháng 2": 3150, "Tháng 3": 3220, "Tháng 4": 4000]
for (x,y) in tudien {

15

println("Thu nhập trong \(x) là \(y)")



Tuỳ từng trường hợp mà chúng ta có thể dùng for hay for-in, tuy nhiên hầu hết khi

chúng ta làm việc với Array/Dictionary thì đều sử dụng for-in.

22




Vòng lặp for/for-in thường được dùng khi ta đã biết trước được số lần lặp.



Ta có thể đặt vòng lặp for/for-in bên trong một vòng lặp for/for-in khác, được gọi là 2
vòng lặp for lồng nhau.

3. Vòng lặp While
Khi thoả mãn những điều kiện thì cậu lệnh trong vòng lặp while sẽ được thực hiện. Vòng lặp
while sẽ luôn kiểm tra các điều kiện ngay từ đầu, nếu như điều kiện sai thì câu lệnh trong vòng
lặp while sẽ không được thực hiện nữa.
Cú pháp:
while <điều kiện> {
<câu lệnh 1>
<câu lệnh 2>
}


<điều kiện>: biểu thức điều kiện để giúp câu lệnh thực hiện



<câu lệnh 1>: nhóm câu lệnh cần thực hiện




<câu lệnh 2>: câu lệnh để đổi lại giá trị so sánh của những biểu thức điều kiện. Sau mỗi
một lần lặp thì giá trị phải tiến gần tới điều kiện để có thể dừng vòng lặp, nếu không thì
vòng lặp sẽ lặp vô tận.

Ví dụ:

1 var n = 0
2 while n < 10 {
3

println("Giá trị n = \(n)")

4

n += 1

5}

4. Vòng lặp Do-While
Vòng lặp Do-While cũng tương tự như vòng lặp While tuy nhiên những câu lệnh sẽ được thực
hiện trước khi kiểm tra tới điều kiện. Tức là những câu lệnh sẽ được thực hiện ít nhất là 1 lần.

23


Cú pháp


1 do {
2

<câu lệnh 1>

3

<câu lệnh 2>

4 } while <điều kiện>



<câu lệnh 1>: là nhóm câu lệnh ta cần thực hiện



<câu lệnh 2>: sử dụng để thay đổi giá trị so sánh giữa các biểu thức điều kiện. Nếu như
giá trị so sánh của biểu thức điều kiện không tiến gần tới điều kiện dừng thì vòng lặp sẽ
trở thành vòng lặp vô tận.



<điều kiện>: biểu thức điều kiện để câu lệnh có thể được thực hiện.



Vòng lặp Do-While được dùng khi ta chưa biết được trước số lần lặp

1 var n = 0

2 do {
3

println("Giá trị n = \(n)")

4

n = n*2

5 } while n < 100

*** Chú ý: Ta không nên dùng quá 4 vòng lặp For lồng vào nhau, mà chúng ta hãy tìm cách
thay thế nó bằng vòng lặp While/Do-While

24


Bài 6. [HÀM ĐIỀU KHIỂN] – CẤU TRÚC RẼ NHÁNH TRONG LẬP TRÌNH SWIFT
Ở bài hôm trước trong series Hàm điều khiển, mình đã đề cập tới cấu trúc lặp trong lập trình
Swift và hôm nay mình sẽ tiếp tục cùng các bạn tìm hiểu về một cấu trúc khác – Cấu trúc rẽ
nhánh.
Cấu trúc rẽ nhánh là loại cấu trúc cho phép người dùng thực hiện một câu lệnh hay một nhóm
câu lệnh dựa vào những điều kiện đã xác định và cho trước.
1. Hàm điều kiện If và If-Else
Hàm If


Cú pháp:

1 if <điều kiện> { <câu lệnh> }



Khi <điều kiện> đúng thì <câu lệnh sẽ được thực hiện> và ngược lại, nếu điều kiện sai
thì hàm if sẽ không thực hiện bất cứ điều gì cả.

Hàm If-Else


Cú pháp:

1 if <điều kiện> { <câu lệnh a> } else { <câu lệnh b> }


Khi <điều kiện> đúng thì <câu lệnh a> sẽ được thực hiện còn nếu như <điều kiện>
không đúng thì <câu lệnh b> sẽ được thực hiện.



Ta có thể sử dụng nhiều hàm if lồng vào nhau.

Ví dụ:

25


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×