<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] >[success]## **一、 函數介紹** >[info]### 1.1 定義 函數:有輸入、有輸出,用來執行一個指定任務的代碼塊。 ~~~ func functionname([parametername type]) [return type] { //function body } //其中參數列表和返回值列表都是可選的 ~~~ 解釋: ~~~ func 函數名([參數名 類型])[返回值 類型] { 函數體 } ~~~ <br> <br> >[info]### **1.2 特點** golang函數的特點: 1)不支持重載,即一個包不能有兩個名字一樣的函數 2)函數也是一種類型,一個函數可以賦值給變量 3)匿名函數 4)多返回值 >[info]### **1.3 return函數** :-: ![](https://img.kancloud.cn/b5/7a/b57ad89ff4596829bdcfd2e07cb75d07_415x102.png) <br> >[]#### **多返回值** 返回多個值時要用括號包起來 ~~~ package main import "fmt" func test(num1,num2 int) (int,int){ res1 := num1 + num2 res2 := num1 - num2 return res1,res2 } func main(){ a,b := test(20,10) fmt.Printf("a = %v\nb = %v",a,b) } ~~~ **運行結果** `a = 30` `b = 10` <br> <br> >[]#### **只接受一個返回值(_)來忽略** ~~~ package main import "fmt" func test(num1,num2 int) (int,int){ res1 := num1 + num2 res2 := num1 - num2 return res1,res2 } func main(){ a,_ := test(20,10) fmt.Printf("a = %v\nb = %v",a) } ~~~ **運行結果** a = 30 b = %!v(MISSING) <br> <br> >[info]## **二、函數遞歸調用** 說名:函數體內又調用了本身,稱之為遞歸調用 ~~~ package main func test(n int){ if n > 2{ n-- test(n) } } func main(){ test(4) } ~~~ ~~~ package main import "fmt" func test(n int){ if n > 2{ n-- test(n) }else{ fmt.Println("n = ",n) } } func main(){ test(4) } ~~~ <br> >[success]### **2.1 遞歸調用的原則** 1)執行一個函數時,就創建一個新的受保護的獨立空間(新函數棧) 2)函數的局部變量是獨立的,不會相互影響 3)遞歸必須向退出遞歸的條件逼近,否則就是無限遞歸,死龜了:) 4)當一個函數執行完畢,或者遇到return,就會返回,遵守誰調用,就將結果返回 給誰,同時當函數執行完畢或者返回時,該函數本身也會被系統銷毀 >[success]## **三、init函數** >[info] ### **3.1 基本介紹** 每一個包都有一個init函數,該函數在main函數之前執行, >[info] ### **3.2 案例演示** ~~~ package main import "fmt" func init(){ fmt.Println("init") } func main(){ fmt.Println("main") } ~~~ **運行結果** **init** **main** >[warning] ### **注意事項** 1)go中在當前文件中的執行順序,全局變量 ?---> init函數----> main函數 代碼如下: ~~~ package main import "fmt" var sum = test() func test() int{ fmt.Println("test()") return 100 } func init(){ fmt.Println("init") } func main(){ fmt.Println("main") } ~~~ **運行結果** **test()** **init** **main** <br> 2)如果引入其他文件的全局變量和init函數,那么執行順序如下: :-: ![](https://img.kancloud.cn/bf/b0/bfb0e65edf3e26d5b34eb5f9abfd59b7_344x130.png) <br> <br> >[success]## **四、匿名函數** >[info]### **4.1 基本介紹** Go支持匿名函數,匿名函數就是沒有名字的函數,如果我們某個函數只是希望使用一次,可以考慮使用匿名函數,匿名函數也可以實現多次調用。 >[info] ### **4.2 匿名函數使用方式** 1)匿名函數使用方式1 在定義匿名函數時就直接調用,[案例演示] ~~~ package main import "fmt" func main(){ res := func(n,m int) int{ return n + m }(10,20) // 這里是直接調用 fmt.Println(res) } ~~~ 2)匿名函數使用方式2 將匿名函數賦給一一個變量(函數變量),再通過該變量來調用匿名函數 此時匿名函數`func(n3 int , n4 int) int 賦值給了res` res的數據類型是一個函數類型,通過調用ret來完成調用 【案例演示】 ~~~ package main import "fmt" func main(){ res := func(n,m int) int{ return n + m } sum := res(100,200) fmt.Println("sum = ",sum) sum1 := res(30,20) fmt.Println("sum1 = ",sum1) } ~~~ **運行結果** `sum = 300` `sum1 = 50` <br> <br> 全局匿名函數 如果將匿名函數賦給一個全局變量,那么這個匿名函數,就成為一個全局匿名函數,可以在程序有效。[案例演示] ~~~ package main import "fmt" var ( res = func(n,m int) int{ return n + m } ) func main(){ ret := res(200,200) fmt.Println(ret) } ~~~ **運行結果** 400 <br> <br> >[success]## **五、閉包** >[info]### **5.1閉包介紹:** 閉包就是一個函數與其相關的引用環境,組合成一個整體 >[info]### **5.2** **strings 和 strconv 包** >[info]### **5.3案例演練:** ~~~ package main import "fmt" func Addper()func(int)int{ var sum = 10 return func(i int) int { fmt.Printf("匿名函數接收到了%v\n",i) sum = sum + i return sum } } func main(){ f := Addper() fmt.Println(f(1)) fmt.Println(f(10)) fmt.Println(f(100)) } ~~~ **運行結果** 匿名函數接收到了1 11 匿名函數接收到了10 21 匿名函數接收到了100 121 <br> 返回的是一個匿名函數。但是這個匿名函數引用到函數外的i .因此這個匿名函數就和i形成一個整體,構成閉包。(第6行到10行就是閉包) 1)大家可以這樣理解:閉包是類.函數是操作,i是字段。函數和它使用到n構成閉包。 2)當我們反復的調用f函數時,因為i是初始化一次,因此每調用一次就進行累計。 3)我們要搞清楚閉包的關鍵,就是要分析出返回的函數它使用(引用)到哪些變量,因為函數和它引用到的變量共同構成閉包。 <br> <br> >[info]### **5.4閉包的最佳實踐** 請編寫一個程序,具體要求如下 1)編寫一個函數makefuffix(suffix string)可以接收一個文件后綴名(比如.jpg),并回一個閉包 2)調用閉包,可以傳入一個文件名,如果該文件名沒有指定的后綴(比如.jpg) ,則返 3)回文件名.jpg,如果已經有.jpg后綴,則返回原文件名。要求使用閉包的方式完成 4)strings.HasSuffix(判斷后綴名) func [HasSuffix](https://github.com/golang/go/blob/master/src/strings/strings.go?name=release#376 "View Source")[](https://studygolang.com/static/pkgdoc/pkg/strings.htm#pkg-index) ~~~ package main import ( "fmt" "strings" ) func MaKeSuffix(suffix string)func(string)string{ return func(name string) string { if !strings.HasSuffix(name,suffix){ return name + suffix } return name } } func main(){ res := MaKeSuffix(".jpg") fmt.Println(res("witer")) fmt.Println(res("f")) fmt.Println(res("image")) } ~~~ **運行結果** witer.jpg f.jpg image.jpg <br> <br> >[success]## **六、函數 defer** >[info]### **6.1 基本介紹** 在函數中,程序員經常需要創建資源(比如:數據庫連接、文件句柄、鎖等),為了在函數執行完畢后,及時的釋放資源,Go的設計者提供defer (延時機制) >[info]### **6.2 案例演示** ~~~ package main import "fmt" func test(n,m int)int{ defer fmt.Println("n",n) defer fmt.Println("m",m) res := n + m fmt.Println("res = ",res) return res } func main(){ f := test(10,20) fmt.Println(f) } ~~~ **運行結果** res = 30 m 20 n 10 30 <br> <br> >[info]### **defer細節** 1)當go執行到一個defer時, 不會立即執行defer后的語句,而是將defer后的語句壓入到一個棧中【我為了方便,暫時稱該棧為defer棧】然后繼續執行函數下一個語句 2)當函數執行完畢后,在從defer棧中,依次從棧頂取出語句執行(注:遵守棧先入后出的機制),所以同學們看到前面案例輸出的順序。 3)在defer 將語句放入到棧時,也會將相關的值拷貝同時入棧。請看一段代碼: 4)在golang編程中的通常做法是,創建資源后,比如(打開了文件,獲取了數據庫的鏈接,或者是鎖資源),可以執行 `defer file.Close() defer connect .CloseO ` 5)在defer后,可以繼續使用創建資源 6)當函數完畢后,系統會依次從defer棧中,取出語句,關閉資源三造, 7)這種機制,非常簡潔,程序員不用再為在什么時機關閉資源而煩心。 <br> <br> >[success]## **七、函數參數的傳遞方式** :-: ![](https://img.kancloud.cn/05/7d/057d75729c7e428da2f0918f57a30ffa_500x302.png) >[info]### **7.1 基本介紹** 我們在講解函數注意事項和使用細節時,已經講過值類型和引用類型了,這里 我們再系統總結一下,因為這是重難點,**值類型參數默認就是值傳遞**,而引用類型 **參數默認就是引用傳遞。** 兩種傳遞方式 1)值傳遞 2)引用傳遞 其實,不管是值傳遞還是引用傳遞,傳遞給函數的都是變量的副本,不同的是,值傳遞的是值的拷貝,引用傳遞的是地址的拷貝,一般來說,**地址拷貝效率高**,因為數據量小,而值拷貝訣定拷貝的數據大小,數據越大,效率越低。 >[info]### **7.2 值類型和引用類型** 1)值類型: 基本數據類型int系列, float系列, bool, string、數組和結構體struct 2)引用類型: 指針、slice切片、 map、管道chan、interface 等都是引用類型 &emsp;&emsp;&emsp;&emsp;●函數參數的傳遞方式 &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;1)值類型默認是值傳遞: 變量直接存儲值,內存通常在棧中分配[案例:畫出示意圖] :-: ![](https://img.kancloud.cn/bf/15/bf1528a7d599abf1cabf56a268debdc7_294x95.png) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;2)引用類型默認是引用傳遞:變量存儲的是一個地址,這個地址對應的空間才真正存儲數據(值),內存通常在堆上分配,當沒有任何變量引用這個地址時,該地址對應的數據空間就成為一個垃圾,由GC來回收。[案例, 并畫出示意圖] :-: ![](https://img.kancloud.cn/25/6a/256a998eda076ec5b8d54a77afcf876d_326x92.png) >[success]## **八、變量的作用域** >[info] ### 基本介紹 1)函數內部聲明/定義的變量叫局部變量,作用域僅限于函數內部。 2)函數外部聲明/定義的變量叫全局變量,作用域在整個包都有效,如果其首字母為大寫,則作用域在整個程序有效。 ~~~ package main import "fmt" var( age = 23 Name = "Boy" ) func test(){ age := 18 Name := "jack" fmt.Printf("age = %v\nName = %v",age,Name) } func main(){ fmt.Println(age) fmt.Println(Name) test() } ~~~ **運行結果** 23 Boy age = 18 Name = jack 1)如果變量是在一個代碼塊,比如for/if中, 那么這個變量的的作用域就在該代碼塊 **練習題** 如下代碼,會報錯 :-: ![](https://img.kancloud.cn/51/ea/51ea5598415666d5f99c9cdf6980b2d5_298x74.png) **函數的練習** 1)在終端輸入一個整數,打印出相應的金字塔 :-: ![](https://img.kancloud.cn/f9/96/f9962feaa745a59e1899a1a6f2ae3d9a_296x213.png) >[success]## **九、string常用的函數** 說明:字符串在我們程序開發中,使用的是非常多的,常用的函數需要掌握[帶看手冊或者官方編程指南]: >[info]**9,1 統計字符串的長度** 按字節len(str)-----(len是按照字節遍歷,并非按照字符) ~~~ func main(){ c := "hello" fmt.Println(len(c)) } ~~~ >[info]**9.2 字符串遍歷** 同時處理有中文的問題r:= **[ ]rune(str)**,;例如遍歷 a:=“hallo北京” ~~~ package main import "fmt" func main(){ c := "hello北京" res := []rune(c) for i := 1;i < len(res);i++{ fmt.Printf("hello北京的長度是:%c\n",res[i]) } } ~~~ >[info]**9.3 字符串轉整數**: n, err := strconv.Atoi("12") ~~~ package main import ( "fmt" "strconv" ) func main(){ sum := "12345" re,err := strconv.Atoi(sum) if err != nil{ fmt.Println("轉換錯誤",err) }else{ fmt.Println("轉換成功",re) } } ~~~ >[info]**9.4 整數轉字符串**? str = strconv.Itoa(12345) ~~~ package main import ( "fmt" "strconv" ) func main(){ sum := 123456 str := strconv.Itoa(sum) fmt.Printf("str value is【%v】\nstr type is【%T】",str,str) } ~~~ **運行結果** str value is【123456】 str type is【string】 >[info] **9.5 字符串轉[]byte** var bytes = [ ]byte("hello go") ~~~ package main import ( "fmt" ) func main(){ sum := []byte("hello") fmt.Println(sum) } ~~~ **運行結果** `[104 101 108 108 111]` >[info] **9.6 []byte 轉字符串:** **`str = string( [ ]byte{97, 98, 99})`** ~~~ package main import ( "fmt" ) func main(){ sum := string([]byte{97, 98, 99}) fmt.Printf("sum value %v\nsum type is %T",sum,sum) } ~~~ **運行結果** **sum value abc** **sum type is string**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看