方法使用的注意事项和细节

柯帆 · · 282 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1、结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式。

2、如果程序员希望在方法中,修改结构体的值,可以通过结构体指针的方式来处理。

3、Golang中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct,比如int,float32等都可以有方法。


给系统类型int添加方法myprint
用int对象a1执行方法myprint()
报错

报错表明不能给int、float32这种non-local type人为添加方法,否则无法执行。我们只需把int类型换成别名比如myint,系统就认为是自定义类型,那么这样就可以执行了,如下所示:

type myint int
定义myint的对象a1
正常输出


4、方法的调用范围控制的规则,和函数一样,方法名首字母小写,只能在本包访问;方法名首字母大写,可以在本包和其他包访问。

5、如果一个类型实现了String()的这个方法,那么fmt.Println默认会调用这个变量String()进行输出。

有示例如下:

给结构体定义String()方法

这里给Student结构体定义了一个String()方法,这会影响到println(结构体实例的输出)。此外,要介绍下Printf和Sprintf的区别:

Printf : 只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整形变量和整形。

Sprintf:用传入的格式化规则符将传入的变量格式化,(终端中不会有显示),返回为 格式化后的字符串。

下面我们执行以下代码:

main函数的代码

发现输出为:

输出

说明在执行fmt.Println(student)时,调用了我们自己定义的String()方法,故有了上面的输出。若我们将String()方法注释掉,如下图:

注释掉String()方法

发现输出为:

输出

这里因为我们注释掉了String(),故调用的是原来的fmt.Println()。


6、方法执行时编译器的优化

如下图所示,我们给Student结构体定义了一个edit()的方法,定义中调用它的对象是Student类型,因此main函数中,我们用的student.edit()。

示例1

输出如下:

输出1

毫无疑问,由于edit()方法是值传递,edit()方法内部给Student对象的age重新复制未能生效。而当我们对上面代码做如下修改后:

示例2

这里我们方法接收的对象是*Student,是一个指针,由此可推断这个引用传递的方法执行后可以让Student对象中的age变为40。而我们在main()函数中的调用依旧是student.edit(),此时还能输出我们想要的值吗?

输出2

答案是肯定的。其实这里,编译器在底层做了优化,按照最科学的写法,应该是需要这要调用的:

最科学的调用

因为edit()方法的调用对象是*Student,我们本应传入一个Student对象的指针即(&student)进去,但是由于编译器做了语法糖优化,不用传入指针变量也能被识别。同理,如果edit()方法传值,我们在main()函数中却用的指针调用,也是可以被识别的。只不过最终Student对象中的age值能否被修改,取决于edit()方法是传值还是传引用,而与你在main()函数中调用时传入的是何种参数无关。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:柯帆

查看原文:方法使用的注意事项和细节

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

282 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传