GO是編譯性語言,所以函數的順序是無關緊要的,為了方便閱讀,建議入口函數 main 寫在最前面,其余函數按照功能需要進行排列
成都做網站、成都網站建設,成都做網站公司-創(chuàng)新互聯建站已向上千多家企業(yè)提供了,網站設計,網站制作,網絡營銷等服務!設計與技術結合,多年網站推廣經驗,合理的價格為您打造企業(yè)品質網站。
GO的函數 不支持嵌套,重載和默認參數
GO的函數 支持 無需聲明變量,可變長度,多返回值,匿名,閉包等
GO的函數用 func 來聲明,且左大括號 { 不能另起一行
一個簡單的示例:
輸出為:
參數:可以傳0個或多個值來供自己用
返回:通過用 return 來進行返回
輸出為:
上面就是一個典型的多參數傳遞與多返回值
對例子的說明:
按值傳遞:是對某個變量進行復制,不能更改原變量的值
引用傳遞:相當于按指針傳遞,可以同時改變原來的值,并且消耗的內存會更少,只有4或8個字節(jié)的消耗
在上例中,返回值 (d int, e int, f int) { 是進行了命名,如果不想命名可以寫成 (int,int,int){ ,返回的結果都是一樣的,但要注意:
當返回了多個值,我們某些變量不想要,或實際用不到,我們可以使用 _ 來補位,例如上例的返回我們可以寫成 d,_,f := test(a,b,c) ,我們不想要中間的返回值,可以以這種形式來舍棄掉
在參數后面以 變量 ... type 這種形式的,我們就要以判斷出這是一個可變長度的參數
輸出為:
在上例中, strs ...string 中, strs 的實際值是b,c,d,e,這就是一個最簡單的傳遞可變長度的參數的例子,更多一些演變的形式,都非常類似
在GO中 defer 關鍵字非常重要,相當于面相對像中的析構函數,也就是在某個函數執(zhí)行完成后,GO會自動這個;
如果在多層循環(huán)中函數里,都定義了 defer ,那么它的執(zhí)行順序是先進后出;
當某個函數出現嚴重錯誤時, defer 也會被調用
輸出為
這是一個最簡單的測試了,當然還有更復雜的調用,比如調試程序時,判斷是哪個函數出了問題,完全可以根據 defer 打印出來的內容來進行判斷,非??焖?,這種留給你們去實現
一個函數在函數體內自己調用自己我們稱之為遞歸函數,在做遞歸調用時,經常會將內存給占滿,這是非常要注意的,常用的比如,快速排序就是用的遞歸調用
本篇重點介紹了GO函數(func)的聲明與使用,下一篇將介紹GO的結構 struct
golang定義可變參數的函數方法是:
—- 采用ANSI標準形式時,參數個數可變的函數的原型聲明是:
type funcname(type para1, type para2, …)
—- 這種形式至少需要一個普通的形式參數,后面的省略號不表示省略,而是函數原型的一部分。type是函數返回值和形式參數的類型。
—- 采用與UNIX System V兼容的聲明方式時,參數個數可變的函數原型是:
type funcname(va_alist)
va_dcl
—- 這種形式不需要提供任何普通的形式參數。
type是函數返回值的類型。va_dcl是對函數原型聲明中參數va_alist的詳細聲明,實際是一個宏定義,對不同的硬件平臺采用不同的類型來定義,但在最后都包括了一個分號。因此va_dcl后不再需要加上分號了。va_dcl在代碼中必須原樣給出。va_alist在VC中可以原樣給出,也可以略去。
此外,采用頭文件stdarg.h編寫的程序是符合ANSI標準的,可以在各種操作系統(tǒng)和硬件上運行;而采用頭文件varargs.h的方式僅僅是為了與以前的程序兼容。所以建議使用前者。
1、反射可以在運行時 動態(tài)獲取變量的各種信息 ,比如變量的類型、類別;
2、如果是結構體變量,還可以獲取到結構體本身的信息(包括結構體的字段、方法);
3、通過反射,可以修改 變量的值 ,可以調用關聯的方法;
4、使用反射,需要import " reflect ".
5、示意圖:
1、不知道接口調用哪個函數,根據傳入參數在運行時確定調用的具體接口,這種需要對函數或方法反射。
例如以下這種橋接模式:
示例第一個參數funcPtr以接口的形式傳入函數指針,函數參數args以可變參數的形式傳入,bridge函數中可以用反射來動態(tài)執(zhí)行funcPtr函數。
1、reflect.TypeOf(變量名),獲取變量的類型,返回reflect.Type類型。
2、reflect.ValueOf(變量名),獲取變量的值,返回reflect.Value類型reflect.Value是一個結構體類型。
3、變量、interface{}和reflect.Value是可以互相轉換的,這點在實際開發(fā)中,會經常使用到。
1、reflect.Value.Kind,獲取變量的 類別(Kind) ,返回的是一個 常量 。在go語言文檔中:
示例如下所示:
輸出如下:
Kind的范疇要比Type大。比如有Student和Consumer兩個結構體,他們的 Type 分別是 Student 和 Consumer ,但是它們的 Kind 都是 struct 。
2、Type是類型,Kind是類別,Type和Kind可能是相同的,也可能是不同的。
3、通過反射可以在讓 變量 在 interface{} 和 Reflect.Value 之間相互轉換,這點在前面畫過示意圖。
4、使用反射的方式來獲取變量的值(并返回對應的類型),要求數據類型匹配,比如x是int,那么久應該使用reflect.Value(x).Int(),而不能使用其它的,否則報panic。
如果是x是float類型的話,也是要用reflect.Value(x).Float()。但是如果是struct類型的話,由于type并不確定,所以沒有相應的方法,只能 斷言。
5、通過反射的來修改變量,注意當使用SetXxx方法來設置需要通過對應的指針類型來完成,這樣才能改變傳入的變量的值,同時需要使用到reflect.Value.Elem()方法。
輸出num=20,即成功使用反射來修改傳進來變量的值。
6、reflect.Value.Elem()應該如何理解?