Chapter011 golang中方法

上一章:Chapter010 golang中struct结构体
下一章:Chapter012 golang面向对象编程应用实例

一、简单快速入门

1、golang中方法是作用在指定数据类型上的(即:和指定的数据类型绑定),因此,自定义类型都可以有方法,而不仅仅是struct
2、方法申明和调用

func (receive type) methodName (参数列表) (返回列表){
	方法体
	return 返回值列表
}

(1)参数列表:表示方法输入
(2)receive type:表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型。type可以是结构体,也可以是其他的自定义类型。
(3)receiver :就是type类型的一个变量(实例),比如Person结构体的一个变量(实例)
(4)返回值列表:表示返回的值,可以多个
(5)方法主体:表示为了实现某一功能代码块
(6)return 语句不是必须的(但是有返回值列表或者返回值就必须有)

3、举例:

type A struct{
	Num int
}
func(a A)test(){
	fmt.Println(a.num)
}

3、对上面语法的说明
(1)func(a A) test(){}表示A结构体有一方法,方法名为test
(2)(aA)体现test方法是和A绑定的

package main

import (
	"fmt"
	_ "fmt"
)

type Person struct {
	Name string
}

//给A类型绑定一个方法 ,Person的变量名为p
func (p Person)test()  {
	fmt.Println("test()",p.Name)
}

func main()  {
	var p1  Person
	p1.test() //调用方法,这个时候就会把这里的p1传给上面的方法为p
	p1.Name = "tom"
	p1.test() //调用方法,这个时候就会把这里的p1传给上面的方法为p
}

(3)对上面代码说明
1)test方法和Person类型绑定
2)test方法只能通过Person类型的变量来调用,而不能直接调用,也不能使用其他类型的变量调用 ,即不能直接test()和p1.test()
3)func(p Person) test() {}… p表示哪个Person调用,这个p就是它的副本,这点和函数传参非常相似

package main

import (
	"fmt"
	_ "fmt"
)

type Person struct {
	Name string
}

//给A类型绑定一个方法 ,Person的变量名为p
func (p Person)test()  {
	p.Name = "jack"
	fmt.Println("test()",p.Name)
}

func main()  {
	var p1  Person
	p1.test() //调用方法,这个时候就会把这里的p1传给上面的方法为p
	p1.Name = "tom"
	p1.test() //调用方法,这个时候就会把这里的p1传给上面的方法为p
	fmt.Println("test()",p1.Name)

}

即:
在这里插入图片描述
4)p这个形参名,有程序员指定,不是固定

二、方法举例
package main

import (
	"fmt"
	_ "fmt"
)

type Person struct {
	Name string
}

func (p Person) speak() {
	fmt.Print(p.Name," is a good person\n")
}

func (p Person) jisuan()  {
	res :=0
	for i:= 1;i<100;i++{
		res +=i
	}
	fmt.Print(res)
}

func (p Person) jisuan2(n int)  {
	res :=0
	for i:= 1;i<n;i++{
		res +=i
	}
	fmt.Print(res,"\n")
}

func (p Person) getSum(n1 int,n2 int) int  {
	res := n1+n2
	return res
}

func main()  {
	person :=Person{"tom"}
	person.speak()
	person.jisuan()
	person.jisuan2(100)
	res := person.getSum(10,20)
	fmt.Print(res,"\n")
}

在这里插入图片描述

三、方法的调用和传参机制原理

1、在通过一个变量去调用方法时,其调用机制和函数是一样的
2、不一样的地方是,变量调用方法时,该变量本身也会作为一个参数传递到方法(如果变量是值类型,进行值拷贝,是引用类型,进行地址拷贝)
3、案例演示
求周长和面积:

package main

import (
"fmt"
_ "fmt"
)

type Circle struct {
	radius float64
}

func (c Circle) area() float64  {
	return 3.14 * c.radius * c.radius
}

func (c Circle) lens() float64  {
	return 2*3.14*c.radius
}

//为了提高效率,通常和结构体指针相绑定 **********************此时就是引用类型了
func (c *Circle) area2() float64 {
	return 3.14 * (*c).radius * (*c).radius //等价于c.radius
}

func (c *Circle) lens2() float64  {
	return 2 * 3.14 * (*c).radius  //等价于c.radius
}

func main()  {
	var circle Circle
	circle.radius = 4.0
	area := circle.area()
	lens := circle.lens()
	fmt.Print("面积是:",area,"\n","周长是:",lens,"\n")
	area2 :=(&circle).area2() //等价于circle.area2()
	lens2 :=(&circle).lens2() //等价于circle.lens2()
	fmt.Print("2: 面积是:",area2,"\n","周长是:",lens2)
}

在这里插入图片描述

四、方法的注意事项和细节

1、结构体是值类型,在方法调用时,遵守值类型的传递机制,是值拷贝
2、如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来修改
3、Golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct,比如int、float32等都可以有方法
例如:

package main

import (
	"fmt"
	_ "fmt"
)

type integer int

func (i integer) printi()  {
	fmt.Println("i=",i)
}

func main()  {
	var i integer = 10
	i.printi()
}

在这里插入图片描述
4、方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本地访问,方法首字母大写,可以在本包和其他包访问
5、如果一个类型实现了String()这个方法,那么fmt.Println就会默认调用这个变量的String()进行输出(应用:输出日志)

package main

import (
	"fmt"
	_ "fmt"
)

type Student struct {
	Name string
	Age int
}

func (stu *Student) String() string {  //**************************
	str := fmt.Sprintf("Name = [%v],Age = [%v]",stu.Name,stu.Age)
	return str
}

func main()  {
	var stu Student
	stu.Name = "tom"
	stu.Age = 10
	fmt.Println(&stu) //******************************************
}

在这里插入图片描述

五、方法和函数的区别

1、调用不一样
(1)函数的调用:函数名(实参列表)
(2)方法的调用:变量 方法名(实参列表)
2、对于普通函数:接受者为值类型时,不能将指针类型的数据直接传递,反之亦然
3、对于方法(如struct的方法)接受者为值类型时,可以直接使用指针类型的变量调用方法,反过来同样也可以

六、总结

不管调用如何,真正决定是值拷贝还是地址拷贝,看这个方法是和那个类型绑定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰西啊杰西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值