6.go語言函數

Go語言中的函數是組織代碼的最小單元,用于封裝一段代碼,完成特定的功能。函數的使用可以減少代碼冗余,提高代碼的可讀性和可維護性。

函數的基本定義和語法

在Go語言中,定義一個函數的基本語法如下:

func functionName(parameter1 type1, parameter2 type2, ...) (returnType, returnType...){

// 函數體return value1,value2... // 返回值

}

  • func:關鍵字用于定義函數。

  • functionName:函數名,用于唯一標識該函數。

  • parameter1 type1, parameter2 type2, ...:參數列表,函數可以接收零個或多個參數。每個參數由參數名和參數類型組成,多個參數之間使用逗號分隔。

  • returnType:返回類型,指定函數的返回值的數據類型。可以返回零個或多個值

  • return value:返回值,如果有返回值,則需要使用return語句將結果返回給調用者。

如果沒有返回值,可以不寫 return。如果寫了,代表退出整個函數。

命名返回值

go語言支持為返回值命名。這些命名的返回值可以在函數體內部直接使用,而不需要顯式地返回它們。這種方式特別適用于在函數執行過程中逐步構建或計算返回值,或者在滿足特定條件時提前返回。

func sum(a, b int) (result int) {result = a + b // 直接賦值給命名返回值if result >= 0 {return // 提前返回,此時 result 自動返回}// 可以繼續處理其他邏輯。比方返回值小于0,打印一句提醒,并把結果處理成正數。fmt.Println("您的計算結果小于0,已經為您取絕對值")result = result * -1return // 最終返回 result
}func main() {fmt.Println(sum(5, 7))  // 輸出: 12fmt.Println(sum(-3, -7)) // 輸出: (您的計算結果小于0,已經為您取絕對值  10)
}

函數的調用方式

函數的調用是通過函數名加上括號實現的。如果函數有參數,調用時需要在括號內傳入實際的參數值。例如:

func add(a int, b int) int {
return a + b
}
func main() {result := add(3, 5) // 調用add函數,傳入3和5作為參數fmt.Println("3 + 5 =", result) // 輸出結果
}

定義多返回值函數

你可以在函數定義時,通過在參數列表后直接指定返回值的類型來實現多返回值。每個返回值類型之間用逗號分隔。

使用函數時候,你只對函數的某些返回值感興趣,可以使用下劃線(_)來忽略不需要的返回值。

func divide(a, b int) (int, int) {r := a / breturn r, a % b // 可以使用變量 返回,也可以使用表達式計算結果返回
}func main() {_, remainder := divide(10, 3) // 只關心余數,忽略商數fmt.Println("Remainder:", remainder)
}

//注意,定義無返回值函數,不能使用變量接收 函數的返回。

可變參數

go語言,不支持給參數設置默認值。

但是支持,可變參數。使用...type 定義。把收集到多余的實參,存放到對應類型的切片中。

匿名函數

匿名函數是通過 func 關鍵字直接定義的,沒有指定函數名。你可以將匿名函數賦值給一個變量,或者直接調用它。

  myFunction := func(x, y int) int {return x + y}// 調用匿名函數result := myFunction(5, 10)fmt.Println(result) // 輸出: 15// 直接調用匿名函數result := func(x, y int) int {return x + y}(5, 10)fmt.Println(result) // 輸出: 15

go函數作為參數類型

函數作為參數的使用方式非常簡單,我們只需要將需要傳遞的函數作為參數傳遞給另一個接受這個函數作為參數的函數即可。

如果邏輯代碼很復雜,上邊代碼就很 臃腫,不容易讓人理解。我們可以。把函數簽名聲明為一個類型。

函數閉包

閉包通常涉及到定義一個函數,該函數在其內部定義了另一個函數,并將該函數返回出去,返回出去的函數可以訪問外部函數的變量。

package mainimport "fmt"func outerFunction() func() int {var x = 10return func() int {x++return x}
}func main() {myClosure := outerFunction() // 獲取閉包fmt.Println(myClosure()) // 輸出: 11fmt.Println(myClosure()) // 輸出: 12
}

函數總結

函數的特性

Go語言的函數具有以下特性:

  • 支持不定參數:可以使用...來表示不定參數,允許函數接收任意數量的參數。

  • 支持多返回值:可以返回多個結果,例如錯誤信息和結果值。

  • 支持命名返回參數:可以在函數內部給返回值命名,方便處理返回值。

  • 支持匿名函數和閉包:可以定義匿名函數并在需要時調用。

  • 函數也是一種類型:一個函數可以賦值給變量,實現更靈活的調用。

  • 不支持嵌套、重載和默認參數:Go語言不支持在一個包中定義兩個名字相同的函數、函數的重載以及默認參數

defer 延遲調用

defer的核心作用是延遲調用函數或方法,

這意味著defer語句所指定的函數調用會被推遲到當前函數返回之前執行,無論函數是正常返回還是因發生異常而返回。

當一個函數中有多個defer語句時,它們會按照后進先出的順序執行。也就是說,最后一個defer語句所指定的函數會最先被調用,而第一個defer語句所指定的函數最后被調用。例如:

遞歸是一種常見的編程技術,它允許函數直接或間接地調用自身。

遞歸的核心思想在于將一個大問題分解為若干個小問題,然后逐步解決這些小問題,最終達到解決整個大問題的目的。

特點:

??自身調用:原問題可以分解為子問題,子問題和原問題的求解方法是一致的,即都是調用自身的同一個函數。

??終止條件:遞歸必須有一個終止的條件,即不能無限循環地調用本身。

??簡潔但效率不高:遞歸算法解題通常顯得很簡潔,但遞歸算法解題的運行效率較低,因為數據存入堆棧中,等待函數調用結束后再取出,會增加性能消耗。另外堆棧還存在溢出的風險。

計算階乘的遞歸函數:

func factorial(n uint) uint {

????????if n == 0 {

????????????????return 1 // 遞歸終止條件

?????????? }

????????return n * factorial(n-1) // 調用自身

}

  • . 構建遞歸調用堆棧

每次函數調用自身時,一個新的調用實例被推入調用堆棧。直到達到基本情況,才開始從堆棧中逐個返回結果。這個過程類似于函數調用鏈的構建和解析。

  • 避免無限遞歸和棧溢出

正確設置遞歸終止條件,確保每個遞歸函數都有清晰定義的基本情況是非常重要的,否則可能會導致無限遞歸,進而耗盡棧空間,導致程序崩潰(棧溢出)。

  • 優化遞歸(尾遞歸優化)

在某些情況下,可以通過尾遞歸優化來提高效率。尾遞歸是指在函數的最后一步調用自身的情況。Go語言在某些情況下可以優化尾遞歸,使其表現得像循環一樣,從而避免棧溢出。

遞歸是實現諸如樹遍歷、排序算法(如快速排序)、 斐波那契數列,圖與樹的遍歷搜索等多種算法的有效方式

快速排序的實現

package mainimport ("fmt"
)// quickSort 對數組 arr 進行快速排序
func quickSort(arr []int) []int {if len(arr) < 2 {// 基本情況:數組只有一個元素或為空,無需排序return arr}left, right := 0, len(arr)-1// 選擇最右邊的元素作為基準值pivot := right// 將數組分為小于基準和大于基準的兩部分newPivot := partition(arr, left, right, pivot)// 遞歸排序左右兩部分quickSort(arr[:newPivot])quickSort(arr[newPivot+1:])return arr
}// partition 對數組進行劃分,返回新的基準位置
func partition(arr []int, left, right, pivot int) int {pivotValue := arr[pivot]// 將基準值交換到最右邊,即最后一個位置arr[pivot], arr[right] = arr[right], arr[pivot]storeIndex := leftfor i := left; i < right; {if arr[i] < pivotValue {arr[i], arr[storeIndex] = arr[storeIndex], arr[i]storeIndex++}i++}// 將基準值放到正確的位置上arr[storeIndex], arr[right] = arr[right], arr[storeIndex]return storeIndex // 返回新的基準位置
}func main() {arr := []int{10, 7, 8, 9, 1, 5}fmt.Println("Original array:", arr)sortedArr := quickSort(arr)fmt.Println("Sorted array:  ", sortedArr)
}

go內置排序函數

sort.Slice進行通用排序

從Go 1.8開始,sort包引入了Slice函數,它允許你直接對切片進行排序,而無需實現任何接口。

package mainimport ("fmt""sort"
)func main() {a := []int{3, 1, 4, 1, 5, 9}sort.Slice(a, func(i, j int) bool { return a[i] < a[j] }) // 使用閉包進行排序邏輯定義fmt.Println(a) // 輸出: [1 1 3 4 5 9]
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73539.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73539.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73539.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringCould微服務架構之Docker(4)

Docker ce是社區版。 安裝docker之前&#xff0c;先安裝yum-util 。 安裝docker之前&#xff0c;一定要先關閉防火墻。

Keepalived 實現高可用方案

Keepalived簡介 ?Keepalived? 是一個基于 ?VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;協議?的高可用性解決方案&#xff0c;主要用于實現?服務故障自動切換&#xff08;Failover&#xff09;和負載均衡?。通過管理虛擬 IP&#xff08;VIP&#xf…

WPS JS宏編程教程(從基礎到進階)--第二部分:WPS對象模型與核心操作

第二部分&#xff1a;WPS對象模型與核心操作 WPS對象的屬性、方法、集合 工作簿對象常用表達方式工作表對象常用表達方式單元格對象常用表達方式 單元格操作實戰 單元格復制與重定位單元格偏移與尺寸調整 顏色設置專題 索引顏色與RGB顏色按條件動態設置單元格顏色 第二部分&…

基于DrissionPage的TB商品信息采集與可視化分析

一、項目背景 隨著電子商務的快速發展,淘寶作為中國最大的電商平臺之一,擁有海量的商品信息。這些數據對于市場分析、用戶行為研究以及競爭情報收集具有重要意義。然而,由于淘寶的反爬蟲機制和復雜的頁面結構,直接獲取商品信息并不容易。尤其是在電商行業高速發展的今天,商…

【003安卓開發方案調研】之ReactNative技術開發安卓

基于2025年最新行業動態和搜索資料&#xff0c;以下是針對國內使用React Native&#xff08;RN&#xff09;開發安卓應用的深度分析&#xff1a; 一、技術成熟度評估 1. 核心架構升級 新架構全面普及&#xff1a;2024年起&#xff0c;React Native的 新架構&#xff08;Fabri…

JS數組方法

數組方法 一、數組 JavaScript 數組的大小是可調整的&#xff0c;并且可以包含不同 數據類型。&#xff08;當不需要這些特性時&#xff0c;請使用 類型數組。&#xff09; 注&#xff1a;JavaScript 類型數組是類似數組的對象&#xff0c;它提供了一種在內存緩沖區中讀取和寫…

【一起學Rust | Tauri2.0框架】深入淺出 Tauri 2.0 應用調試:從新手到專家的蛻變

前言 Tauri 是一款備受矚目的跨平臺桌面應用開發框架&#xff0c;它允許開發者使用 Web 技術棧&#xff08;HTML、CSS、JavaScript&#xff09;構建高性能、安全的原生應用。Tauri 2.0 的發布帶來了諸多令人興奮的新特性和改進&#xff0c;進一步提升了開發體驗和應用性能。然…

Python項目-基于Python的網絡爬蟲與數據可視化系統

1. 項目簡介 在當今數據驅動的時代&#xff0c;網絡爬蟲和數據可視化已成為獲取、分析和展示信息的重要工具。本文將詳細介紹如何使用Python構建一個完整的網絡爬蟲與數據可視化系統&#xff0c;該系統能夠自動從互聯網收集數據&#xff0c;進行處理分析&#xff0c;并通過直觀…

TCP/IP三次握手的過程,為什么要3次?

一&#xff1a;過程 第一次&#xff08;SYN&#xff09;&#xff1a; 客戶端發送一個帶有SYN標志的TCP報文段給服務器&#xff0c;設置SYN1&#xff0c;并攜帶初始序列號Seqx&#xff08;隨機值&#xff09;&#xff0c;進入SYN_SENT狀態。等待服務器相應。 第二次&#xff08…

消息隊列性能比拼: Kafka vs RabbitMQ

本內容是對知名性能評測博主 Anton Putra Kafka vs RabbitMQ Performance 內容的翻譯與整理, 有適當刪減, 相關數據和結論以原作結論為準。 簡介 在本視頻中&#xff0c;我們將首先比較 Apache Kafka 和傳統的 RabbitMQ。然后&#xff0c;在第二輪測試中&#xff0c;會將 Kaf…

打磨和修改:字帖自動生成

功能增加一些。 一個人和大語言模型對話的結果。 不過是重復性勞動&#xff0c;特別需要創意的地方還是不容易做到。

電腦干貨:萬能驅動--EasyDrv8

目錄 萬能驅動EasyDrv8 功能介紹 主程序界面 驅動解壓與安裝 PE環境支持 系統部署環境 桌面環境一鍵解決方案 萬能驅動8電腦版是由IT天空出品的一款智能識別電腦硬件并自動安裝驅動的工具&#xff0c;一般又稱為it天空萬能驅動&#xff0c;萬能驅動vip版&#xff0c;簡稱…

LeetCode熱題100JS(79/100)第十五天|347|295|121|55|45

347. 前 K 個高頻元素 題目鏈接&#xff1a;347. 前 K 個高頻元素 難度&#xff1a;中等 刷題狀態&#xff1a;1刷 新知識&#xff1a; 解題過程 思考 示例 1: 輸入: nums [1,1,1,2,2,3], k 2 輸出: [1,2] 沒思路&#xff0c;看答案 題解分析 參考題解鏈接&#xff1a…

Sentinel 限流利器(功能以及源碼解析)

Sentinel簡介 Sentinel是阿里開源的一款面向分布式、多語言異構化服務架構的流量治理組件。 主要以流量為切入點&#xff0c;從流量路由、流量控制、流量整形、熔斷降級、系統自適應過載保護、熱點流量防護等多個維度來幫助開發者保障微服務的穩定性。 核心概念 資源 資源是…

子數組 之 logTrick算法,求解或,與,LCM,GCD

文章目錄 gcd的問題最大公約數 求解子數組的&,|,lcm,gcd的最值or計數問題&#xff0c;如果采用暴力的做法&#xff0c;那么時間復雜度會來到o(n^2),其實在求解的過程中&#xff0c;會出現很多的結果不變的情況&#xff0c;所以我們就可以提前結束 存在一定的單調性&#x…

How to use pgbench to test performance for PostgreSQL?

pgbench 是一個用于測試 PostgreSQL 數據庫性能的基準測試工具。通過模擬多個客戶端并發執行 SQL 查詢&#xff0c;它可以幫助你評估數據庫的性能。以下是使用 pgbench 的基本步驟&#xff1a; 安裝 pgbench pgbench 是 PostgreSQL 的一部分&#xff0c;因此在安裝 PostgreSQ…

應用服務接口第二次請求一直pending問題

目錄 一、問題背景二、問題排查過程三、解決方案四、總結 一、問題背景 升級內容發布到灰度環境&#xff0c;驗證相關服務&#xff0c;查看接口調用日志&#xff0c;發現第一次請求正常&#xff0c;第二次相同接口請求就一直pending&#xff0c;其他服務也是如此 二、問題排查…

嵌入式八股RTOS與Linux---網絡系統篇

前言 關于計網的什么TCP三次握手 幾層模型啊TCP報文啥的不在這里講,會單獨分成一個計算機網絡模塊 ??這里主要介紹介紹lwip和socket FreeRTOS下的網絡接口–移植LWIP 實際上FreeRTOS并不自帶網絡接口,我們一般會通過移植lwip協議棧讓FreeRTOS可以通過網絡接口收發數據,具體可…

推薦一款好看的 vue3 后臺模板

SoybeanAdmin 項目簡介 SoybeanAdmin 是一個基于最新前端技術棧的清新、優雅、高顏值且功能強大的后臺管理模板。它采用 Vue3, Vite5, TypeScript, Pinia, NaiveUI 和 UnoCSS 構建&#xff0c;為開發者提供了一個現代化、高效且易于擴展的后臺管理系統解決方案。 主要特點&am…

【django】1-1 django構建web程序的基礎知識

文章目錄 1 構建web應用的基礎知識1.1 互聯網相關的概念1.2 互聯網協議DNS(域名系統)IP協議(互聯網絡協議)TCP(傳輸控制協議)HTTP(超文本傳輸協議)SSL(安全套接字層)TLS(傳輸層安全) 1.3 URL 2 web程序2.1 web程序的本質2.2 web框架的設計模式1.2.1 經典的MVC設計模式1.2.2 Dja…