装修网站模板,微信营销方案,wordpress安装后要删除哪些文件夹,wordpress 根目录GO 中的方法是什么#xff1f;
前面我们有分享到 GO 语言的函数#xff0c;他是一等公民#xff0c;那么 GO 语言中的方法和函数有什么区别呢#xff1f;
GO 语言中的方法实际上和函数是类似的#xff0c;只不过在函数的基础上多了一个参数#xff0c;这个参数在 GO 语…GO 中的方法是什么
前面我们有分享到 GO 语言的函数他是一等公民那么 GO 语言中的方法和函数有什么区别呢
GO 语言中的方法实际上和函数是类似的只不过在函数的基础上多了一个参数这个参数在 GO 语言中被称为 receiver 参数
例如我们可以这么来申明一个方法
func (xx T/*T) helloworld(入参参数列表) (返回值列表) {// 具体实现
}demo 中的 helloworld 方法就绑定到了 receiver T 类型上这个 helloworld 方法我们可以通过使用 T 类型或者 *T 来进行调用例如
var tt T
tt.helloworld(入参参数列表)
var pt *T
pt.helloworld(入参参数列表)看着还是挺简单的对吗对于使用的时候我们需要注意这些问题
GO 语言中原生的类型是不能作为上述的 receiver 的例如 intslicemap等等都是不行的只能是我们自定义的类型方法只能有一个 receiver 参数只能绑定一个不能绑定多个receiver 参数类型本身不能是指针或者是接口类型这里非常需要注意
如图receiver 参数类型本身不能是指针类型 如图receiver 参数类型本身不能是接口类型 对于方法是绑定了一个 receiver 类型的参数那么这个参数是不是很像 C 里面的入参呢
func helloworld(xx T/*T, 其他入参) (返回值列表){// 具体实现
}所以在 GO 语言里面我们能够明白一个方法所绑定类型的实例实际上就是一个普通函数的第一个参数
就像这样
func (t T) helloworld() helloworld(t T)
func (pt *T) helloworld() helloworld(pt *T)那么对于上述绑定的类型有 T 也有 *T 如何去选择呢什么时候用 T 什么时候又用 *T 呢
此处 T 叫做值类型 *T 叫做指针类型 选择不同的类型
如果选择 T 类型那么这是一个值传递类型的在调用 helloworld 方法的时候实际上就是传了一个 T 类型实例的副本那么如果在 helloworld 方法中对 t 做了一些变动那么只会影响副本对于原来的 T 类型实例是不会有影响的如果选择了 *T 类型那么这就是一个指针类型的调用 helloworld 方法的时候传的就是类型 T 的实例地址这个时候 helloworld 内部如果对 t 做了一些变动都会体现到原来的 T 的实例上
这个理解方式实际上就和咱们普通函数中传入的参数是一样的传值和传地址的区别
一个简单的 demo 再来加深一下
定义个 TT 类型的结构成员有 Name定义 Hello1 方法绑定 TT定义 hello2 方法绑定 *TT新建一个 TT 类型的变量 t分别去调用 hello1 和 hello2新建一个 *TT 类型的变量 pt分别去调用 hello1 和 hello2 可以看到上述程序的结果如下
name
name hello2
name
name hello2从上述 demo 中就可以看出实际上 GO 语言对于我们调用方法的时候是做了隐式转换无论是值类型的实例还是指针类型的实例都是可以去调用绑定了值类型的方法也可以去调用绑定了指针类型的方法
只不过得到的结果就要看具体方法是绑定的值类型还是指针类型了
所以我们如何去选择 receiver 的类型到此就很清楚了吧
如果我们期望要去修改 receiver 类型的实例那么就用指针类型如果不期望修改则使用值类型
当然如果我们是要考虑到性能就要使用传地址的方式较好
方法的集合
GO 里面虽然没有类没有对象没有继承但是关于面向对象里面的内容在 GO 里面完全可以使用组合的方式来进行实现
所以对于GO 里面是如何组合的的基本知识我们要搞清楚前提我们就先要弄明白方法的集合是如何玩的
在 GO 语言里面我们在给接口变量复制使用结构体嵌入或者接口嵌入使用 类型别名的时候都是会涉及到方法集合的但是具体要看某一个实例包含哪些方法集合我们就可以来演练一下
定义 ITT 接口里面有 2 个方法 Hello1() , Hello2()定义 TT 结构体实现上述接口其中 Hello1() 绑定 TT Hello2() 绑定 *TT查看 nil 转成 ITT 的方法集合TT 的方法集合*TT 的方法集合
type ITT interface{Hello1()Hello2()}type TT struct{}func (t TT)Hello1(){}func (pt *TT)Hello2(){}// 打印方法集合
func GetMethodSet(i interface{}){v : reflect.TypeOf(i)et : v.Elem()num : et.NumMethod()if num 0 {fmt.Println(et, methond num is 0 )return}// 有方法集合fmt.Println(et,mthond set is :)for i:0;inum;i{fmt.Println(---,et.Method(i).Name)}
}func main(){var t TTvar pt * TT// 先查看 nil 接口的方法集合GetMethodSet((*ITT)(nil))// 查看 TT 的方法集合GetMethodSet(t)// 查看 *TT 的方法集合GetMethodSet(pt)
}运行结果如下 可以查看到上述案例绑定类型为 TT 的方法集合只有 1 个绑定类型为 *TT 的方法集合有 2 个可以看得出来
**T 类型的方法集合是包含了 T 类型和 T 类型
T 类型的方法集合是包含了 T 类型
对于 GO 语言里面的组合总的来说有三种这个可以多多尝试和写 demo 练习
接口中嵌入接口
type ITT interface{hello1()
}
type ITT2 interface{hello2()
}
type ITT3 interface{ITT ITT2
}接口中嵌入接口最终的接口方法个数是取和数此处我们要注意的地方就是方法名如果重复也是可以正常得到方法集合具体使用接口中的方法还是要看实例是如何实现的
结构体中嵌入接口
type ITT interface{hello1()hello2()
}
type ITT2 interface{hello2()hello3()
}
type TT struct{ITT ITT2
}
// 此时 TT 的方法集合就存在 hello2() 是冲突的因此此处就需要 TT 去实现自己的 hello2()
func (TT)hello2(){}结构体中嵌入接口如果遇到同名的方法GO 语言会优先选择结构体自己实现的方法如果结构体自己未实现则会将接口中的同名方法提升到自己的结构体中来
结构体中嵌入结构体
结构体中嵌入结构体就要注意嵌入的结构体是值类型的还是指针类型的例如
type TT struct{TT1*TT2
}那么 TT 的方法集合是什么 *TT 的方法集合是什么
TT 的方法集合就是按照正常值传递的来等于 TT1 的方法集合 加上 *TT2 的方法集合
*TT 的方法集合按照地址传递的来等于 *TT1的方法集合 加上 *TT2 的方法集合
那么类型别名的方法集合又是如何去查看的有什么需要注意的地方吗
那么还是上述方法集合中的案例我们分别给结构体 TT 定一个别名TTB给接口类型 ITT 定义一个 ITTB 此时来查看别名的方法集合与其原有类型的方法集合是否有差距 上述程序运行结果如下
main.ITT mthond set is :
--- Hello1
--- Hello2
main.ITT mthond set is :
--- Hello1
--- Hello2
main.TT mthond set is :
--- Hello1
main.TT mthond set is :
--- Hello1
*main.TT mthond set is :
--- Hello1
--- Hello2
*main.TT mthond set is :
--- Hello1
--- Hello2通过打印结果我们可以看到类型别名的方法集合与原有类型的方法集合是一样的无论是结构体类型还是接口类型
知道 receiver 能够调用的方法集合有哪些 那么在具体使用的时候就避免出错避免误解对于后续的接口组合就会理解的更加明白和清晰了
总结
本次主要分享了 GO 语言中方法和函数的关系GO 语言中的方法集合如何查看、甄别和使用
欢迎点赞关注收藏
朋友们你的支持和鼓励是我坚持分享提高质量的动力 好了本次就到这里
技术是开放的我们的心态更应是开放的。拥抱变化向阳而生努力向前行。
我是阿兵云原生欢迎点赞关注收藏下次见~ 可以进入地址进行体验和学习https://xxetb.xet.tech/s/3lucCI