<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在物件導向程式設計中,一個物件其實也就是一個簡單的值或者一個變數,在這個物件中會包含一些函數,這種帶有接收者的函數,我們稱為方法(method)。本質上,一個方法則是一個和特殊型別關聯的函數。
一個物件導向的程式會用方法來表達其屬性和對應的操作,這樣使用這個物件的使用者就不需要直接去操作物件,而是藉助方法來做這些事情。
在Go語言中,可以給任意自定義型別(包括內建型別,但不包括指標型別)新增相應的方法。
⽅法總是繫結物件範例,並隱式將範例作為第⼀實參 (receiver),方法的語法如下:
func (receiver ReceiverType) funcName (parameters) (results)
type MyInt int//自定義型別,給int改名為MyInt //在函數定義時,在其名字之前放上一個變數,即是一個方法 func (a MyInt) Add(b MyInt) MyInt {//物件導向 return a + b } //傳統方式的定義 func Add(a, b MyInt) MyInt {//程式導向 return a + b } func main() { var a MyInt=1 // a := MyInt(1) 等價 var b MyInt=1 //呼叫func (aMyInt) Add(bMyInt) fmt.Println("a.Add(b)=",a.Add(b))//a.Add(b)=2 //呼叫func Add(a,bMyInt) fmt.Println("Add(a,b)=",Add(a,b))//Add(a,b)=2 }
通過上面的例子可以看出,物件導向只是換了一種語法形式來表達。方法是函數的語法糖,因為receiver其實就是方法所接收的第1個引數。
注意:雖然方法的名字一模一樣,但是如果接收者不一樣,那麼方法就不一樣。
方法裡面可以存取接收者的欄位,呼叫方法通過點(. )存取,就像struct裡面存取欄位一樣:
package main import "fmt" func main(){ jeff:=user{1,"jeff",18,"上海"} fmt.Println(jeff.Add(10)) } // 相當於定義user類 type user struct { id int name string age int addr string } // 新增Add方法,接收引數num func (p user) Add(num int)int{ fmt.Println(p.age) return p.age+num }
package main import "fmt" func main() { //指標作為接收者,參照語意 jeff := Person{"jeff","男",18}//初始化 fmt.Println("函數呼叫前=",jeff)//函數呼叫前= {jeff 男 18} (&jeff).Add() // 生效,(&jeff)拿到jeff的地址(指標) //jeff.Add() // 修改不生效 fmt.Println("函數呼叫後=",jeff)//函數呼叫後= {aaa 女 22} fmt.Println("==========================") chary := Person{"chary","女",18}//初始化 //值作為接收者,值語意 fmt.Println("函數呼叫前=",chary)//函數呼叫前= {chary 女 18} chary.Add2() //不生效 //(&chary).Add() fmt.Println("函數呼叫後=",chary)//函數呼叫後= {chary 女 18} } type Person struct { name string sex string age int } //指標作為接收者,參照語意 func (p *Person) Add(){ //給成員賦值 (*p).name = "aaa" p.sex = "女" p.age = 22 } //值作為接收者,值語意 func (p Person) Add2(){ //給成員賦值 p.name = "bbb" p.sex = "男" p.age = 22 }
型別的方法集是指可以被該型別的值呼叫的所有方法的集合。
用範例範例 value 和 pointer 呼叫方法(含匿名欄位)不受⽅法集約束,編譯器編總是查詢全部方法,並自動轉換 receiver 實參。
一個指向自定義型別的值的指標,它的方法集由該型別定義的所有方法組成,無論這些方法接受的是一個值還是一個指標。
如果在指標上呼叫一個接受值的方法,Go語言會聰明地將該指標解除參照,並將指標所指的底層值作為方法的接收者。
型別 *T ⽅法集包含全部 receiver T + *T ⽅法:
type Person struct{ name string sex byte age int } //指標作為接收者,參照語意 func (p *Person) SetInfoPointer(){ (*p).name="yoyo" p.sex='f' p.age=22 } //值作為接收者,值語意 func (p Person) SetInfoValue(){ p.name="xxx" p.sex='m' p.age=33 } func main() { //p為指標型別 var p*Person = &Person{"mike",'m',18} p.SetInfoPointer() //func (p)SetInfoPointer() p.SetInfoValue() //func (*p)SetInfoValue() (*p).SetInfoValue() //func (*p)SetInfoValue() }
一個自定義型別值的方法集則由為該型別定義的接收者型別為值型別的方法組成,但是不包含那些接收者型別為指標的方法。
但這種限制通常並不像這裡所說的那樣,因為如果我們只有一個值,仍然可以呼叫一個接收者為指標型別的方法,這可以藉助於Go語言傳值的地址能力實現。
type Person struct{ name string sex byte age int } //指標作為接收者,參照語意 func (p *Person) SetInfoPointer(){ (*p).name="yoyo" p.sex='f' p.age=22 } //值作為接收者,值語意 func (p Person)SetInfoValue(){ p.name="xxx" p.sex='m' p.age=33 } func main() { //p為普通值型別 var p Person = Person{"mike",'m',18} (&p).SetInfoPointer() //func(&p)SetInfoPointer() p.SetInfoPointer() //func(&p)SetInfoPointer() p.SetInfoValue() //func(p)SetInfoValue() (&p).SetInfoValue() //func(*&p)SetInfoValue() }
如果匿名欄位實現了一個方法,那麼包含這個匿名欄位的struct也能呼叫該方法。
type Person struct { name string sex byte age int } //Person定義了方法 func (p *Person) PrintInfo() { fmt.Printf("%s,%c,%dn",p.name,p.sex,p.age) } type Student struct { Person//匿名欄位,那麼Student包含了Person的所有欄位 id int addr string } func main() { p := Person{"mike",'m',18} p.PrintInfo() s := Student{Person{"yoyo",'f',20},2,"sz"} s.PrintInfo() }
type Person struct { name string sex byte age int } //Person定義了方法 func (p *Person) PrintInfo() { fmt.Printf("Person:%s,%c,%dn",p.name,p.sex,p.age) } type Student struct { Person//匿名欄位,那麼Student包含了Person的所有欄位 id int addr string } //Student定義了方法 func (s *Student) PrintInfo() { fmt.Printf("Student:%s,%c,%dn",s.name,s.sex,s.age) } func main() { p:=Person{"mike",'m',18} p.PrintInfo() //Person:mike,m,18 s:=Student{Person{"yoyo",'f',20},2,"sz"} s.PrintInfo() //Student:yoyo,f,20 s.Person.PrintInfo() //Person:yoyo,f,20 }
類似於我們可以對函數進行賦值和傳遞一樣,方法也可以進行賦值和傳遞。
根據呼叫者不同,方法分為兩種表現形式:方法值和方法表示式。兩者都可像普通函數那樣賦值和傳參,區別在於方法值繫結範例,⽽方法表示式則須顯式傳參。
type Person struct{ name string sex byte age int } func (p *Person) PrintInfoPointer() { fmt.Printf("%p,%vn",p,p) } func (p Person) PrintInfoValue(){ fmt.Printf("%p,%vn",&p,p) } func main() { p:=Person{"mike",'m',18} p.PrintInfoPointer() //0xc0420023e0,&{mike 109 18} pFunc1:=p.PrintInfoPointer //方法值,隱式傳遞 receiver pFunc1() //0xc0420023e0,&{mike 109 18} pFunc2:=p.PrintInfoValue pFunc2() //0xc042048420,{mike 109 18} }
type Person struct { name string sex byte age int } func (p *Person) PrintInfoPointer() { fmt.Printf("%p,%vn",p,p) } func (p Person) PrintInfoValue() { fmt.Printf("%p,%vn",&p,p) } func main() { p:=Person{"mike",'m',18} p.PrintInfoPointer()//0xc0420023e0,&{mike 109 18} //方法表示式,須顯式傳參 //func pFunc1 (p *Person)) pFunc1:=(*Person).PrintInfoPointer pFunc1(&p) //0xc0420023e0,&{mike 109 18} pFunc2:=Person.PrintInfoValue pFunc2(p) //0xc042002460,{mike 109 18} }
以上就是go語言方法集以及為型別新增方法的範例解析的詳細內容,更多關於go語言方法集型別新增方法的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45