新聞中心
淺談Go語言函數與方法的區(qū)別
前段時間,我們實驗室用go作為后臺開發(fā)語言開發(fā)了一個web項目,由于這是自己第一次使用go語言進行開發(fā),在開發(fā)過程中,一味著追求完成任務,在編碼的時候沒有太注重性能,雖然勉強實現了功能,但是對go語言的理解還是比較淺顯的。下面來談談自己對go語言中函數與方法的理解。
創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供竹溪網站建設、竹溪做網站、竹溪網站設計、竹溪網站制作等企業(yè)網站建設、網頁設計與制作、竹溪企業(yè)網站模板建站服務,十載竹溪做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。
普通函數:
go函數可以返回多個值
值傳遞: 值傳遞是指在調用函數時將實際參數復制一份傳遞到函數中,這樣函數中如果對參數進行修改,將不會影響到實際參數
引用傳遞: 引用傳遞是指在調用函數將實際參數的地址傳遞到函數中,那么在函數中對參數進行的修改,將影響到實際參數。
一般來說go語言函數的 接收者(也就是形參)一般放在函數名后面 ,不能將指針類型的數據直接傳遞,也就是說函數形參如果是值類型,調用者必須使用值作為實參過來,如果函數形參是指針類型,則函數調用者需使用指針作為實參來調用。
普通方法:
接收者是在func關鍵字后面,而不是在函數名稱后面,接收者可以是自己定義的一個類型,這個類型可以是struct、interface,一個方法就是一個包含了接收者的函數,接收者可以是命名類型或者是結構體類型的一個值或者是一個指針。
下面是一個例子來說明方法和函數的區(qū)別(重點)
golang 內置函數new 和struct 初始化的區(qū)別
在go語言中 new() 這是一個用來分配內存的內置函數,它的第一個參數是一個類型,不是一個值,它的返回值是一個指向新分配的 t 類型的零值的指針。 在golang的代碼定義如下: func new(t Type) *Type strut{} 直接使用struct{} 來初始化strut時,返回的是一個struct類型的值,而不是指針兩者是不一樣的 兩者對比代碼如下: type Student struct{ id int name string } func main(){ var s_1 *Student = new(Student) s_1.id = 100 s_1.name = "cat" var s_2 Student = Student{id:1,name:"tom"} fmt.Println(s_1,s_2) } 輸出結果: {100 cat} {1 tom} 從上面代碼的聲明和打印的結果中就可以看出 s_1 的類型為指針,s_2 為一個Student類型
GO語言學習系列八——GO函數(func)的聲明與使用
GO是編譯性語言,所以函數的順序是無關緊要的,為了方便閱讀,建議入口函數 main 寫在最前面,其余函數按照功能需要進行排列
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
怎么樣使用Go語言中函數的參數傳遞與調用
按值傳遞函數參數,是拷貝參數的實際值到函數的形式參數的方法調用。在這種情況下,參數在函數內變化對參數不會有影響。
默認情況下,Go編程語言使用調用通過值的方法來傳遞參數。在一般情況下,這意味著,在函數內碼不能改變用來調用所述函數的參數。考慮函數swap()的定義如下。
代碼如下:
/* function definition to swap the values */
func swap(int x, int y) int {
var temp int
temp = x /* save the value of x */
x = y /* put y into x */
y = temp /* put temp into y */
return temp;
}
現在,讓我們通過使實際值作為在以下示例調用函數swap():
代碼如下:
package main
import "fmt"
func main() {
/* local variable definition */
var a int = 100
var b int = 200
fmt.Printf("Before swap, value of a : %d\n", a )
fmt.Printf("Before swap, value of b : %d\n", b )
/* calling a function to swap the values */
swap(a, b)
fmt.Printf("After swap, value of a : %d\n", a )
fmt.Printf("After swap, value of b : %d\n", b )
}
func swap(x, y int) int {
var temp int
temp = x /* save the value of x */
x = y /* put y into x */
y = temp /* put temp into y */
return temp;
}
讓我們把上面的代碼放在一個C文件,編譯并執(zhí)行它,它會產生以下結果:
Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :100
After swap, value of b :200
這表明,參數值沒有被改變,雖然它們已經在函數內部改變。
通過傳遞函數參數,即是拷貝參數的地址到形式參數的參考方法調用。在函數內部,地址是訪問調用中使用的實際參數。這意味著,對參數的更改會影響傳遞的參數。
要通過引用傳遞的值,參數的指針被傳遞給函數就像任何其他的值。所以,相應的,需要聲明函數的參數為指針類型如下面的函數swap(),它的交換兩個整型變量的值指向它的參數。
代碼如下:
/* function definition to swap the values */
func swap(x *int, y *int) {
var temp int
temp = *x /* save the value at address x */
*x = *y /* put y into x */
*y = temp /* put temp into y */
}
現在,讓我們調用函數swap()通過引用作為在下面的示例中傳遞數值:
代碼如下:
package main
import "fmt"
func main() {
/* local variable definition */
var a int = 100
var b int= 200
fmt.Printf("Before swap, value of a : %d\n", a )
fmt.Printf("Before swap, value of b : %d\n", b )
/* calling a function to swap the values.
* a indicates pointer to a ie. address of variable a and
* b indicates pointer to b ie. address of variable b.
*/
swap(a, b)
fmt.Printf("After swap, value of a : %d\n", a )
fmt.Printf("After swap, value of b : %d\n", b )
}
func swap(x *int, y *int) {
var temp int
temp = *x /* save the value at address x */
*x = *y /* put y into x */
*y = temp /* put temp into y */
}
讓我們把上面的代碼放在一個C文件,編譯并執(zhí)行它,它會產生以下結果:
Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :200
After swap, value of b :100
這表明變化的功能以及不同于通過值調用的外部體現的改變不能反映函數之外。
Go語言中new和 make的區(qū)別詳解
1、new 的主要特性
首先 new 是內建函數,定義也很簡單:
func new(Type) *Type
內建函數 new 用來分配內存,第一個參數是一個類型,不是一個值,返回值是一個指向新分配類型零值的指針
實現一個類似 new 的功能:
func newInt() *int {
var i int
return i
}
someInt := newInt()
函數的功能跟 someInt := new(int) 一模一樣。定義 new 開頭的函數時,出于約定也應該返回類型的指針。
2、make 的主要特性
make 也是內建函數,定義比 new 多了一個參數,返回值也不同:
func make(Type, size IntegerType) Type
內建函數 make 用來為 slice,map 或 chan 類型分配內存和初始化一個對象(注意:只能用在這三種類型上),跟 new 類似,第一個參數也是一個類型而不是一個值,跟 new 不同的是,make 返回類型的引用而不是指針,而返回值也依賴于具體傳入的類型,具體說明如下:
Slice: 第二個參數 size 指定了長度,容量和長度相同。
可以傳入第三個參數來指定不同的容量值,但必須不能比長度值小。
比如 make([]int, 0, 10)
Map: 根據 size 大小來初始化分配內存,不過分配后的 map 長度為 0,如果 size 被忽略了,那么會在初始化分配內存時分配一個小尺寸的內存
Channel: 管道緩沖區(qū)依據緩沖區(qū)容量被初始化。如果容量為 0 或者忽略容量,管道沒有緩沖區(qū)。
3、總結
new 的作用是初始化一個指向類型的指針(*T),make 的作用是為 slice,map 或 chan 初始化并返回引用(T)。
網站題目:go語言函數內函數 go 語言語法
URL網址:http://www.ef60e0e.cn/article/hidchd.html