Basic Swift Trong 10 Phút (hoặc Hơn) - Fx Studio

Written by chuotfx on October 9, 2019Basic Swift trong 10 phútiOS & Swift

Contents

Toggle
  • Chuẩn bị
  • 1. Hello world
  • 2. Biến & kiểu dữ liệu cơ bản
  • 3. Collection Type
    • 3.1. Array
    • 3.2. Dictionary
    • 3.3. Set
  • 4. Control Flow
    • 4.1. Lệnh điều kiện
    • 4.2. Lệnh rẽ nhánh
    • 4.3. Lệnh lặp
  • 5. Function
  • 6. Closure
  • 7. Class & Object
    • 7.1. Class
    • 7.2. Object
  • 8. Enumerations and Structures
    • 8.1. Enumerations
    • 8.2. Structures
  • 9. Protocol & Extension
    • 9.1. Protocol
    • 9.2. Extension
  • 10. Optional
  • 11. Error handling
    • Tham khảo ví dụ sau
  • 12. Generics
  • Tổng kết

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ị được gán cho biến/hằng
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ử \
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:)
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
  • 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
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
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
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
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
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
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
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
  • 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

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
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
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
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 ?
  • 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 ?
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ằng nil
    • Trong dự án iOS thường sẽ bị cấm cái này hay trong swiftlint cũng cấm
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
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
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.
FacebookTweetPinYummlyLinkedInPrintEmailShares17

Related Posts:

  • cropped-feature_bg_3.jpg
    Autoresizing Masks trong 10 phút
  • feature_bg_swift_04
    Dependency Injection trong 10 phút
  • feature_bg_swift_10
    Swift Optional trong 10 phút
  • feature_bg_swiftui_4
    Observation Framework trong 10 phút
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

  • 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.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Comment *

Name *

Email *

Website

Save my name, email, and website in this browser for the next time I comment.

Từ khóa » ép Kiểu Trong Swift