Hàm trong swift – Swift Functions (Bài 6)

Hàm trong swift là một tập hợp các câu lệnh được tổ chức với nhau để thực hiện một công việc cụ thể. Giống như các ngôn ngữ lập trình khác, hàm trong swift có 2 thành phần là khai báo hàm (Function Declaration) và định nghĩa hàm (Function Definition).

Khai báo hàm là thông báo với trình biên dịch về tên hàm, kiểu trả về và tham số. Định nghĩa hàm là phần thân hàm (xử lý của hàm)

Cú pháp khai báo hàm trong swift

func funcname(Parameters list) -> Datatype {
   Statement1
   Statement2
    ---
   Statement N
   return value
}

Ví dụ khai báo và định nghĩa hàm có tên getStudentName()

func getStudentName(name: String) -> String {
   return name
}

Gọi hàm trong swift

Cũng giống như các ngôn ngữ lập trình khác, gọi hàm trong swift phải thông qua tên hàm và phải đúng với cấu trúc như phần khai báo hàm (kiểu trả về và tham số). Sau đây là ví dụ về cách khai báo, định nghĩa và gọi hàm trong swift. Hàm có tên getStudentName

import UIKit

func getStudentName() -> String {
   return "Gia Su Tin Hoc"
}

print(getStudentName());

Khi chạy chương trình trên sử dụng playground, chúng ta sẽ nhận được kết quả sau

Gia Su Tin Hoc

Tham số và kiểu trả về của hàm trong swift

Swift cho phép khai báo hàm với nhiều tham số và nhiều giá trị trả về một cách linh hoạt. Tương tự như cách khai báo hàm của ngôn ngữ lập trình C và Objective – C, Swift cho phép khai báo hàm với nhiều hình thức.

Hàm với một tham số

Ví dụ khai báo và định nghĩa hàm printWelcome có một tham số name kiểu chuỗi

import UIKit

func printWelcome(name: String) -> String {
    let welcome = "Welcome " + name + "!"
    return welcome
}

print(printWelcome("Gia Su Tin Hoc"))

Khi chạy chương trình trên sử dụng playground, chúng ta sẽ nhận được kết quả sau

Welcome Gia Su Tin Hoc!

Hàm với các tham số (Functions with Parameters)

Hàm có thể có nhiều tham số đầu vào, chúng được viết bên trong cặp dấu ngoặc đơn và được phân cách bởi dấu phẩy.

Ví dụ khai báo và định nghĩa hàm add() có 2 tham số n1, n2 kiểu số nguyên (integer) và trả về kiểu integer. Khi bạn gọi hàm có nhiều hơn một tham số, những tham số thứ 2 trở đi phải được gán nhãn theo tên tham số tương ứng.

import UIKit

func add(n1: Int, n2: Int) -> Int {
   return n1 + n2
}

// Gọi hàm
print(add(2, n2: 15))
print(add(3, n2: 20))
print(add(4, n2: 25))

Khi chạy chương trình trên sử dụng playground, chúng ta sẽ nhận được kết quả sau

17
23
39

Hàm không có tham số (Functions without Parameters)

Cú pháp

func functionName() -> datatype {
   return datatype
}

Ví dụ khai báo và định hàm hàm getName() không có tham số và trả về chuỗi

func getName() -> String {
   return "Ro"
}
// Gọi hàm
print(getName())

Hàm có nhiều giá trị trả về (Functions with return values)

Swift cho phép lập trình viên khai báo hàm có nhiều giá trị trả về như giá trị kiểu chuỗi (string), giá trị kiểu số nguyên (integer), giá trị kiểu số thực (float), …

Ví dụ để tìm số có giá trị lớn nhất và số có giá trị nhỏ nhất trong một mảng kiểu số nguyên (integer). Hàm nhận tham số là mảng và trả về giá trị lớn nhất và nhỏ nhất.

func findLS(arr: [Int]) -> (largeElement: Int, smallElement: Int) {
   var l = arr[0]
   var s = arr[0]
   for i in arr[1..<arr.count] {
      if i < s {
         s = i
      } else if i > l {
         l = i
      }
   }
   return (l, s)
}

let num = findLS([40,12,-5,78,98])
print("Số lớn nhất là: \(num.largeElement) và số nhỏ nhất là: \(num.smallElement)")

Khi chạy chương trình trên sử dụng playground, chúng ta sẽ nhận được kết quả sau

Số lớn nhất là: 98 và số nhỏ nhất là: -5

Hàm không trả về giá trị (Functions without return values)

Một số hàm có nhận tham số nhưng không trả về giá trị. Ví dụ sau đây khai báo hàm với 2 tham số n và m được truyền vào hàm calc(). Hàm này có nhiệm vụ tính tổng và hiệu và in kết quả.

// Khai báo và định nghĩa hàm
func calc(n: Int, m: Int) {
   let a = n + m
   let b = n - m
   print("Tổng là \(a), hiệu là \(b)")
}

// Gọi hàm
calc(10, m: 20)
calc(30, m: 40)
calc(60, m: 50)

Khi chạy chương trình trên sử dụng playground, chúng ta sẽ nhận được kết quả sau

Tổng là 30, hiệu là -10
Tổng là 70, hiệu là -10
Tổng là 110, hiệu là 10

Hàm với kiểu trả về tuỳ chọn (Functions with optional return types)

Khi chúng ta khai báo hàm với trả về giá trị kiểu số nguyên (integer) nhưng điều gì sẽ xảy ra khi hàm trả về giá trị kiểu chuỗi (string) hoặc giá trị nil. Trong trường hợp này, trình biên dịch sẽ trả về giá trị lỗi (error value).

Optional functions sẽ chấp nhận hàm trả về với 2 hình thức là ‘value’ và ‘nil’. Ví dụ sau đây khai báo và định nghĩa hàm findMinMax nhận vào mảng số nguyên và trả về 2 giá trị min và max trong mảng. Nếu mảng là rỗng (emplty), hàm sẽ trả về giá trị nil.

import UIKit

// Khai báo và định nghĩa hàm
func findMinMax(arr: [Int]) -> (min: Int, max: Int)? {
    if arr.isEmpty { 
        return nil 
    }

    var currentMin = arr[0]
    var currentMax = arr[0]

    for value in arr[1..<arr.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }

    return (currentMin, currentMax)
}

// Gọi hàm
var ret = findMinMax([80, -16, 20, 109, 30, 171])
if ret != nil {
 print("Số nhỏ nhất là \(ret!.min) và số lớn nhất là \(ret!.max)")
}

var myArr = [Int]()
var ret2 = findMinMax(myArr)
if ret2 != nil {
 print("Số nhỏ nhất là \(ret!.min) và số lớn nhất là \(ret!.max)")
} else {
 print("null")
}

Khi chạy chương trình trên sử dụng playground, chúng ta sẽ nhận được kết quả sau

Số nhỏ nhất là -16 và số lớn nhất là 171
null

Hàm trong swift – Giá trị mặc định cho tham số (Default Parameter Values)

Bạn có thể định nghĩa giá trị mặc định cho bất kỳ tham số nào trong hàm bằng cách gán một giá trị sau kiểu dữ liệu. Nếu một giá trị mặc định được định nghĩa, bạn có thể bỏ qua tham số khi gọi hàm.

// Khai báo và định nghĩa hàm
func myFunction(pwd: Int = 12) -> Int {
    return pwd + 6
}

// Gọi hàm
print(myFunction(6)) // 12
print(myFunction())  // 18

Hàm trong swift – Variadic Parameters

Một variadic parameter chấp nhận không hoặc nhiều giá trị cho tham số. Bạn có thể sử dụng variadic parameter để chỉ định rằng tham số có thể được truyền với số lượng thay đổi khi gọi hàm. Khai báo variadic parameter bằng các chèn (…) sau kiểu dữ liệu

Ví dụ dưới đây tính toán trung bình cộng cho một danh sách các số có chiều dài bất kỳ

// Khai báo và định nghĩa hàm
func avg(numbers: Double...) -> Double {
    var total: Double = 0
    for n in numbers {
        total += n
    }
    return total / Double(numbers.count)
}

// Gọi hàm
print(avg(1, 2, 3, 4, 5)) // 3.0
print(avg(3, 8.25, 18.75)) // 10.0

Hàm trong swift – Khai báo tham số In-Out (In-Out Parameters)

Tham số của hàm mặc định là hằng số. Nếu bạn cố gắng thay đổi giá trị của nó bên trong hàm thì trình biên dịch sẽ thông báo lỗi. Do đó, nếu bạn muốn thay đổi giá trị của các tham số và bạn muốn những thay đổi đó tồn tại sau khi lời gọi hàm kết thúc, định nghĩa hàm với từ khoá inout.

Ví dụ hàm hoán vị 2 số nguyên

func swap(inout a: Int, inout b: Int) {
    let t = a
    a = b
    b = t
}

Gọi hàm

var a = 10
var b = 17
// Gọi hàm
swap(&a, &b)
// Sau khi chạy him a là 17 và b là 10"
print("a = \(a), b = \(b)")

Hàm trong swift – Hàm lồng nhau (Nested functions)

Swift cho phép bạn định nghĩa một hàm bên trong một hàm khác được gọi là nested functions. Hàm được khai báo bên trong một hàm chỉ tồn tại trong hàm được định nghĩa.

func chooseStep(previous: Bool) -> (Int) -> Int {
    func moveNext(n: Int) -> Int { 
      return n + 1 
    }

    func movePrevious(n: Int) -> Int { 
      return n - 1 
    }

    return previous ? movePrevious : moveNext
}

var n = 3
let f = chooseStep(n > 0)
while n != 0 {
    print("\(n)")
    n = f(n)
}

Kết quả hiển thị trong playground

3
2
1

Hàm trong swift – Tổng kết

  • Khai báo và định nghĩa hàm
  • Hàm không có tham số
  • Hàm có một hoặc nhiều tham số
  • Hàm với tham số inout
  • Hàm trả về giá trị
  • Hàm lồng nhau

Hàm trong swift – Bài tập thực hành

Bài thực hành số 1: Viết chương trình nhập vào số nguyên n. Cho biết n là số nguyên dương hay không? n có phải là số chẵn hay không? n có chia hết cho 5 hay không? và n có phải là số nguyên tố hay không?

Bài thực hành số 2: Tìm số n bé nhất sao cho n! lớn hơn một số m cho trước.

Bài thực hành số 3: Đổi số nguyên dương n từ hệ thập phân ra hệ nhị phân.

Bài thực hành số 4: Nhập một số nguyên x. Tìm vị trí xuất hiện của x trong mảng nếu có, ngược lại thì thông báo không có số này.

Bài thực hành số 5: Hiệu của tổng các số ở vị trí chẵn và tổng các số ở vị trí lẻ trong mảng.

Bài thực hành số 6: Vị trí đầu tiên của số lẻ, vị trí cuối cùng của số chẵn trong mảng.

Xem giáo trình môn lập trình Swift