遇见go语言的第六天——方法

方法

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

type Person struct {
	Name string
	Age int
}
//给Person类型绑定一个方法
func (a Person)test(){
	fmt.Println(a.Name)
}
func main()  {
	var a Person
	a.Name = "tom"
	//调用方法
	a.test()
}
  • test方法和Person类型绑定
  • test方法只能通过Person类型的变量来调用,而不能直接调用,也不能使用其他类型变量调用
  • func(p Person)test(){} p表示哪个Person变量调用,这个p就是它的副本,这点和函数传参非常相似
  • p这个形参名,有程序员指定,不固定
type Person struct{
	Name string
}
//给Person结构体添加speak方法
func (p Person)speak(){
	fmt.Println(p.Name,"是一个好人")
}
//传参计算
func (p Person)jisuan(n int ){
	res := 0
	for i := 1;i <= n;i++{
		res += i
	}
	fmt.Println(res)
}
//传返回值
func (p Person)getsum(n1 int,n2 int)int{
	return n1 + n2
}

func main()  {
	var a Person
	a.Name = "jack"
	a.speak()
	a.jisuan(10)
	res := a.getsum(10,20)
	fmt.Println(res)
}
  • 方法的调用和传参机制

  • 在通过一个变量去调用方法时,其调用机制和函数一样

  • 不一样的地方是,变量调用方法时,该变量本身也会作为一个参数传递到方法(如果变量是值类型,则进行值拷贝,如果变量是引用类型,则进行地址拷贝)

type Circle struct {
	radius float64
}

func (c Circle)area(radius float64)float64  {
	area := radius * radius * 3.14
	return area
}
func main()  {
	var b Circle
	fmt.Println(b.area(2))
}
  • 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
  • 如果程序员希望在方法中修改结构体变量的值,可以通过结构体指针的方式处理
func (c *Circle)area1()float64{
	c.radius = 4
	area := c.radius * c.radius * 3.14
	return area
}
func main()  {
	var b Circle
	b.radius = 3
	fmt.Println(b.area1()) //结果为4为半径的面积
}
  • golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型都可以有方法,而不仅仅是struct,比如int ,float等都可以有方法
type integer int

func (i integer)print()  {
	fmt.Println(i)
}
//编写一个方法,可以改变i的值
func (i *integer)change(){
	*i = *i + 1
}
func main()  {
	var c integer = 1
	c.print()
	c.change()
	fmt.Println(c)
}
  • 方法的访问范围控制的规则和函数一样,方法的首字母小写,只能在本包访问,方法的首字母大写,可以在本包和其他包访问
  • 如果一个类型实现了string()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出
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()  {
	d := Student{
		Name: "txy",
		Age:  20,
	}
	fmt.Println(d.string())
}

实例一:编写一个结构体,方法,方法不需要参数,在方法中打印一个5*6的矩形,在main方法中调用该方法

type MethodUtils struct {
}
func (m MethodUtils)print()  {
	for i := 1;i <= 5;i++{
		for j := 1;j <= 6;j++{
			fmt.Printf("*")
		}
		fmt.Printf("\n")
	}
}
func main()  {
	var a MethodUtils
	a.print()
}

实例二:编写一个方法,提供m和n两个参数,方法中打印一个m*n的矩形

func (method MethodUtils)print1(n int,m int){
	for i := 1;i <= n;i++{
		for j := 1;j <= m;j++{
			fmt.Print("*")
		}
		fmt.Println()
	}
}
func main()  {
	var b MethodUtils
	b.print1(4,5)
}

实例三:编写一个方法算该矩形面积(可以接收长len和宽width),将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。

func (method MethodUtils)area(len float64,width float64)float64  {
	area := len * width
	return area
}
func main()  {
	var c MethodUtils
	fmt.Println(c.area(4,5))
}

实例四:编写方法:判断一个数是奇数还是偶数

func (method *MethodUtils) judge(n int) {
	if n % 2 == 0{
		fmt.Printf("%v是偶数",n)
	}else {
		fmt.Printf("%v是奇数",n)
	}
}
func main()  {
	var d MethodUtils
	d.judge(99)
}

实例五:定义一个小小计算机的结构体(Calcuator),实现加减乘除四个功能

type Calcuator struct {
	num1 float64
	num2 float64
}
func (cal *Calcuator)result(operator byte) float64 {
	var res float64
	switch operator {
	case '+':
		res = cal.num1 + cal.num2
	case '-':
		res = cal.num1 - cal.num2
	case '*':
		res = cal.num1 * cal.num2
	case '/':
		res = cal.num1 / cal.num2
	default:
		fmt.Println("输入错误!!")
	}
	return res
}
func main()  {
	var e Calcuator
	e.num1 = 3.6
	e.num2 = 1.2
	fmt.Println(e.result('/'))
}

方法和函数的区别

  1. 调用方式不一样
  2. 对普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
  3. 对于方法(如struct方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以
  • 不管调用形式如何,真正决定是值拷贝还是地址拷贝,看这个方法是和哪个类型绑定
  • 如果是和值类型,比如(p Person),则是值拷贝,如果和指针类型,比如是(p *Person)则是地址拷贝
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值