经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
Go 之烧脑的接口
来源:cnblogs  作者:灯火消逝的码头  时间:2024/2/18 9:05:56  对本文有异议

基本定义

Go 官方对于接口的定义是一句话:An interface type is defined as a set of method signatures. 翻译过来就是,一个接口定义了一组方法的集合。这和 Java 和 PHP 的接口类似,定义一组方法而不定义方法的具体实现。但是与 Java 和 PHP 迥然不同的地方在于 Go 不需要显式的声明 implements 关键词来继承接口,一个类型只要实现了接口中的所有方法,就视作继承了该接口,是隐式实现的。来看一个基本的使用示例: 

  1. // 定义一个平台接口,包含一个支付方法
  2. type Platform interface {
  3. Pay(amount int) error
  4. }
  5. // 微信平台
  6. type Wechat struct{}
  7. func (w *Wechat) Pay(amount int) error {
  8. fmt.Printf("wechat amount: %d\n", amount)
  9. return nil
  10. }
  11. // 支付宝平台
  12. // 任意值都可以实现接口,并非一定需要struct
  13. type Alipay int
  14. func (a Alipay) Pay(amount int) error {
  15. fmt.Printf("alipay amount: %d, a: %d\n", amount, a)
  16. return nil
  17. }
  18. func ExamplePlatform() {
  19. var (
  20. p Platform
  21. w = Wechat{}
  22. a Alipay = 1
  23. )
  24. p = &w
  25. p.Pay(2)
  26. p = &a
  27. p.Pay(3)
  28. // 这种写法会报错
  29. // p = w
  30. p = a
  31. p.Pay(4)
  32. // Output:
  33. // wechat amount: 2
  34. // alipay amount: 3, a: 1
  35. // alipay amount: 4, a: 1
  36. }

在这个示例中,我们定义了一个 Platform 接口和两个结构体,分别使用了值接收器和指针接收器来实现了 Platform 接口。p = w 这行代码会报错,究其原因是,对于使用指针接收器实现的接口的 Wechat,只有它的指针会实现接口,值不会实现;而对于值实现接口的 Alipay,指针和值都会实现接口。所以 p = a 可以正常运行。

接口嵌套

接口可以嵌套另一个接口:

  1. // 定义一个平台接口,包含一个支付方法
  2. type Platform interface {
  3. Pay(amount int) error
  4. User
  5. }
  6. type User interface {
  7. Login()
  8. Logout()
  9. }
  10. // 微信平台
  11. type Wechat struct{}
  12. func (w *Wechat) Pay(amount int) error {
  13. fmt.Printf("wechat amount: %d\n", amount)
  14. return nil
  15. }
  16. func (w *Wechat) Login() {}
  17. func (w *Wechat) Logout() {}

此时,Wechat 即实现了 Platform 接口,也实现了 User 接口。

接口类型断言

再来看一个很复杂的例子,我们将上面的代码稍作修改,将 WechatLogin Logout 提到另一个结构中,然后使用类型断言判断 Wechat 是否实现了 User 接口:

  1. // 定义一个平台接口,包含一个支付方法
  2. type Platform interface {
  3. Pay(amount int) error
  4. User
  5. }
  6. type User interface {
  7. Login()
  8. Logout()
  9. }
  10. type UserS struct {
  11. }
  12. func (u *UserS) Login() {}
  13. func (u *UserS) Logout() {}
  14. // 微信平台
  15. type Wechat struct {
  16. UserS
  17. }
  18. func (w *Wechat) Pay(amount int) error {
  19. fmt.Printf("wechat amount: %d\n", amount)
  20. return nil
  21. }
  22. func ExamplePlatform() {
  23. var (
  24. p Platform
  25. w = Wechat{}
  26. )
  27. p = &w
  28. p.Pay(2)
  29. // 类型断言
  30. _, ok := p.(User)
  31. fmt.Println(ok)
  32. // Output:
  33. // wechat amount: 2
  34. // true
  35. }

空接口

Go 1.18 新增了一个新的变量类型:any,其定义如下:

  1. type any = interface{}

其实 any 就是一个空接口,对于空接口而言,它没有任何方法,所以对于任意类型的值都相当于实现了空接口,这个概念和另一个编程概念十分相似,它就是大名鼎鼎的泛型。在 Go 语言中,fmt.Println 函数的接收值正是一个 any

  1. func Println(a ...any) (n int, err error) {
  2. return Fprintln(os.Stdout, a...)
  3. }

使用空接口搭配类型断言,我们可以设计出一个简单的类型转换函数,它将任意类型的值转为 int:

  1. func ToInt(i any) int {
  2. switch v := i.(type) {
  3. case int:
  4. return v
  5. case float64:
  6. return int(v)
  7. case bool:
  8. if v {
  9. return 1
  10. }
  11. return 0
  12. case string:
  13. vint, _ := strconv.Atoi(v)
  14. return vint
  15. }
  16. return 0
  17. }

原文链接:https://www.cnblogs.com/oldme/p/18015328

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号