🚀 Golang 函數:從入門到精通

更新於 發佈於 閱讀時間約 20 分鐘


raw-image

👨‍💻簡介

在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。本文要帶你一探究竟,深入了解 Golang 裡的函數有哪些不同的方面。從基本的概念開始,一路講到更高級的技巧,我們會告訴你怎麼樣用函數來處理各種不同的情況。

函數基本概念

函數在 Golang 中是一組程式語句的組合,用於執行特定的任務。它們接受輸入(參數)並返回輸出(返回值),從高層次來看,就像是黑盒子,你提供輸入,它交付結果。在每個 Golang 程式中,最常見的函數是 main(),它是程式的入口點。

函數名稱與命名規則

在 Golang 中,函數名稱的命名規則如下:

  • 名稱必須以字母開始,後面可以是任意數量的字母和數字。
  • 函數名稱不能以數字開頭。
  • 函數名稱不能包含空格。
  • 如果函數名稱以大寫字母開頭,則可以被其他套件引用。如果以小寫字母開頭,則不能被其他套件引用,但可以在同一套件內部使用。
  • 如果名稱由多個單詞組成,從第二個單詞開始的每個單詞首字母應大寫,例如 empNameEmpAddress 等。
  • 函數名稱區分大小寫,即 carCar 和 CAR 是三個不同的變數。

創建函數

在 Golang 中,創建函數的基本語法如下:

func 函數名稱(參數1 型別1, 參數2 型別2, ...) 返回型別 {
// 函數程式碼
return 返回值
}

首先,用 func 關鍵字開始函數宣告,然後是你想要給函數的名稱,一對括號 (),然後是一個包含函數程式碼的區塊。

以下是一個簡單的範例,它不接受任何參數,也不返回任何值。

package main

import "fmt"
// SimpleFunction 印出一個訊息
func SimpleFunction() {
fmt.Println("Hello World")
}
func main() {
SimpleFunction() // 呼叫 SimpleFunction 函數
}

接受參數的函數

如果要將資訊傳遞給函數,可以通過參數來實現。參數就像變數一樣。

在函數名稱後面的括號內指定參數。你可以添加任意多的參數,只需用逗號分隔。

以下是一個帶有兩個整數參數的範例。當呼叫 add() 函數時,我們傳遞了兩個整數值(例如 20 和 30)。

package main

import "fmt"
// 接受參數的函數
func add(x int, y int) {
total := 0
total = x + y
fmt.Println(total)
}
func main() {
// 傳遞參數
add(20, 30)
}

在 Golang 中,函數名稱首字母大寫的話,可以被其他套件引用(export)使用。如果函數名稱首字母小寫,則不能被其他套件引用,但在同一套件內部可以呼叫該函數。

返回值的函數

如果要在函數中返回值,可以在函數中指定返回類型。以下是一個計算兩個整數之和並返回結果的範例:

package main

import "fmt"
// 函數返回 int 型別的值
func add(x int, y int) int {
total := x + y
return total
}
func main() {
// 接收返回值並存入變數
sum := add(20, 30)
fmt.Println(sum)
}

命名返回值的函數

在 Golang 中,函數的返回值可以命名。這意味著你可以在函數中指定返回值的名稱,並在函數內部直接使用這些名稱。

以下是一個計算矩形面積和周長的範例:

package main

import "fmt"
func rectangle(l int, b int) (area int) {
parameter := 2 * (l + b)
fmt.Println("周長:", parameter)
area = l * b
return// 省略返回值變數,使用命名的返回
}
func main() {
fmt.Println("面積:", rectangle(20, 30))
}

返回多個值的函數

函數還可以返回多個值,這在處理多個相關的值時非常方便。以下是一個返回矩形面積和周長的範例:

package main

import "fmt"
// rectangle 是一個計算矩形面積和周長的函數,返回兩個值
func rectangle(length int, breadth int) (area int, perimeter int) {
perimeter = 2 * (length + breadth)
area = length * breadth
return // 省略返回值變數,使用命名的返回
}
func main() {
a, p := rectangle(10, 5) // 呼叫 rectangle 函數並接收返回值
fmt.Println("面積:", a)
fmt.Println("周長:", p)
}

將位址傳遞給函數進行值更新

在 Golang 中,你還可以將變數的位址傳遞給函數,並且在函數內部透過解引用的方式來修改變數的值。以下範例將展示這種通過位址更新變數值的情境:

package main

import "fmt"
func update(a *int, t *string) {
*a = *a + 5 // 透過解引用位址修改變數值
*t = *t + " Doe" // 透過解引用位址修改變數值
return
}
func main() {
var age = 20
var text = "John"
fmt.Println("修改前:", text, age)
update(&age, &text)
fmt.Println("修改後:", text, age)
}

匿名函數:更靈活的處理

在 Golang 中,還可以使用匿名函數。匿名函數是一種無需命名識別符即可宣告的函數。匿名函數可以接受輸入並返回輸出,就像普通函數一樣。以下是一個將函數指派給變數並使用匿名函數:

package main

import "fmt"
var (
area = func(l int, b int) int {
return l * b
}
)
func main() {
fmt.Println(area(20, 30))
}

你還可以將參數傳遞給匿名函數:

package main

import "fmt"
func main() {
func(l int, b int) {
fmt.Println(l * b)
}(20, 30)
}

匿名函數也可以接受參數並返回值:

package main

import "fmt"
func main() {
fmt.Printf(
"100 (°F) = %.2f (°C)\n",
func(f float64) float64 {
return (f - 32.0) * (5.0 / 9.0)
}(100),
)
}

閉包:捕獲外部變數

在 Golang 中,閉包是匿名函數的一種特殊情形。閉包是可以存取在函數外部定義的變數的匿名函數。

以下是一個使用閉包的範例,其中匿名函數可以訪問在函數外部定義的變數:

package main

import "fmt"
func main() {
l := 20
b := 30
func() {
var area int
area = l * b
fmt.Println(area)
}()
}

另一個範例是,在函數內的迴圈迭代過程中,匿名函數可以訪問變數的值:

package main

import "fmt"
func main() {
for i := 10.0; i < 100; i += 10.0 {
rad := func() float64 {
return i * 39.370
}()
fmt.Printf("%.2f 公尺 = %.2f 英吋\n", i, rad)
}
}

高階函數:函數作為參數和返回值

在 Golang 中,函數可以作為參數傳遞給其他函數,也可以作為函數的返回值。這種功能稱為高階函數(Higher-Order Functions),能夠提供更靈活且模組化的程式設計方式。以下範例演示如何創建一個高階函數,將一個函數套用到切片的每個元素:

package main

import (
"fmt"
"strings"
)
// mapString 將 f 函數套用到每個字串元素並返回新的切片
func mapString(arr []string, f func(string) string) []string {
result := make([]string, len(arr))
for i, v := range arr {
result[i] = f(v)
}
return result
}
func main() {
words := []string{"apple", "banana", "cherry"}
toUpper := func(s string) string {
return strings.ToUpper(s)
}
upperWords := mapString(words, toUpper)
fmt.Println(upperWords) // 輸出:[APPLE BANANA CHERRY]
}

函數作為參數傳遞給其他函數

以下是一個將函數作為參數傳遞給高階函數的範例:

package main

import "fmt"
func sum(x, y int) int {
return x + y
}
func partialSum(x int) func(int) int {
return func(y int) int {
return sum(x, y)
}
}
func main() {
partial := partialSum(3)
fmt.Println(partial(7))
}

將函數作為結果返回的高階函數

你還可以將函數作為結果返回,這被稱為返回函數的高階函數。以下是一個範例,該範例返回一個函數,該函數在其內部使用嵌套的匿名函數:

package main

import "fmt"
func squareSum(x int) func(int) func(int) int {
return func(y int) func(int) int {
return func(z int) int {
return x*x + y*y + z*z
}
}
}
func main() {
resultFunc := squareSum(5) // 返回一個函數
subResultFunc := resultFunc(6) // 返回一個嵌套函數
finalResult := subResultFunc(7) // 呼叫最內層的函數獲取結果
fmt.Println(finalResult) // 印出最終計算結果
fmt.Println(squareSum(5)(6)(7))
}

自定義函數類型

在 Golang 中,你可以使用 type 關鍵字定義自己的函數類型。這就像是為函數創建了一個別名,使得該函數類型能夠被用作變數的型別。自定義函數類型能夠讓你更好地組織程式碼,以及在特定情境下使代碼更具表達性。

以下是一個使用自定義函數類型的範例,我們將創建一個函數類型 First,並進一步使用 Second 函數類型。這些自定義的函數類型可以用於創建一個執行特定計算的函數:

package main

import "fmt"
// 定義 First 函數類型
type First func(int) int
// 定義 Second 函數類型
type Second func(int) First
// squareSum 返回一個 Second 函數
func squareSum(x int) Second {
return func(y int) First {
return func(z int) int {
return x*x + y*y + z*z
}
}
}
func main() {
// 使用自定義函數類型的範例
result := squareSum(5)(6)(7)
fmt.Println("計算結果:", result) // 輸出:110
}

函數的特性、限制與使用場景

函數是程式設計中的重要組成部分,它們能夠將程式碼模組化、重複使用,使程式更具可讀性和可維護性。然而,函數也有其特性、限制以及適用的使用場景,讓我們來一起深入了解。

函數的特性

  1. 模組化: 函數能夠將程式碼分成小的模組,使得程式邏輯更加清晰,也更容易進行測試和修改。
  2. 重複使用: 定義一次函數後,你可以在程式中多次調用它,避免了重複編寫相同的程式碼。
  3. 參數和返回值: 函數可以接受參數,這些參數提供了執行函數所需的資訊。同時,函數可以返回值,使得結果能夠被其他程式碼使用。
  4. 封裝: 函數能夠封裝實現細節,隱藏程式碼的複雜性,使得外部使用者只需關心函數的功能。
  5. 遞迴: 函數可以呼叫自己,這種稱為遞迴的特性在處理某些問題時非常有用。

函數的限制

  1. 可讀性: 過多的函數調用可能導致程式難以閱讀和理解,因此需要適當的拆分和命名函數。
  2. 效能考慮: 過於頻繁的函數調用可能會影響程式的效能,因為每次函數呼叫都會有一定的開銷。
  3. 記憶體使用: 函數的呼叫需要保留堆疊帧等相關資訊,這可能會佔用一些記憶體空間。
  4. 可變性: 在某些程式語言中,函數可能會更改其外部範疇的變數,這可能導致程式難以理解和調試。

函數的使用場景

  1. 程式模組化: 將相關的程式碼封裝為函數,可以使程式更具結構,更容易維護。
  2. 代碼重用: 如果你在多個地方需要執行相同或類似的操作,可以將這些操作封裝成函數,方便重複使用。
  3. 抽象化: 函數可以將複雜的實現細節隱藏起來,只暴露必要的介面,使外部程式碼更易於理解。
  4. 遞迴問題: 某些問題的解決方案適合使用遞迴,例如數學中的遞迴定義和分治算法。
  5. 事件處理: 在事件驅動的程式中,函數可以用於處理不同的事件類型,使程式具有彈性。
  6. 資料轉換: 函數可以用於將一種資料類型轉換為另一種,例如日期格式轉換、單位轉換等。
  7. 處理業務邏輯: 在軟體應用中,函數可以用於實現業務邏輯,如處理訂單、用戶驗證等。
  8. 演算法實現: 函數是實現演算法的基本元素,能夠將複雜的演算法分解成可管理的部分。

函數的常見用法

1. 計算數值的平方和

package main

import "fmt"
func squareSum(numbers ...int) int {
sum := 0
for _, num := range numbers {
sum += num * num
}
return sum
}
func main() {
result := squareSum(2, 3, 4)
fmt.Println("平方和:", result)
}

2. 找出切片中的最大值

package main

import (
"fmt"
"math"
)
func findMax(numbers ...float64) float64 {
max := math.Inf(-1)
for _, num := range numbers {
if num > max {
max = num
}
}
return max
}
func main() {
result := findMax(2.3, 5.7, 1.2, 9.8)
fmt.Println("最大值:", result)
}

3. 檢查字串是否為回文

package main

import (
"fmt"
"strings"
)
func isPalindrome(s string) bool {
s = strings.ToLower(s)
for i := 0; i < len(s)/2; i++ {
if s[i] != s[len(s)-1-i] {
return false
}
}
return true
}
func main() {
result := isPalindrome("racecar")
fmt.Println("是否為回文:", result)
}

4. 計算 Fibonacci 數列

package main

import "fmt"
func fibonacci(n int) int {
if n <= 0 {
return 0
} else if n == 1 {
return 1
}
return fibonacci(n-1) + fibonacci(n-2)
}
func main() {
result := fibonacci(6)
fmt.Println("第 6 個 Fibonacci 數:", result)
}

5. 判斷是否為質數

package main

import "fmt"
func isPrime(n int) bool {
if n <= 1 {
return false
}
for i := 2; i*i <= n; i++ {
if n%i == 0 {
return false
}
}
return true
}
func main() {
result := isPrime(17)
fmt.Println("17 是否為質數:", result)
}

小結

函數是 Golang 程式設計的基石之一,讓你能夠組織程式碼、提高重用性,並以更模組化的方式處理不同情境的需求。無論是創建簡單的函數、使用閉包捕獲變數,還是運用高階函數進行模組化設計,函數都在 Golang 中扮演著關鍵角色。

📚Reference

留言
avatar-img
留言分享你的想法!
avatar-img
Alan的開發者天地
19會員
83內容數
golang
Alan的開發者天地的其他內容
2023/10/04
👨‍💻 簡介 最近想要透過小實作來撰寫筆記,達到做中學的效果,因此就來實作個小爬蟲順便結合前面學到的package做一個小複習。
Thumbnail
2023/10/04
👨‍💻 簡介 最近想要透過小實作來撰寫筆記,達到做中學的效果,因此就來實作個小爬蟲順便結合前面學到的package做一個小複習。
Thumbnail
2023/09/28
👨‍💻簡介 今天來介紹一個自己開發後端蠻常用的一個 package,promptui,拿來做menu真的很方便,promptui有兩個主要的輸入模式: Prompt:跳出單行使用者輸入。 Select:提供一個選項列表供使用者選擇。
Thumbnail
2023/09/28
👨‍💻簡介 今天來介紹一個自己開發後端蠻常用的一個 package,promptui,拿來做menu真的很方便,promptui有兩個主要的輸入模式: Prompt:跳出單行使用者輸入。 Select:提供一個選項列表供使用者選擇。
Thumbnail
2023/09/26
👨‍💻 簡介 在處理string時,正則表達式是一個非常有用的工具。Go語言的regexp package 可以使用正則表達式,用來執行如檢查string是否匹配某個模式、提取匹配的subString等操作。
Thumbnail
2023/09/26
👨‍💻 簡介 在處理string時,正則表達式是一個非常有用的工具。Go語言的regexp package 可以使用正則表達式,用來執行如檢查string是否匹配某個模式、提取匹配的subString等操作。
Thumbnail
看更多
你可能也想看
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
本章節旨在介紹 C# 中函數的基本結構,包括訪問修飾符、返回類型、方法名稱、參數列表和方法體。同時,也介紹了函數的各種呼叫方式、參數傳遞方式和返回值類型。讀者可以通過本章節,深入理解 C# 中函數的使用和應用。
Thumbnail
本章節旨在介紹 C# 中函數的基本結構,包括訪問修飾符、返回類型、方法名稱、參數列表和方法體。同時,也介紹了函數的各種呼叫方式、參數傳遞方式和返回值類型。讀者可以通過本章節,深入理解 C# 中函數的使用和應用。
Thumbnail
在Python中,我們可以用def關鍵字定義函數,並透過函數名稱呼叫它。函數參數可以是必填、關鍵字、默認或不定長度的類型。return語句負責結束函數並回傳值。全域變數可以在整個程序中使用,而區域變數只能在特定函數內使用。我們還可以在一個文件中定義函數,然後在另一個文件中呼叫它。
Thumbnail
在Python中,我們可以用def關鍵字定義函數,並透過函數名稱呼叫它。函數參數可以是必填、關鍵字、默認或不定長度的類型。return語句負責結束函數並回傳值。全域變數可以在整個程序中使用,而區域變數只能在特定函數內使用。我們還可以在一個文件中定義函數,然後在另一個文件中呼叫它。
Thumbnail
👨‍💻簡介 套件(Package)在Golang中扮演著組織和管理程式碼的重要角色。 package就像工具箱一樣,裡面裝滿各種不同的工具,每個工具都有特定的功能。這些工具能夠幫助你完成不同的任務,從修理家具到蓋小屋,樣樣都行。
Thumbnail
👨‍💻簡介 套件(Package)在Golang中扮演著組織和管理程式碼的重要角色。 package就像工具箱一樣,裡面裝滿各種不同的工具,每個工具都有特定的功能。這些工具能夠幫助你完成不同的任務,從修理家具到蓋小屋,樣樣都行。
Thumbnail
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
Thumbnail
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
Thumbnail
👨‍💻簡介 在 Go 語言中,有著一個強大又便捷的工具,可以讓你以鍵-值(Key-Value)的形式儲存和查詢資料,它就是「Map」。Map 在 Go 語言中扮演了重要的角色,簡化了許多資料處理的任務,現在讓我們一起來深入了解這個有趣的資料型別。 Map的基本概念 Map 是 Go 語
Thumbnail
👨‍💻簡介 在 Go 語言中,有著一個強大又便捷的工具,可以讓你以鍵-值(Key-Value)的形式儲存和查詢資料,它就是「Map」。Map 在 Go 語言中扮演了重要的角色,簡化了許多資料處理的任務,現在讓我們一起來深入了解這個有趣的資料型別。 Map的基本概念 Map 是 Go 語
Thumbnail
運用 Golang 正則表達式處理文本。從替換操作到 URL 解析,再到日誌分析,掌握實際應用場景下的正則技巧,提取、轉換和分析文本數據。
Thumbnail
運用 Golang 正則表達式處理文本。從替換操作到 URL 解析,再到日誌分析,掌握實際應用場景下的正則技巧,提取、轉換和分析文本數據。
Thumbnail
👨‍💻簡介 在這篇文章裡,會簡單介紹幾個關鍵的基本概念和語法結構,加快上手這門程式語言。
Thumbnail
👨‍💻簡介 在這篇文章裡,會簡單介紹幾個關鍵的基本概念和語法結構,加快上手這門程式語言。
Thumbnail
在第五堂課中,我們將探討 Python 中的函式(functions)。 函式是一種讓我們可以將程式碼塊組織成一個獨立、可重複使用的單元的方式。 函式可以接受參數 (arguments) 並返回一個結果。 讓我們在新的文件 functions.py 中學習如何定義和使用函式。
Thumbnail
在第五堂課中,我們將探討 Python 中的函式(functions)。 函式是一種讓我們可以將程式碼塊組織成一個獨立、可重複使用的單元的方式。 函式可以接受參數 (arguments) 並返回一個結果。 讓我們在新的文件 functions.py 中學習如何定義和使用函式。
Thumbnail
在第五課中,我們將探討 Python 中的函式(functions)。 函式是一種讓我們可以將程式碼塊組織成一個獨立、可重複使用的單元的方式。函式可以接受參數 (arguments) 並返回一個結果。
Thumbnail
在第五課中,我們將探討 Python 中的函式(functions)。 函式是一種讓我們可以將程式碼塊組織成一個獨立、可重複使用的單元的方式。函式可以接受參數 (arguments) 並返回一個結果。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News