# Functions

### การสร้างฟังก์ชัน

โดยทั่วไป ฟังก์ชันจะประกอบด้วย **ชื่อเรียก(name)**, **ค่าสำหรับการทำงาน (parameters)** และ**ค่าที่ส่งกลับ (return)** ซึ่งการนิยาม (defining) การทำงานของฟังก์ชันสามารถทำได้ ดังนี้

```swift
func functionName (parameters) -> ReturnType {
  // คำสั่งเพื่อระบุการทำงานของฟังก์ชัน
  
}
```

ตัวอย่างการสร้างฟังก์ชันอย่างง่ายเพื่อการหาผลรวมของตัวเลข 2 ตัว และการเรียกใช้งาน

```swift
func addNumber(firstNumber: Int, secondNumber: Int) -> Int {
    let result = firstNumber + secondNumber
    return result
}

var totResult = addNumber(firstNumber: 3, secondNumber: 15)
print(totResult) // 18
```

* `addNumber`  คือ ชื่อฟังก์ชัน (functionName) ซึ่งใช้กำกับเพื่อการเรียนใช้งานฟังก์ชัน
* `firstNumber: Int` และ `secondNumber: Int`  คือ พารามิเตอร์ (parameters) ซึ่งประกอบไปด้วยชื่อและประเภทของพารามิเตอร์ที่จะรับเข้ามาเพื่อใช้ในการทำงานตามคำสั่งภายในฟังก์ชัน
* `-> Int` คือ ประเภทของค่าที่จะส่งกลับหลังจากการทำงานตามคำสั่งเสร็จสิ้น โดยจะต้องสอดคล้องกับที่ระบุไว้ที่ return
* `addNumber(firstNumber: 3 , secondNumber: 15)` คือ การเรียกใช้ฟังก์ชัน (call) พร้อมกับส่งอาร์กิวเมนต์ (Argument) จำนวน 2 ค่า คือ 3 และ 5 ไปเพื่อเป็นพารามิเตอร์สำหรับใช้ในการประมวลผลของฟังก์ชัน และรับผลลัพธ์ที่ได้มาเก็บไว้ในตัวแปร ชื่อ totResult\
  \
  \* อาร์กิวเมนต์  คือ ข้อมูลที่ส่งให้กับพารามิเตอร์ของฟังก์ชัน

### ฟังก์ชันที่ไม่มีพารามิเตอร์และไม่มีการรีเทิร์นค่า

```swift
func displayPi() {
  print("3.1415926")
}

displayPi()  // 3.1415926
```

### ฟังก์ชันที่มีพารามิเตอร์แต่ไม่มีการรีเทิร์นค่า

```swift
func triple(value: Int) {
  let result = value * 3
  print("If you multiply \(value) by 3, you'll get \(result).")
}

triple(value: 10)  // If you multiply 10 by 3, you'll get 30.
```

### ฟังก์ชันที่มีพารามิเตอร์มากกว่า 2 ตัว แต่ไม่มีการรีเทิร์นค่า

```swift
func sayHello(to: String, and: String) {
   print("Hello! \(to) and \(and).")
}

sayHello(to: "Thiti", and: "Looknam")  // Hello! Thiti and Looknam.
```

### ฟังก์ชันที่มีการรีเทิร์นค่า

```swift
func multiply(firstNumber: Int, secondNumber: Int) -> Int {
   let result = firstNumber * secondNumber
   return result
}

var result = multiply(firstNumber: 3, secondNumber: 5)
print(result)  // 15
```

### การใช้พารามิเตอร์แบบ External และ Local name&#x20;

```swift
func sayHello(to person: String, and anotherPerson: String) {
   print("Hello! \(person) and \(anotherPerson).")
}

sayHello(to: "Thiti", and: "Looknam")  // Hello! Thiti and Looknam.
```

หากเราต้องการเรียกใช้ฟังก์ชัน โดยละเว้นการระบุชื่ออาร์กิวเมนต์ (Omiting label) สามารถทำได้ โดยใช้เครื่องหมาย `_` ระบุไว้แทนชื่อพารามิเตอร์ของฟังก์ชัน

```swift
func sayHello(_ person: String, _ anotherPerson: String) {
   print("Hello! \(person) and \(anotherPerson).")
}

sayHello("Thiti", "Looknam")  // Hello! Thiti and Looknam.
```

### การกำหนดค่าเริ่มต้นให้กับพารามิเตอร์

เราสามารถกำหนดค่าเริ่มต้น (default value) ให้กับพารามิเตอร์ได้ ซึ่งหากเราไม่มีการผ่านค่าไปยังฟังก์ชัน ฟังก์ชันก็จะใช้ค่าดังกล่าวแทนทันที

```swift
func power(number: Int, by: Int = 2) -> Int {
  var result = 1
  for _ in 1...by {
     result = result * number
  }
  return result
}

let firstResult = power(number: 5)  // 25
let secondResult = power(number: 3, by: 4)  // 81
```

### การกำหนดพารามิเตอร์แบบ Optional

หากมีพารามิเตอร์บางตัวที่ไม่ได้ถูกใช้ในการทำงานทุกครั้ง เราอาจกำหนดให้สามารถผ่านค่า nil มายังพารามิเตอร์ดังกล่าวได้ กล่าวคือ เราสามารถกำหนดให้พารามิเตอร์ดังกล่าวเป็นแบบ Optional โดยใช้เครื่องหมาย ? กำกับไว้หลังชนิดของข้อมูลที่จะรับเข้ามายังฟังก์ชัน

```swift
func rectArea(width: Double, height: Double?) -> String {
    if height != nil {
        return "สี่เหลี่ยนมีพื้นที่ทั้งหมด \(width * height!) ตารางเมตร"
    } else {
        return "สี่เหลี่ยนมีพื้นที่ทั้งหมด \(width * width) ตารางเมตร"
    }
}

var myArea = rectArea(width: 5.0, height: 3.0)
print(myArea)  // สี่เหลี่ยนมีพื้นที่ทั้งหมด 15.0 ตารางเมตร

myArea = rectArea(width: 5.0, height: nil)
print(myArea)  // สี่เหลี่ยนมีพื้นที่ทั้งหมด 25.0 ตารางเมตร
```

### Function Type

ในภาษา Swift เราสามารถนำฟังก์ชั่นมาใช้เป็นชนิดข้อมูลได้ โดยเราสามารถเขียนตัวแปรที่มีชนิดเป็นฟังก์ชัน (หรือเรียกว่า function type) ได้ในรูปแบบ ดังนี้

```swift
(parameter type, parameter type) -> return ReturnType
```

#### (1) การใช้ Function Type ในรูปแบบตัวแปร

```swift
func addTwoInt(_ firstInt: Int, _ secondInt: Int) -> Int {
    return firstInt + secondInt
}

func multiplyTwoInt(_ firstInt: Int, _ secondInt: Int) -> Int {
    return firstInt * secondInt
}

var myFunc: (Int, Int) -> Int
myFunc = addTwoInt
print(myFunc(7, 5))    // 12

myFunc = multiplyTwoInt
print(myFunc(7, 5))     // 35
```

#### (2) การใช้ Function Type ในแบบพารามิเตอร์

```swift
func multiplyTwoInt(_ firstInt: Int, _ secondInt: Int) -> Int {
    return firstInt * secondInt
}

func calculate(a: Int, b: Int, operation: (Int, Int) -> Int ) -> Int {
    return operation(a,b) 
}


let result = calculate(a: 10, b: 5, operation: multiplyTwoInt)
print(result)
```

## แหล่งข้อมูลอ้างอิง

* [The Swift Programming Language (Swift 5.0)](https://books.apple.com/th/book/the-swift-programming-language-swift-5-0/id881256329), Apple Inc., 2018. Available on: Apple Book Store.
* [App Development with Swift](https://books.apple.com/th/book/app-development-with-swift/id1465002990), Apple Inc., 2017. Available on: Apple Book Store.

{% hint style="info" %}
**รายละเอียดเพื่อการอ้างอิง**\
**ผู้เขียน** ธิติ ธีระเธียร  \
**วันที่เผยแพร่**  วันที่ 17 มิถุนายน 2562.\
**เข้าถึงได้จาก** <https://ajthiti.gitbook.io/swift/functions>\
**เงื่อนใขในการใช้งาน**\
This work is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License](http://creativecommons.org/licenses/by-nc-nd/4.0/).
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ajthiti.gitbook.io/swift/functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
