轉:原文:https://blog.csdn.net/qq_34777600/article/details/81026589
接觸到go之前,我認為函數和方法只是同一個東西的兩個名字而已。但是在go中是兩個不同的東西。
官方解釋:一個方法就是一個包含了接收者的函數。接收者可以是命名類型或者結構體類型的一個值或者是一個指針。所有給定類型的方法屬於該類型的方法集。
區別:
對於普通函數:接收者(函數參數)為值類型時,不能將指針類型的數據直接傳遞,反之亦然。
func function_name([parameter list]) [return_types] {
函數體
}
對於方法(如struct方法): 接收者為值類型時,可以直接用指針類型的變量調用方法,反之亦然。
func (variable_name variable_data_type) function_name() [return_type]{
/* 函數體*/
}
可以看到方法和函數的區別,方法在func關鍵字后是接收者而不是函數名,接收者可以是自己定義的一個類型,這個類型可以是struct,interface,甚至我們可以重定義基本數據類型。
Go函數
函數是基本的代碼塊,用於執行一個任務。
Go 語言最少有個 main() 函數。
你可以通過函數來划分不同功能,邏輯上每個函數執行的是指定的任務。
函數聲明告訴了編譯器函數的名稱,返回類型,和參數。
Go 函數可以返回多個值。
Go 語言標准庫提供了多種可動用的內置的函數。例如,len() 函數可以接受不同類型參數並返回該類型的長度。如果我們傳入 的是字符串則返回字符串的長度,如果傳入的是數組,則返回數組中包含的元素個數。
值傳遞:值傳遞是指在調用函數時將實際參數復制一份傳遞到函數中,這樣在函數中如果對參數進行修改,將不會影響到實際參數。
引用傳遞:引用傳遞是指在調用函數時將實際參數的地址傳遞到函數中,那么在函數中對參數所進行的修改,將影響到實際參數。
Go方法
Go 語言中同時有函數和方法。一個方法就是一個包含了接受者的函數,接受者可以是命名類型或者結構體類型的一個值或者是一個指針。所有給定類型的方法屬於該類型的方法集。
下面定義一個結構體類型和該類型的一個方法:
package main
import (
"fmt"
)
/* 定義結構體 */
type Circle struct {
radius float64
}
func main() {
var c1 Circle
c1.radius = 10.00
fmt.Println("Area of Circle(c1) = ", c1.getArea())
}
//該 method 屬於 Circle 類型對象中的方法
func (c Circle) getArea() float64 {
//c.radius 即為 Circle 類型對象中的屬性
return 3.14 * c.radius * c.radius
}
以上代碼執行結果為:
Area of Circle(c1) = 314
例子
package structTest
//普通函數與方法的區別(在接收者分別為值類型和指針類型的時候)
//Date:2014-4-3 10:00:07
import (
"fmt"
)
func StructTest06Base() {
structTest0601()
structTest0602()
}
//1.普通函數
//接收值類型參數的函數
func valueIntTest(a int) int {
return a + 10
}
//接收指針類型參數的函數
func pointerIntTest(a *int) int {
return *a + 10
}
func structTest0601() {
a := 2
fmt.Println("valueIntTest:", valueIntTest(a))
//函數的參數為值類型,則不能直接將指針作為參數傳遞
//fmt.Println("valueIntTest:", valueIntTest(&a))
//compile error: cannot use &a (type *int) as type int in function argument
b := 5
fmt.Println("pointerIntTest:", pointerIntTest(&b))
//同樣,當函數的參數為指針類型時,也不能直接將值類型作為參數傳遞
//fmt.Println("pointerIntTest:", pointerIntTest(b))
//compile error:cannot use b (type int) as type *int in function argument
}
//2.方法
type PersonD struct {
id int
name string
}
//接收者為值類型
func (p PersonD) valueShowName() {
fmt.Println(p.name)
}
//接收者為指針類型
func (p *PersonD) pointShowName() {
fmt.Println(p.name)
}
func structTest0602() {
//值類型調用方法
personValue := PersonD{101, "Will Smith"}
personValue.valueShowName()
personValue.pointShowName()
//指針類型調用方法
personPointer := &PersonD{102, "Paul Tony"}
personPointer.valueShowName()
personPointer.pointShowName()
//與普通函數不同,接收者為指針類型和值類型的方法,指針類型和值類型的變量均可相互調用
}
---------------------
來源:CSDN
原文:https://blog.csdn.net/qq_34777600/article/details/81026589