方法使用的深度剖析(1)|学习笔记

简介: 快速学习方法使用的深度剖析(1)

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:方法使用的深度剖析(1)】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/626/detail/9678


方法使用的深度剖析(1)

 

内容介绍:

一、方法的声明(定义)

二、方法注意事项和细节讨论(1)

三、方法注意事项和细节讨论(2)

 

一、方法的声明(定义)

1、语法:

func (recevier type) methodName(参数列表)(返回值列表){

方法体

return返回值}

关键词 func 后的括号用来确定方法与何种数据类型完成绑定。receiver 是 type 类型的一个变量,比如:Person结构体的一个变量;methodName是方法的名字,根据前面所讲的标识符的命名规则来写;参数列表类似于函数的形参列表,表示方法输入;返回值列表,方法如果有返回值,返回值就会写入返回值列表中;方法体表示该方法要完成的任务是什么,比如输入 return 表示返回值。recevier type:表示该方法和 type 类型进行绑定,或者说该方法作用于 type 类型,type 可以是结构体,也可以其它的自定义类型;返回值列表表示返回的值,可以是多个;方法主体:表示为了实现某一功能代码块;return 语句不是必须的。

2、具体说明:

1)参数列表

表示方法输入,有什么输入就在参数列表中写清楚。比如前面所举的例子,得到两个数的和,n1和n2就是输入的参数。

2) recevier type

表示这个方法和 type 这个类型进行绑定,或者说该方法作用于 type 类型,当然type 的类型根据实际情况而定。例如前面所讲的 person,或者是 student,就表示方法分别与 person、student 进行绑定。

3) receiver type

type 可以是结构体,也可以其它的普通自定义类型。例如 type integer int,也可以给 integer 进行绑定方法

4) Receiver

Receiver就是 type 类型的一个变量(实例),如果是结构体变量,有些程序员还是习惯于称作实例。比如:Person 结构体的一个变量(实例)

5) 返回值列表

表示返回的值,可以是多个

6) 方法主体

表示为了实现某一功能的代码块,根据实际需求来写,可以实现计算、连接数据库、添加数据等功能。

7) return 语句

Return 语句不是必预的,如果没有 return 语句,返回值列表也就不存在了;反之,如果有返回值列表,那么 return 语句一定存在。

 

二、方法注意事项和细节讨论(1)

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

该注意事项在之前的内容中已经做了详细的解释和说明,因此在此不再进行赘述了。

 

三、方法注意事项和细节讨论(2)

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

实际上,更多的是绑定结构体指针类型,而不是结构体本身,因为这样可以提高传输的速度、效率。如果是结构体类型的绑定,在传输的时候,进行值的拷贝;而如果是与结构体的指针进行绑定,拷贝的时候只进行地址的拷贝

举例说明:指针类型,而不是结构体

func (c *circle)area2() f1oat64 {

c.radius =10

return 3.14*(*c).radius*(*c).radius

)

方法与 circle 绑定时,需要完成值的拷贝,效率比较低。因此为了提高效率,通常会将方法与结构体的指针类型绑定,此时传入的是地址。因为c是指针,因此访问字段的标准方式是(*c).radius,(*c).radius 等价于 c.radius,因此可以输入为 return 3.14* c.radius*c.radius

进行调用时,首先创建一个circle的变量,传入数值7,标准调用方式如下:

var c circle

c.radius =5.0

res2 :=(&c). area()

fmt.Print1n("面积=",res2)

因为是c指针,所有在调用时,需要添加一个&,同样的道理,在取值的时候,要对值进行加*处理。但是这种调用方式比较麻烦,因此编译器底层做了优化,会自动的给变量添加上&,从而实现了 c.area() 等价为 (&c).area2()。调用代码可以写作:

var c circle

c.radius =5.0

res2 :=c. area()

fmt.Print1n("面积=",res2)

可以更改变量值检验上述的等价操作是否正确,将传入值7.0改为6.0后,运行查看效果,输入 cd.exercise go run main.go,可以看到输出的结果由78.5变成了113.83999……,值发生了改变,与理论值效果一致。虽然两种调用方式都可以得到正确的返回值,但是两者的机制完全不同。如果写作 c.radius=10,外侧c的值通过 fmt.Println(c.radius=",c.radius)查看有没有发生变化,运行后发现c的值变成了10,因为在进行传输的时候是指针类型,此时c拷贝的不是所有的内容,只是拷贝了地址,因此指针直接指向了 main 函数中的c,所以在函数里对函数进行修改,外侧的值也会发生改变

内存分析图

image.png

说明分析

主函数即代表了一个主栈,它是一个独立的数据空间。主栈中存有c变量,c是一个结构体,它会指向一个数据空间,数据空间里存有字段 radius,值为7.0。紧接着会进行c.area2 的操作,会创建一个新的独立的栈——area2 栈,area2 也是一个独立的数据空间,此时不再时将值进行拷贝。当c与指针完成绑定时,仍然存在c变量,但此时c变量只相当于地址。main 栈本身也含有地址,假设 main 栈中的地址为0X11122,即会在 area2 栈就会将地址拷贝进来area栈中的c是一个指针,所以 area2 栈中c指向main 栈中的地址。按照原理来说,由于c是地址,所以不可以直接访问 radius 的值,按照标准应该是以(*)的格式进行访问,但是由于编译器的优化,会将(*)在底层进行添加,因此此时也是可以直接访问的。接下来进行运算 return 3.14*(*c).radius*(*c).radius,此时的值就是在 main 栈中获取的,这里与之前所讲的都不一样,没有所谓的结构体的数据空间。

为了打消顾虑,可以检验一下计算所需要的值是从哪里获取的,先将主栈里c的值取出,输入 fmt.Printf("main c 结构体变量地址 =%\n",&c),添加\n是为了便于查看。因为c本身就是一个指针,所以应该将它的内容取出,代码为 fmt.Printf("c是*Circle 指向的地址 =%p",c),不需要再利用&了,因为此时c本身就是一个地址,若此时通过上述代码取出的地址和已知的地址一致,即可证明上述结论正确。运行后发现,输出的地址地区与所知地址一样。

 

相关文章
|
7月前
|
存储 Java 程序员
|
7月前
|
XML Java 数据库连接
谈谈Java反射:从入门到实践,再到原理
谈谈Java反射:从入门到实践,再到原理
134 0
|
缓存 Java
认真阅读完这篇文章熟练掌握阿里巴巴规范创建Java线程池
认真阅读完这篇文章熟练掌握阿里巴巴规范创建Java线程池
821 0
|
人工智能 分布式计算 Java
【C++初阶】前言——C++的发展简述及学习方法分享
之前我们一直分享C语言和使用C语言完成数据结构的初阶的文章,今天我们正式进入C++的学习,这篇文章主要是给大家带来的是C++的由来、以及和C语言的区别、更主要的是和大家分享自己的学习方法,给一些我的建议。
|
1月前
|
自然语言处理 安全 PHP
深入浅出PHP编程:从基础到实战
【10月更文挑战第36天】本文将带你走进PHP的奇妙世界,无论你是初学者还是有一定经验的开发者,都将从中获益。文章首先介绍PHP的基础概念和语法,然后通过实际代码示例,展示如何利用PHP进行高效的Web开发。最后,我们将探讨一些高级主题,如面向对象编程、数据库操作以及安全性问题。让我们一起开启PHP的学习之旅吧!
|
1月前
|
存储 Serverless PHP
PHP编程入门:从基础到实战
【10月更文挑战第35天】本文将带你走进PHP的世界,从最基本的语法开始,逐步深入到实际应用。我们将通过简单易懂的语言和实际代码示例,让你快速掌握PHP编程的基础知识。无论你是初学者还是有一定经验的开发者,都能在这篇文章中找到你需要的内容。让我们一起探索PHP的魅力吧!
|
1月前
|
存储 Java PHP
PHP编程之旅:从基础到实战
【10月更文挑战第23天】本文将带你走进PHP的世界,探索这个流行的服务器端脚本语言的魅力。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你提供有价值的信息和实用的代码示例。我们将从PHP的基本概念开始,然后深入到实际应用中,最后通过一个实战项目来巩固所学知识。让我们一起开启这段激动人心的PHP编程之旅吧!
26 0
|
2月前
|
机器学习/深度学习 人工智能 Kubernetes
技术探索之旅:从基础到进阶的心得体会
本文记录了作者在技术领域的学习和实践过程中积累的经验与感悟。文章涵盖了从基础知识的学习、项目实践,到新技术的探索与应用,最终总结出几点对未来技术发展的思考。希望这些分享能够启发更多的技术爱好者,共同进步。
|
7月前
|
C++
Tars重要知识点
Tars重要知识点
|
6月前
|
算法 安全 Java
技术经验分享:JavaSecurity:Java加密框架(JCA)简要说明
技术经验分享:JavaSecurity:Java加密框架(JCA)简要说明

热门文章

最新文章