Golang
Go语言方法
11-10 09:14什么是方法
Golang的方法类似函数,但在func关键字和方法名之间,有一个特殊接收器参数,它定义了方法所属的类型。
Goland中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此不仅是struct,任何自定义类型都可以有方法
方法的声明
func (receiver type) methodName(参数列表) 返回值类型 {
... 方法体
return 返回值
}
1、参数列表:表示方法输入
2、receiver type:表示 methodName 方法和 type 类型绑定,receiver 是 type 类型的一个变量(实例),在方法内部使用 receiver 作为变量名,来调用 type 类型的相关字段
3、receiver type:type 可以是结构体,也可以是其它的自定义类型
4、返回值可以多个
5、return 语句不是必须的
体验方法的声明和调用
//定义一个 User 结构体
type User struct {
Name string
}
//下面表示 User 结构体有一个方法,名为test
func (u User) test() { // (u User) 说明 test 方法和 User 类型绑定
fmt.Println(u.Name)
}
func main() {
user := User{"Tom"}
user.test() //调用方法
}
方法快速入门

对上面代码的说明:
1、test 方法和 User 类型绑定
2、test 方法只能通过 User 类型的变量来调用,不能直接调用,也不能使用其它类型变量来调用
3、func (u User) test() {...} 中,u 表示调用test方法的 User 类型的变量,类似函数传参,比如上面的 u 就表示 userFun 函数中的 user(值传递,copy一份)
4、u 这个名字并不是固定写法,由程序员指定,可以为任意字符串
方法传参
举例说明,比如:为 Cal 结构体添加 Sum 方法,传入两个参数,可以求和并返回结果

通过以上的代码不难看出,方法调用与传参机制和函数基本一样,不同之处是方法调用时,会将调用方法的(结构体)变量,当做实参也传递给方法
方法调用和传参机制原理
如上图代码所示,下面为 Sum 方法的执行过程 + 说明

以上代码的说明:
1、在通过一个变量去调用方法时,其调用机制和函数一样
2、通过变量调用方法时,该变量本身也会做为一个参数传递给方法,如果变量是值类型,则进行值拷贝,如果变量是引用类型,则进行地址拷贝
在方法中使用指针接收者
结构体类型是值类型,在调用方法时,遵守值类型的传递机制,是值拷贝传递方式,即:在方法内部对结构体字段进行赋值或修改,方法外部的结构体字段的值,并不会被改变
如果希望在方法中,修改外部结构体变量的值,可以通过结构体指针的方式来处理

方法可以作用在任何类型上
Golang 中的方法需要作用在某个类型上(和指定数据类型绑定),因此自定义类型都可以有方法,这里所说的自定义类型,不仅是struct,int、float32等都可以有方法

方法的作用域
方法的可调用范围和函数一样,方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其他包访问
使用fmt.Println时默认调用String()方法
如果一个类型中实现了 String() 方法,那么使用 fmt.Println() 打印这个类型的变量时,会默认调用这个变量的 String() 方法
仔细阅读以下代码和注释,加深对 String() 方法的使用理解

还可以在 String() 方法中使用指针接受者,此时不同的调用方式,将会决定变量的值

注意:
1、若某类型存在 String() 方法,在这个类型的其它任何方法中使用 fmt.Println() 打印此类型的变量,都会调用 String()方法
2、每使用一次 fmt.Println(),就会调用一次 String() 方法
方法接收者指针的说明
在创建结构体变量时,不论是值类型或指针类型,调用方法时,方法内的使用结构体类型由方法的接收者决定
即:方法的 receiver type 是值类型,那外面不管是值或指针,在方法内部都是值类型,相反,方法的 receiver type 是指针类型,那么不论调用方法时的变量是什么类型,在方法内都是指针(修改字段的值外部会生效)
通过代码理解
type User struct{
Name string
}
func (u User) changeName(){
//由于变量 u 不是指针,即使外面调用 changeName() 方法的变量是指针类型,在方法内部依然为普通类型
u.Name = "Lcuy"
}
func (u *User) changeName2(){
u.Name = "" //指针
}
func main(){
u1 := &User{"Tom"} //指针
u1.changeName()
fmt.Println(u1) //
u2 := User{"Jack"}
}
案例:根据输入的数字打印99乘法表

案例:矩阵转置

打印金字塔
