go 函数名之前括号中的内容_2020 重学 Go 系列:09. 一篇文章理解 Go 里的函数
1. 關(guān)于函數(shù)
函數(shù)是基于功能或 邏輯進(jìn)行封裝的可復(fù)用的代碼結(jié)構(gòu)。將一段功能復(fù)雜、很長(zhǎng)的一段代碼封裝成多個(gè)代碼片段(即函數(shù)),有助于提高代碼可讀性和可維護(hù)性。
在 Go 語(yǔ)言中,函數(shù)可以分為兩種:
帶有名字的普通函數(shù)
沒有名字的匿名函數(shù)
由于 Go語(yǔ)言是編譯型語(yǔ)言,所以函數(shù)編寫的順序是無(wú)關(guān)緊要的,它不像 Python 那樣,函數(shù)在位置上需要定義在調(diào)用之前。
2. 函數(shù)的聲明
函數(shù)的聲明,使用 func 關(guān)鍵字,后面依次接 函數(shù)名,參數(shù)列表,返回值列表,用 {} 包裹的代碼邏輯體
func?函數(shù)名(形式參數(shù)列表)(返回值列表){????函數(shù)體
}
形式參數(shù)列表描述了函數(shù)的參數(shù)名以及參數(shù)類型,這些參數(shù)作為局部變量,其值由參數(shù)調(diào)用者提供
返回值列表描述了函數(shù)返回值的變量名以及類型,如果函數(shù)返回一個(gè)無(wú)名變量或者沒有返回值,返回值列表的括號(hào)是可以省略的。
舉個(gè)例子,定義一個(gè) sum 函數(shù),接收兩個(gè) int 類型的參數(shù),在運(yùn)行中,將其值分別賦值給 a,b,并規(guī)定必須返回一個(gè)int類型的值 。
func?sum(a?int,?b?int)?(int){????return?a?+?b
}
func?main()?{
????fmt.Println(sum(1,2))
}
3. 函數(shù)實(shí)現(xiàn)可變參數(shù)
上面舉的例子,參數(shù)個(gè)數(shù)都是固定的,這很好理解 ,指定什么類型的參數(shù)就傳入什么類型的變量,數(shù)量上,不能多一個(gè),也不能少一個(gè)。(好像沒有可選參數(shù))。
在 Python 中我們可以使用 *args 和 **kw ,還實(shí)現(xiàn)可變參數(shù)的函數(shù)。
可變參數(shù)分為幾種:
多個(gè)類型一致的參數(shù)
多個(gè)類型不一致的參數(shù)
多個(gè)類型一致的參數(shù)
首先是多個(gè)類型一致的參數(shù)。
這邊定義一個(gè)可以對(duì)多個(gè)數(shù)值進(jìn)行求和的函數(shù),
使用 ...int,表示一個(gè)元素為int類型的切片,用來(lái)接收調(diào)用者傳入的參數(shù)。
//?使用?...類型,表示一個(gè)元素為int類型的切片func?sum(args?...int)?int?{
????var?sum?int
????for?_,?v?:=?range?args?{
????????sum?+=?v
????}
????return?sum
}
func?main()?{
????fmt.Println(sum(1,?2,?3))
}
//?output:?6
其中 ... 是 Go 語(yǔ)言為了方便程序員寫代碼而實(shí)現(xiàn)的語(yǔ)法糖,如果該函數(shù)下會(huì)多個(gè)類型的函數(shù),這個(gè)語(yǔ)法糖必須得是最后一個(gè)參數(shù)。
同時(shí)這個(gè)語(yǔ)法糖,只能在定義函數(shù)時(shí)使用。
多個(gè)類型不一致的參數(shù)
上面那個(gè)例子中,我們的參數(shù)類型都是 int,如果你希望傳多個(gè)參數(shù)且這些參數(shù)的類型都不一樣,可以指定類型為 ...interface{},然后再遍歷。
比如下面這段代碼,是Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)中 fmt.Printf() 的函數(shù)原型:
import?"fmt"func?MyPrintf(args?...interface{})?{
????for?_,?arg?:=?range?args?{
????????switch?arg.(type)?{
????????????case?int:
????????????????fmt.Println(arg,?"is?an?int?value.")
????????????case?string:
????????????????fmt.Println(arg,?"is?a?string?value.")
????????????case?int64:
????????????????fmt.Println(arg,?"is?an?int64?value.")
????????????default:
????????????????fmt.Println(arg,?"is?an?unknown?type.")
????????}
????}
}
func?main()?{
????var?v1?int?=?1
????var?v2?int64?=?234
????var?v3?string?=?"hello"
????var?v4?float32?=?1.234
????MyPrintf(v1,?v2,?v3,?v4)
}
在某些情況下,我們需要定義一個(gè)參數(shù)個(gè)數(shù)可變的函數(shù),具體傳入幾個(gè)參數(shù),由調(diào)用者自己決定,但不管傳入幾個(gè)參數(shù),函數(shù)都能夠處理。
比如這邊實(shí)現(xiàn)一個(gè)累加
func?myfunc(args?...int)?{????for?_,?arg?:=?range?args?{
????????fmt.Println(arg)
????}
}
4. 多個(gè)可變參數(shù)函數(shù)傳遞參數(shù)
上面提到了可以使用 ... ?來(lái)接收多個(gè)參數(shù),除此之外,它還有一個(gè)用法,就是用來(lái)解序列,將函數(shù)的可變參數(shù)(一個(gè)切片)一個(gè)一個(gè)取出來(lái),傳遞給另一個(gè)可變參數(shù)的函數(shù),而不是傳遞可變參數(shù)變量本身。
同樣這個(gè)用法,也只能在給函數(shù)傳遞參數(shù)里使用。
例子如下:
import?"fmt"func?sum(args?...int)?int?{
????var?result?int
????for?_,?v?:=?range?args?{
????????result?+=?v
????}
????return?result
}
func?Sum(args?...int)?int?{
????//?利用?...?來(lái)解序列
????result?:=?sum(args...)
????return?result
}
func?main()?{
????fmt.Println(sum(1,?2,?3))
}
5. 函數(shù)的返回值
Go語(yǔ)言中的函數(shù),在你定義的時(shí)候,就規(guī)定了此函數(shù)
有沒有返回值?
當(dāng)沒有指明返回值的類型時(shí), 函數(shù)體可以有 return,Go并不像 Python 那樣沒有return,就默認(rèn)返回None
返回幾個(gè)值?
Go 支持一個(gè)函數(shù)返回多個(gè)值
func?double(a?int)?(int,?int)?{???b?:=?a?*?2
???return?a,?b
}
func?main()?{
???//?接收參數(shù)用逗號(hào)分隔
???a,?b?:=?double(2)
???fmt.Println(a,?b)
}
怎么返回值?
Go支持返回帶有變量名的值
func?double(a?int)?(b?int)?{???//?不能使用?:=?,因?yàn)樵诜祷刂的睦镆呀?jīng)聲明了為int
???b?=?a?*?2
???//?不需要指明寫回哪個(gè)變量,在返回值類型那里已經(jīng)指定了
???return
}
func?main()?{
???fmt.Println(double(2))
}
//?output:?4
6. 方法與函數(shù)
方法,在上一節(jié)《08. 面向?qū)ο缶幊?#xff1a;結(jié)構(gòu)體與繼承》里已經(jīng)介紹過(guò)了,它的定義與函數(shù)有些不同,你可以點(diǎn)擊前面的標(biāo)題進(jìn)行交叉學(xué)習(xí)。
那 方法和函數(shù)有什么區(qū)別? 為防有朋友第一次接觸面向?qū)ο?#xff0c;這里多嘴一句。
方法,是一種特殊的函數(shù)。當(dāng)你一個(gè)函數(shù)和對(duì)象/結(jié)構(gòu)體進(jìn)行綁定的時(shí)候,我們就稱這個(gè)函數(shù)是一個(gè)方法。
7. 匿名函數(shù)的使用
所謂匿名函數(shù),就是沒有名字的函數(shù),它只有函數(shù)邏輯體,而沒有函數(shù)名。
定義的格式如下
func(參數(shù)列表)(返回參數(shù)列表){????函數(shù)體
}
一個(gè)名字實(shí)際上并沒有多大區(qū)別,所有使用匿名函數(shù)都可以改成普通有名函數(shù),那么什么情況下,會(huì)使用匿名函數(shù)呢?
定義變量名,是一個(gè)不難但是還費(fèi)腦子的事情,對(duì)于那到只使用一次的函數(shù),是沒必要擁有姓名的。這才有了匿名函數(shù)。
有了這個(gè)背景,決定了匿名函數(shù)只有擁有短暫的生命,一般都是定義后立即使用。
就像這樣,定義后立馬執(zhí)行(這里只是舉例,實(shí)際代碼沒有意義)。
func(data?int)?{????fmt.Println("hello",?data)
}(100)
亦或是做為回調(diào)函數(shù)使用
//?第二個(gè)參數(shù)為函數(shù)func?visit(list?[]int,?f?func(int))?{
????for?_,?v?:=?range?list?{
????????//?執(zhí)行回調(diào)函數(shù)
????????f(v)
????}
}
func?main()?{
????//?使用匿名函數(shù)直接做為參數(shù)
????visit([]int{1,?2,?3,?4},?func(v?int)?{
????????fmt.Println(v)
????})
}
推薦閱讀
2020 重學(xué) Go 系列:08. 面向?qū)ο缶幊?#xff1a;結(jié)構(gòu)體與繼承
喜歡本文的朋友,歡迎關(guān)注“Go語(yǔ)言中文網(wǎng)”:
Go語(yǔ)言中文網(wǎng)啟用微信學(xué)習(xí)交流群,歡迎加微信:274768166,投稿亦歡迎
總結(jié)
以上是生活随笔為你收集整理的go 函数名之前括号中的内容_2020 重学 Go 系列:09. 一篇文章理解 Go 里的函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MFC模拟360悬浮窗加速球窗口
- 下一篇: 办公效率:从事会计行业,这些Excel技