Contents
Chào bạn đến với thế giới của ngôn ngữ lập trình Swift,
Lưu ý
: bài viết này mang tính chất cưỡi ngựa xem hoa là chủ yếu. Nếu bạn muốn tìm hiểu hay học chi tiết hơn thì có có thể ghé trang “The Basic – Swift” của Apple.
Chuẩn bị
Đối tượng hướng tới:
- Chọn ngôn ngữ Swift để học thêm.
- Học nhanh Swift để qua học iOS và tiết kiệm thời gian.
- Muốn xem thử Swift có gì không.
- … học cho vui
Công cụ và môi trường:
- MacOS 10.14.4 (hoặc mới hơn)
- Xcode 11 (hoặc mới hơn)
- Swift 5 (hoặc mới hơn)
1. Hello world
- Mọi thứ sẽ bắt đầu bằng Hello world
- Nó mang 2 ý nghĩa
- Kiểm tra xem IDE (Xcode) và Swift của bạn OK chưa?
- Build được Swift không?
print("Hello, world!")
2. Biến & kiểu dữ liệu cơ bản
- Biến số khai báo với từ khoá là
var
- Có thể thay đổi giá trị
- Hằng số khai báo với từ khoá là
let
- Không thể thay đổi giá trị
- Cú pháp:
var/let <variable_name> : <type> = <value>
(hoặc không cần chỉ rõ kiểu dữ liệu cho biến)
var/let <variable_name> = <value>
- Ví dụ:
var myVariable = 100 myVariable = 50 let myConstant = 99
Tất cả các biến/hằng của Swift thì phải được gán giá trị ngay lúc khai báo.
- Giá trị mặc định cho biến/hằng
- Khi không xét kiểu dữ liệu cho biến/hằng thì Swift sẽ tự động nội suy kiểu dữ liệu từ
kiểu
của giá trị đượcgán
cho biến/hằng
- Khi không xét kiểu dữ liệu cho biến/hằng thì Swift sẽ tự động nội suy kiểu dữ liệu từ
var a = 10 //Int var b = 1.1 //Double var str = "hello" //String
- Các giá trị không tự động ép kiểu (casting) mà bạn phải chịu khó ép kiểu để được dữ liệu như mong muốn.
let str = "apples" let number = 999 let countLabel = String(number) + str
(hoặc)
let a = 5.1 let b: Float = 10.7 let c: Float = Float(a) + b
- In giá trị vào 1 chuỗi string
- Dùng toán tử
\
- Dùng toán tử
let apples = 3 let oranges = 5 let appleSummary = "I have \(apples) apples." let fruitSummary = "I have \(apples + oranges) pieces of fruit."
- Sử dụng dấu
"""
cho:- Nhiều dòng đối với string
let quotation = """ I said "I have \(apples) apples." And then I said "I have \(apples + oranges) pieces of fruit." """
3. Collection Type
3.1. Array
- Array là tập hợp các phần tử có cùng kiểu dữ liệu.
- Sử dụng toán tử
[]
để khai báo - Swift sẽ tự động nhận diện được kiểu dữ liệu của array cho biến
- Lưu ý: thời gian build sẽ rất lâu nếu không chỉ rõ kiểu dữ liệu cho array
var numbers = [1, 2, 3, 4, 5] var names: [String] = ["Nick", "Join", "Tom", "Mary"] print(numbers[2]) print(names[3])
- Thêm phần tử
- 1 phần tử :
append()
- nhiều phần tử:
append(contensOf:)
- 1 phần tử :
numbers.append(1) names.append(contentsOf: ["Alex", "Lee", "Andrew"]) print(numbers.last) print(names.last)
- Khởi tạo & gán
Ví dụ
var arr1 = [1, 2, 3] // tạo arr1 và gán mãng Int var arr2 = [] // arr2 với mảng Any var arr3: [Int] = [Int]() //Khởi tạo arr3 với kiểu mãng Int var arr4: [Int] = [] //tạo arr4 và gán mãng rỗng
3.2. Dictionary
- Dictionary là kiểu dữ liệu từ điển.
- Có
key
sẽ cóvalue
tương ứng - Không tồn tại 2 key giống nhau
- Có
- Tương tự như JSON
- Khai báo thông qua toán tử
[:]
- Cách khai báo và sử dụng tương tự như array
var dic = ["tree" : "cây", "love" : "tình yêu", "hate" : "ghét"] print(dic["love"]) dic["cat"] = "mèo" dic["dog"] = "chó" print(dic["cat"]) var dic2: [String: String] = [:] var dic3 = [String: String]()
3.3. Set
Set
là tập hợp các phần tử có cùng kiểu dữ liệu mà các giá trị tồn tại duy nhất.- Dễ hiểu là 1 Set các số Int thì không có 2 phần tử mang giá trị là 1.
let newString = "Hello Swift AAAA" let array = Array(newString) //["H", "e", "l", "l", "o", " ", "S", "w", "i", "f", "t", " ", "A", "A", "A", "A"] let set = Set(array) print(set) //[" ", "e", "l", "o", "S", "H", "t", "f", "w", "A", "i"]
4. Control Flow
4.1. Lệnh điều kiện
- If
var temperatureInFahrenheit = 30 if temperatureInFahrenheit <= 32 { print("It's very cold. Consider wearing a scarf.") } // Prints "It's very cold. Consider wearing a scarf."
- If else
temperatureInFahrenheit = 40 if temperatureInFahrenheit <= 32 { print("It's very cold. Consider wearing a scarf.") } else { print("It's not that cold. Wear a t-shirt.") } // Prints "It's not that cold. Wear a t-shirt."
- If else if
temperatureInFahrenheit = 90 if temperatureInFahrenheit <= 32 { print("It's very cold. Consider wearing a scarf.") } else if temperatureInFahrenheit >= 86 { print("It's really warm. Don't forget to wear sunscreen.") } else { print("It's not that cold. Wear a t-shirt.") } // Prints "It's really warm. Don't forget to wear sunscreen."
- If let
- Dùng để kiểm tra các giá trị bằng
nil
- Hay đảm bảo giá trị của biến tồn tại
- Dùng để kiểm tra các giá trị bằng
var myName: String? if let myName = myName { print("My name is \(myName)") } else { print("Sorry") }
- Guard let
- Hay còn gọi là
if ngược
- Sẽ thực thi khi điều kiện bị sai
- Dùng làm bảo vệ các biến khi nhập xuất và đảm bảo đoạn code dưới chạy được
- Yêu cầu phải có
return
để kết thúc function
- Hay còn gọi là
func sayName(name: String?) { guard let name = name else { print("Sorry") return } print("My name is \(name)") } sayName(name: myName)
4.2. Lệnh rẽ nhánh
- switch case
- switch được nhiều kiểu dữ liệu
- Int, Float, Array … object
- switch được nhiều kiểu dữ liệu
let anotherCharacter: Character = "a" switch anotherCharacter { case "a": // Invalid, the case has an empty body case "A": print("The letter A") default: print("Not the letter A") } // This will report a compile-time error.
-
- Kết hợp nhiều điều kiện
- từ khoá
where
- từ khoá
- Kết hợp nhiều điều kiện
let temp = 9 switch temp { case 0: print("Number 0") case 1: print("Number 1") case 2: print("Number 2") case 3: print("Number 3") case 4: print("Number 4") case 5: print("Number 5") case 6...10: print("6 <= && >= 10") default: print("unknown") }
4.3. Lệnh lặp
- For
- Từ khoá
for
in
- Lặp từ số tới đối tượng
- Duyệt theo range hoặc array
- Từ khoá
for count in 0...100 { print(count) } for name in names { print("Hello, \(name)") } var dic: [String: String] = ["tree" : "cây", "love" : "tình yêu", "hate" : "ghét"] for item in dic { print(item.key + " is '" + item.value + "'" ) }
-
- For phức tạp chút
let interestingNumbers = [ "Prime": [2, 3, 5, 7, 11, 13], "Fibonacci": [1, 1, 2, 3, 5, 8], "Square": [1, 4, 9, 16, 25], ] var largest = 0 for (kind, numbers) in interestingNumbers { for number in numbers { if number > largest { largest = number } } } print(largest) // Prints "25"
- while
- Kiểm tra trước & làm sau
var i = 0 while i < 10 { print("i = \(i)") i += 1 }
- repeat-while
- làm trước & kiểm tra sau
var j = 0 repeat { print("j = \(j)") j += 1 } while j < 10
5. Function
- Khai báo function
- Từ khoá :
func
- Từ khoá :
func greet(person: String, day: String) -> String { return "Hello \(person), today is \(day)." } greet(person: "Bob", day: "Tuesday")
- Tham số khi khai báo sẽ có 2 tên:
- argument label
- parameter name
- Không muốn sử dụng argument label thì có thể dùng
_
để thay thế. Sẽ trở thành giống như các ngôn ngữ khác.
func greet(_ person: String, on day: String) -> String { return "Hello \(person), today is \(day)." } greet("John", on: "Wednesday")
- Function trả về nhiều giá trị
- Return về kiểu là
Tuple
- Return về kiểu là
let numbers = [1, 3, 10, -11, 98, 45] func getMinMax(numbers: [Int]) -> (Int, Int) { return (numbers.min()!, numbers.max()!) } let result = getMinMax(numbers: numbers) print("Min = \(result.0) & Max = \(result.1)")
6. Closure
- Đã có 1 bài viết chi tiết, đọc thêm ở đây : Closure trong 10 phút
- Ví dụ cơ bản nhất
let myClosure = {(name: String) -> Void in print("Hello, \(name)") } myClosure("Nick")
7. Class & Object
7.1. Class
- Khai báo class
- Từ khoá :
class
- Từ khoá :
- Các thuộc tính (property)
- khai báo như biến/hằng
- Các phương thức (method)
- khai báo như function
- Hàm khởi tạo
- Từ khoá
init
- Nếu tất cả các thuộc tính được gán giá trị ban đầu hay là kiểu optional thì không cần hàm init
- Từ khoá
Ví dụ:
class NamedShape { var numberOfSides: Int = 0 var name: String init(name: String) { self.name = name } func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." } }
- Thừa kế
- Dùng toán tử
:
- Ghi đè phương thức lớp cha, dùng từ khoá
override
- Sử dụng từ khoá
final
trước từ khoá class thì sẽ không được thừa kế tiếp
- Dùng toán tử
class Square: NamedShape { var sideLength: Double init(sideLength: Double, name: String) { self.sideLength = sideLength super.init(name: name) numberOfSides = 4 } func area() -> Double { return sideLength * sideLength } override func simpleDescription() -> String { return "A square with sides of length \(sideLength)." } }
7.2. Object
- Object là thể hiện của class
- Sử dụng toán tử
( )
để tạo 1 object
Ví dụ:
class Shape { var numberOfSides = 0 func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." } } var shape = Shape() shape.numberOfSides = 7 var shapeDescription = shape.simpleDescription()
8. Enumerations and Structures
8.1. Enumerations
- Enum là bảng liệt kê các trường hợp
- Từ khoá
enum
- Dùng để tăng tính tường minh cho code
- Swift thì enum khá là bá:
- có thể kế thừa từ nhiều loại kiểu dữ liệu
- có thể có function như class
- khởi tạo thì dùng rawValue hoặc khởi tạo bằng
case
của enum
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()
- Có thể thêm nhiều dữ liệu cho các
case
(tương tựTuple
)- Sử dụng phải
switch case
- Sử dụng phải
enum ServerResponse { case result(String, String) case failure(String) } let success = ServerResponse.result("6:00 am", "8:09 pm") let failure = ServerResponse.failure("Out of cheese.") switch success { case let .result(sunrise, sunset): print("Sunrise is at \(sunrise) and sunset is at \(sunset).") case let .failure(message): print("Failure... \(message)") } // Prints "Sunrise is at 6:00 am and sunset is at 8:09 pm."
8.2. Structures
- Struct kiểu dữ liệu kết hợp từ nhiều kiểu dữ liệu khác
- Tương tự như class
- Khác class một vài điểm cơ bản sau:
- Không kế thừa được
- Theo kiểu tham trị
- Không cần định nghĩa hàm
init
- Với swift 5
- Nếu các thuộc tính được gán trị ban đầu thì có thể lượt bỏ nó ở hàm
init
của struct
- Nếu các thuộc tính được gán trị ban đầu thì có thể lượt bỏ nó ở hàm
struct Point { var x: Float = 0.0 var y: Float = 0.0 func showInfo() { print("Point (\(x), \(y))") } } let point1 = Point() point1.showInfo() let point2 = Point(x: 10.0, y: 25) point2.showInfo() var point3 = Point() point3.x = 77.5 point3.y = -85 point3.showInfo()
9. Protocol & Extension
9.1. Protocol
- Protocol là kiểu interface
- Khái báo các thuộc tính và phương thức
- Không định nghĩa chúng
- Dùng xem là 1 hình thức đa kế thừa trong swift
- Dùng được cho class, struct và enum
- Khai báo dùng từ khoá
protocol
protocol ExampleProtocol { var simpleDescription: String { get } mutating func adjust() }
- Khi implement thì phải định nghĩa lại hết các phương thức & thuộc tính đã được khai báo
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
9.2. Extension
- Khi muốn thêm function hay thuộc tính cho 1 class/struct/enum có sẵn mà không muốn tạo sub-class để kế thừa lại.
- Từ khoá
extension
extension Int: ExampleProtocol { var simpleDescription: String { return "The number \(self)" } mutating func adjust() { self += 42 } } print(7.simpleDescription) // Prints "The number 7"
10. Optional
- Cho phép 1 biến vắng mặt giá trị của nó. Tức là bằng
nil
- Các toán tử
- Khai báo sử dụng
?
- Khai báo sử dụng
- Sử dụng giá trị mặc định dùng
??
var name: String? = nil print(name) //nil print(name ?? "no name") //no name
- Implicitly Unwrapping: Khai báo với
!
dùng để dùng trực tiếp- Khi sử dụng thì không cần toán tử
!
hay?
- Khi sử dụng thì không cần toán tử
var name: String! = "Nick Lee" print(name ?? "no name")
- Force Unwrap : dùng để truy cập trực tiếp
- Chương trình có thể bị
crash
khi giá trị của biến bằngnil
- Trong dự án iOS thường sẽ bị cấm cái này hay trong swiftlint cũng cấm
- Chương trình có thể bị
name = "abc" print(name) print(name!)
- Optional binding : dùng để truy cập và sử dụng optional 1 cách an toàn hơn
if let name = name { print(name) } else { print("no name") }
11. Error handling
- Dùng để xử lý các
error
và các ngoại lệ - Đảm bảo chương trình không bị
crash
Tham khảo ví dụ sau
- Khai báo 1 enum error
enum PrinterError: Error { case outOfPaper case noToner case onFire }
- Khai báo 1 function
- Để nén 1 ngoại lệ thì sử dụng từ khoá
throws
- Để nén 1 ngoại lệ thì sử dụng từ khoá
func send(job: Int, toPrinter printerName: String) throws -> String { if printerName == "Never Has Toner" { throw PrinterError.noToner } return "Job sent" }
- Thực thi function
- Để bắt error thì cần
try ... catch
- Xử lý error thì trong phần
catch
- Để bắt error thì cần
do { let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng") print(printerResponse) } catch { print(error) } // Prints "Job sent" do { let printerResponse = try send(job: 1040, toPrinter: "Never Has Toner") print(printerResponse) } catch { print(error) } // Prints "noToner"
- Dùng
try?
để trả về 1 optional
let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler") let printerFailure = try? send(job: 1885, toPrinter: "Never Has Toner")
defer
để thực thi đoạn code sau khi xử lý xong các đoạn mã khác của function- Xét lại giá trị cho biến
- Dùng xử lý sau cùng khi có error
- …
var fridgeIsOpen = false let fridgeContent = ["milk", "eggs", "leftovers"] func fridgeContains(_ food: String) -> Bool { fridgeIsOpen = true defer { fridgeIsOpen = false } let result = fridgeContent.contains(food) return result } fridgeContains("banana") print(fridgeIsOpen) // Prints "false"
12. Generics
- Khai báo với 1 kiểu dữ liệu chung chung, mang tính chất đại diện là chủ yếu.
func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] { var result = [Item]() for _ in 0..<numberOfTimes { result.append(item) } return result } makeArray(repeating: "knock", numberOfTimes: 4)
- Sử dụng với enum
enum OptionalValue<Wrapped> { case none case some(Wrapped) } var possibleInteger: OptionalValue<Int> = .none possibleInteger = .some(100)
- Sử dụng với array
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Bool where T.Element: Equatable, T.Element == U.Element { for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { return true } } } return false } anyCommonElements([1, 2, 3], [3])
Tổng kết
- Học xong thì bạn có thể tự tin code Swift ở mức cơ bản.
- Cần tìm hiểu thêm về các đặc trưng riêng của ngôn ngữ lập trình Swift.
Related Posts:
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
2 comments
Leave a Reply Cancel reply
Fan page
Tags
Actor
Advanced Swift
api
AppDistribution
autolayout
basic ios tutorial
blog
bundle
ci/cd
closure
collectionview
combine
concurrency
crashlytics
darkmode
dart
dart basic
dart tour
Declarative
delegate
deploy
design pattern
fabric
fastlane
firebase
flavor
flutter
GCD
gestures
gradients
iOS
MVVM
optional
protocol
rxswift
safearea
Swift
Swift 5.5
SwiftData
SwiftUI
SwiftUI Notes
tableview
testing
TravisCI
unittest
Recent Posts
- Charles Proxy – Phần 1 : Giới thiệu, cài đặt và cấu hình
- Complete Concurrency với Swift 6
- 300 Bài code thiếu nhi bằng Python – Ebook
- Builder Pattern trong 10 phút
- Observer Pattern trong 10 phút
- Memento Pattern trong 10 phút
- Strategy Pattern trong 10 phút
- Automatic Reference Counting (ARC) trong 10 phút
- Autoresizing Masks trong 10 phút
- Regular Expression (Regex) trong Swift
You may also like:
Archives
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)
Have you ever considered about adding a little bit more than just your articles?
I mean, what you say is valuable and all. But think of if
you added some great photos or video clips to give your posts more, “pop”!
Your content is excellent but with images and video clips, this website could definitely be one of the most beneficial in its niche.
Fantastic blog!
I just want to say thank you for this great website. I found a solution here on fxstudio.dev for my issue.