【一Go到底】第三十八天---方法使用深度解析

98 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第38天,点击查看活动详情

一、方法使用深度解析

1.1 方法的声明(定义)

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

1.2 注意事项

  1. 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
  2. 如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理。详见案例 2.1 案例一
  3. Golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct,比如int,float32等都可以有方法. 详见案例 2.2 案例二
  4. 方法的访问范围控制的规则,和函数-样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其它包访问。
  5. 如果一个类型实现了String()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出,如果没有实现,&取的就是地址.详见 2.3 案例三

二 案例分析

2.1 案例一

package main

import (
	"fmt"
)

// 1. 声明一个结构体Circle.字段为 radius
// 2. 声明一个方法area和Circle绑定,可以返回面积

type Circle struct {
	radius float64
}

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

// 为了提高效率,通常方法和结构体的指针类型进行绑定
func (c *Circle) area2() float64 {
	// 因为 c 是指针,标准访问字段方式 如下  (*c).radius
	// 这里也可以写成  c.radius  ,在之前有讲过,底层进行优化,方便程序员进行编写
	return 3.14 * (*c).radius * (*c).radius
}

func main() {

	// // 创建实例
	// c := Circle{}
	// c.radius = 3.14
	// // 3.14 的圆的面积是 30.959144000000002
	// fmt.Printf("%v 的圆的面积是 %v\n", c.radius, c.area())

	//  指针类型绑定调用
	c := Circle{}
	c.radius = 5.0
	prtResult := (&c).area2()
	// 编译器底层做了优化,也可以这样写
	// (&c).area2() =======>>> c.area2()
	// 编译器自动加上

	// prtResult =  78.5
	fmt.Println("prtResult = ", prtResult)
}

2.2 案例二

package main

import "fmt"

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

type integer int

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

// 编写一个方法,可以修改i的值

func (i *integer) change() {
	*i += 1
}

func main() {

	var i integer = 10
	// i =  10
	i.print()

	// 调用change方法
	i.change()
	// print() =  11
	i.print()
	// main i=  11
	fmt.Println("main i= ", i)
}

2.3 案例三

package main

import "fmt"

// 定义结构体
type Student struct {
	Name string
	Age  int
}

// 给 *student 实现方法String()

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

}

func main() {
	// 调用 student的String方法
	stu := Student{"Aliy", 22}
	// Main() stu =  Name = [Aliy], Age=[22]
	fmt.Println("Main() stu = ", &stu)
}