Golang——函數(shù)func

函數(shù)是執(zhí)行特定公開花颗、可復(fù)用的代碼塊,包括函數(shù)惠拭、匿名函數(shù)扩劝、閉包≈案ǎ可作為變量今野、返回值、參數(shù)等罐农。

func 函數(shù)名(參數(shù))(返回值){
        函數(shù)體
}

函數(shù)名:字母条霜、數(shù)字、下劃線組成涵亏,第一個(gè)字母不能是數(shù)字宰睡;同一個(gè)包內(nèi)蒲凶,函數(shù)名也不能重名;
返回值:可返回多個(gè)返回值拆内,必須用()包裹旋圆,并用,分隔

函數(shù)定義與使用

func testOne(){
    fmt.Println("Hello")
}

func testTwo(x int){
    fmt.Println(x)
}

//多個(gè)同類型的參數(shù),可省略前面的類型
func testThree(x, y int){
    fmt.Println(x, y)
}

func testSum(x int, y int)int{
    ret := x + y
    return ret
} 

func testSum2(x int, y int)(ret int){
    ret = x + y
    return 
} 

//可變參數(shù)麸恍,在函數(shù)體中是切片類型
//固定參數(shù)和可變參數(shù)一起出現(xiàn)時(shí)候灵巧,可變參數(shù)必須放到最后
//go語言中沒有默認(rèn)參數(shù)
func testSum3(a int, x ...int)int{
    fmt.Printf("tyep:%T,content:%v\n", a, a)
    fmt.Printf("tyep:%T,content:%v\n", x, x)
    sum := 0
    for _, value := range x {
        sum += value
        // sum = testSum2(sum, value)
    }
    return sum
} 


//多個(gè)返回值情況,必須用括號(hào)包起來
//多個(gè)返回值抹沪,也支持參數(shù)簡(jiǎn)寫
func calc(a, b int)(sum, sub int){
    sum = a + b
    sub = a - b
    return 
}


func main() {
    
    testOne()

    testTwo(2)

    testThree(3, 3)

    fmt.Println(testSum(1, 1))

    fmt.Println(testSum2(2, 2))

    sum1 := testSum3(1, 2, 3, 4, 5);
    fmt.Println(sum1)

    sum2 := testSum3(1, 2, 3, 4);
    fmt.Println(sum2)

    sum3 := testSum3(1);
    fmt.Println(sum3)

    sum, sub := calc(100, 200)
    fmt.Println(sum, sub)

} 

defer語句

將其后面跟隨的語句進(jìn)行延遲處理刻肄,在defer歸屬的函數(shù)即將返回時(shí),將延遲處理的語句按照defer定義的逆序進(jìn)行執(zhí)行(先被defer的語句最后執(zhí)行融欧,最后被defer語句敏弃,最先被執(zhí)行)。
defer語句非常方便處理資源釋放問題噪馏,比如資源清理麦到、文件關(guān)閉、解鎖及記錄時(shí)間等欠肾。

//defer 延遲執(zhí)行
func main() {
    fmt.Println("start")
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    fmt.Println("end")
} 

輸出
start
end
3
2
1

經(jīng)典案例

package main

import "fmt"

//1.匯編層面定義一個(gè)變量接收函數(shù)返回值
//2.return x瓶颠,則這個(gè)返回變量的值為5
//3.defer指令,x++刺桃,x為6
//4.匯編層面RET指令粹淋,返回變量的值是5
func f1() int {
    x := 5
    defer func(){
        x++
    }()
    return x  
}

//1.匯編層面定義一個(gè)變量接收函數(shù)返回值,是x
//2.return x虏肾,則這個(gè)返回變量的值為5廓啊,x=5
//3.defer指令,x++封豪,x=6
//4.匯編層面RET指令谴轮,返回變量的值是6(x=6)
func f2() (x int) {
    defer func(){
        x++
    }()
    return 5
}

//1.匯編層面定義一個(gè)變量接收函數(shù)返回值,是y
//2.return x吹埠,則這個(gè)返回變量的值為5第步,y=5
//3.defer指令,x++缘琅,x=6
//4.匯編層面RET指令粘都,返回變量的值是5(y=5)
func f3() (y int) {
    x := 5
    defer func(){
        x++
    }()
    return x
}

//1.匯編層面定義一個(gè)變量接收函數(shù)返回值,是x
//2.return x刷袍,則這個(gè)返回變量的值為5翩隧,x=5
//3.defer指令,值傳遞
//4.匯編層面RET指令呻纹,返回變量的值是5(x=5)
func f4() (x int) {
    defer func(x int){
        x++
    }(x)
    return 5
}

func main() {
    fmt.Println(f1())    //5
    fmt.Println(f2())    //6
    fmt.Println(f3())    //5
    fmt.Println(f4())    //5
}

image.png

作用域

  • 函數(shù)內(nèi)部可以訪問全局變量堆生,如果函數(shù)內(nèi)部定義同名的局部變量专缠,先取用局部變量;
  • 外層不能訪問函數(shù)的內(nèi)部變量(局部變量)淑仆;
  • 外層訪問不到內(nèi)部for涝婉、if、switch語句塊中的變量蔗怠;
//定義全局變量
var num = 10

func test(){
    fmt.Println("全局變量", num)
    num := 20
    fmt.Println("局部變量", num)
}

func main() {
    test()

    fmt.Println("全局變量", num)
} 
輸出
全局變量 10
局部變量 20
全局變量 10

函數(shù)作為變量

//定義全局變量
var num = 10

func test(){
    fmt.Println("全局變量", num)
    num := 20
    fmt.Println("局部變量", num)
}

func main() {
    //函數(shù)作為變量
    abc := test
    fmt.Printf("%T\n", abc)
    //調(diào)用
    abc() 
} 
輸出
func()
全局變量 10
局部變量 20

函數(shù)作為參數(shù)

func add(x, y int) int {
    return x + y
}

func sub(x, y int) int {
    return x - y
}

func calc(x, y int, op func(int, int) int) int{
    return op(x, y)
}

func main() {
    add := calc(100, 200, add)
    fmt.Println(add)

    sub := calc(100, 200, sub)
    fmt.Println(sub)
} 

匿名函數(shù)

沒有函數(shù)名的函數(shù)

func(參數(shù))(返回值){
    函數(shù)體
}
func main() {
    //匿名函數(shù)賦值給變量
    test := func(){
        fmt.Println("haha")
    }
    test()

    //匿名函數(shù)直接使用
    func(){
        fmt.Println("hihi")
    }() 
}

閉包

閉包指的是一個(gè)函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體墩弯,即閉包=函數(shù)+引用環(huán)境

//函數(shù)返回值是函數(shù)
func a() func() {
    name := "lv"
    return func(){
        fmt.Println("haha", name)
    }
}

func b(name string) func() {
    return func(){
        fmt.Println("haha", name)
    }
}

func main() {
    //閉包 = 函數(shù) + 外層變量的引用
    r := a()
    r() //相當(dāng)于執(zhí)行了a函數(shù)內(nèi)部的匿名函數(shù)

    c := b("c")
    c()
}

常用內(nèi)置函數(shù)

內(nèi)置函數(shù) 介紹
close 主要是用來關(guān)閉channel
len 求長度寞射,例如string渔工、array、slice怠惶、map涨缚、channel
new 主要分配值類型內(nèi)存轧粟,例如 int策治、struct、string兰吟、array等通惫,返回的是指針
make 主要分配引用類型的內(nèi)存,比如chan混蔼、map履腋、slice
append 追加元素到array、slice中
panic和recover 用來錯(cuò)誤處理

Go(1.12)沒有異常處理惭嚣,用panicrecover遵湖。panic是運(yùn)行時(shí)候錯(cuò)誤。

  • recover必須搭配defer使用
  • defer一定要在可能引發(fā)panic的語句之前定義
func a(){
    fmt.Println("func a")
}

func b(){
    defer func(){
        err := recover()
        if err != nil {
            panic("func b error")
        }
    }()
    panic("panic in b")
}

func c(){
    fmt.Println("func c")
}

func main() {
    a()
    b()  //程序崩潰
    c()
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晚吞,一起剝皮案震驚了整個(gè)濱河市延旧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌槽地,老刑警劉巖迁沫,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異捌蚊,居然都是意外死亡集畅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門缅糟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挺智,“玉大人,你說我怎么就攤上這事窗宦∩馄模” “怎么了谣辞?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沐扳。 經(jīng)常有香客問我泥从,道長,這世上最難降的妖魔是什么沪摄? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任躯嫉,我火速辦了婚禮,結(jié)果婚禮上杨拐,老公的妹妹穿的比我還像新娘祈餐。我一直安慰自己,他們只是感情好哄陶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布帆阳。 她就那樣靜靜地躺著,像睡著了一般屋吨。 火紅的嫁衣襯著肌膚如雪蜒谤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天至扰,我揣著相機(jī)與錄音鳍徽,去河邊找鬼。 笑死敢课,一個(gè)胖子當(dāng)著我的面吹牛阶祭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播直秆,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼濒募,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了圾结?” 一聲冷哼從身側(cè)響起瑰剃,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疫稿,沒想到半個(gè)月后培他,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡遗座,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年舀凛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片途蒋。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡猛遍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情懊烤,我是刑警寧澤梯醒,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站腌紧,受9級(jí)特大地震影響茸习,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜壁肋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一号胚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浸遗,春花似錦猫胁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至髓帽,卻和暖如春菠赚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背氢卡。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來泰國打工锈至, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晨缴,地道東北人译秦。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像击碗,于是被迫代替她去往敵國和親筑悴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356