教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Golang-对象方法和实现接口时,方法接受者是指针还是对象的区别

Golang-对象方法和实现接口时,方法接受者是指针还是对象的区别

发布时间:2022-01-19   编辑:jiaochengji.com
教程集为您提供Golang-对象方法和实现接口时,方法接受者是指针还是对象的区别等资源,欢迎您收藏本站,我们将为您提供最新的Golang-对象方法和实现接口时,方法接受者是指针还是对象的区别资源
<h3>方法格式</h3>

golang和java的对象方法实现上有很大的区别,在golang中,一个对象的方法定义如下

<pre class="has"><code class="language-Go">func (o Object) FuncName(args...) (results...){}</code></pre>

其中 o 代表的是函数的接受体,意思是这个函数属于对象 o 的方法。

args 表示形参列表。

results 表示函数返回值列表,对于无返回值的方法可以为空,和java void方法一样

<h3>方法接受体 o 实例和指针的区别</h3>

注意看以下方法的接受体,一个是实例,一个是指针

<pre class="has"><code class="language-Go">type FragmentImpl struct { i int } func (f FragmentImpl) Exec() { fmt.Printf("%p\n", &f) f.i = 10 } func (f *FragmentImpl) Exec2() { fmt.Printf("%p\n", f) f.i = 10 } func main() { fragment := FragmentImpl{1} fmt.Printf("%p -- %v \n", &fragment,fragment) fragment.Exec() fmt.Printf("%p -- %v \n", &fragment,fragment) (&fragment).Exec() fmt.Printf("%p -- %v \n", &fragment,fragment) fmt.Println("----------------------------") fragment2 := &FragmentImpl{1} fmt.Printf("%p -- %v \n", fragment2,fragment2) fragment2.Exec2() fmt.Printf("%p -- %v \n", fragment2,fragment2) (*fragment2).Exec2() fmt.Printf("%p -- %v \n", fragment2,fragment2) } OUT: 0xc042060080 -- {1} 0xc0420600b0 0xc042060080 -- {1} 0xc0420600c0 0xc042060080 -- {1} ---------------------------- 0xc0420600d0 -- &{1} 0xc0420600d0 0xc0420600d0 -- &{10} 0xc0420600d0 0xc0420600d0 -- &{10} </code></pre>

可以看出,对于Exec(),虽然方法接受体是实例,但是不管FragmentImpl的实例还是实例的地址指针都能够调用成功,但是不管以何种形式调用,都会产生值复制(地址不同),不会对原始对象的属性产生更改。

对于Exec2(),方法的接受体是结构体指针,同样的也可以用实例或者指针去调用,而且能够对原始对象产生修改行为。

所以,在golong中,会不会产生值复制,关键在于方法的接受体是对象还是指针,而不是调用方法的类型,因为golang会自动解引用。不过我觉得,即使以*T指针的形式调用方法,实际上也是会产生复制的,不过此时复制的是指针这个“值”,所以在方法中可以通过访问指针修改原生的值。

<h3>接口的实现</h3>

golang中接口的实现比较奇怪,实现类不需要像java一样通过implments显示指定实现的接口类,只需要包含和接口一样的函数,就认为这个结构体实现了接口。

<pre class="has"><code class="language-Go">type Fragment interface { Exec() } type FragmentImp struct { i int } func (f *FragmentImp) Exec() { fmt.Printf("%p\n", f) f.i = 10 } type FragmentImp2 struct { i int } func (f FragmentImp2) Exec() { fmt.Printf("%p\n", f) f.i = 10 } func main() { //var f Fragment = FragmentImp{1} //Exec method has pointer receiver //f.Exec() var f2 Fragment = &FragmentImp{1} f2.Exec() var f3 Fragment = &FragmentImp2{1} f3.Exec() var f4 Fragment = FragmentImp2{1} f4.Exec() } </code></pre>

只要 funcName,args...,results...和interface一样,就认为结构体实现了接口,不管方法的接受体是实例还是指针,不过需要注意的是,如果实现接口的是指针,那么不能把结构体实例值 赋值给接口。

到此这篇关于“Golang-对象方法和实现接口时,方法接受者是指针还是对象的区别”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Golang-对象方法和实现接口时,方法接受者是指针还是对象的区别
Go学习笔记:接口实现与指针
Golang接口 interface 和结构体struct
Go结构体继承指针和非指针区别(转换接口)
golang之interface底层原理
浅谈golang中的接口
go struct 成员变量后面再加个字符串是什么意思?_Go语言的学习笔记(第十章) 接口...
Golang | Go语言多态的实现与interface使用
golang接口使用说明与经典案例
Go语言编程之面向“对象”编程篇

[关闭]
~ ~