首页 > 其他分享 >Go 之烧脑的接口

Go 之烧脑的接口

时间:2024-02-14 17:22:25浏览次数:49  
标签:烧脑 int 接口 amount Wechat func Go type

基本定义

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

// 定义一个平台接口,包含一个支付方法
type Platform interface {
	Pay(amount int) error
}

// 微信平台
type Wechat struct{}

func (w *Wechat) Pay(amount int) error {
	fmt.Printf("wechat amount: %d\n", amount)
	return nil
}

// 支付宝平台
// 任意值都可以实现接口,并非一定需要struct
type Alipay int

func (a Alipay) Pay(amount int) error {
	fmt.Printf("alipay amount: %d, a: %d\n", amount, a)
	return nil
}

func ExamplePlatform() {
	var (
		p Platform
		w        = Wechat{}
		a Alipay = 1
	)
	p = &w
	p.Pay(2)

	p = &a
	p.Pay(3)

	// 这种写法会报错
	// p = w
	p = a
	p.Pay(4)

	// Output:
	// wechat amount: 2
	// alipay amount: 3, a: 1
	// alipay amount: 4, a: 1
}

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

接口嵌套

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

// 定义一个平台接口,包含一个支付方法
type Platform interface {
	Pay(amount int) error
	User
}

type User interface {
	Login()
	Logout()
}

// 微信平台
type Wechat struct{}

func (w *Wechat) Pay(amount int) error {
	fmt.Printf("wechat amount: %d\n", amount)
	return nil
}

func (w *Wechat) Login()  {}
func (w *Wechat) Logout() {}

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

接口类型断言

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

// 定义一个平台接口,包含一个支付方法
type Platform interface {
	Pay(amount int) error
	User
}

type User interface {
	Login()
	Logout()
}

type UserS struct {
}

func (u *UserS) Login()  {}
func (u *UserS) Logout() {}

// 微信平台
type Wechat struct {
	UserS
}

func (w *Wechat) Pay(amount int) error {
	fmt.Printf("wechat amount: %d\n", amount)
	return nil
}

func ExamplePlatform() {
	var (
		p Platform
		w = Wechat{}
	)
	p = &w
	p.Pay(2)

	// 类型断言
	_, ok := p.(User)
	fmt.Println(ok)

	// Output:
	// wechat amount: 2
	// true
}

空接口

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

type any = interface{}

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

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

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

func ToInt(i any) int {
	switch v := i.(type) {
	case int:
		return v
	case float64:
		return int(v)
	case bool:
		if v {
			return 1
		}
		return 0
	case string:
		vint, _ := strconv.Atoi(v)
		return vint
	}

	return 0
}

标签:烧脑,int,接口,amount,Wechat,func,Go,type
From: https://www.cnblogs.com/oldme/p/18015328

相关文章

  • Go 100 mistakes - #16: Not using linters
    Alinterisanautomatictooltoanalyzecodeandcatcherrors. Tounderstandwhylintersareimportant,let’stakeoneconcreteexample.Inmistake#1,“Unintendedvariableshadowing,”wediscussedpotentialerrorsrelatedto variableshadowing.Using......
  • Go 100 mistakes - #15: Missing code documentation
    Documentationisanimportantaspectofcoding.ItsimplifieshowclientscanconsumeanAPIbutcanalsohelpinmaintainingaproject.InGo,weshouldfollowsome rulestomakeourcodeidiomatic.First,everyexportedelementmustbedocumented.Wheth......
  • Go语言精进之路读书笔记第26条——了解接口类型变量的内部表示
    接口是Go这门静态语言中唯一“动静兼备”的语言特性接口的静态特性接口类型变量具有静态类型,比如:vareerror中变量e的静态类型为error支持在编译阶段的类型检查:当一个接口类型变量被赋值时,编译器会检查右值的类型是否实现了该接口方法集合中的所有方法接口的动态特性接......
  • Go - Project structure
    TheGolanguagemaintainerhasnostrongconventionaboutstructuringaprojectin Go.However,onelayouthasemergedovertheyears:project-layout(https://github.com/golang-standards/project-layout).Ifourprojectissmallenough(onlyafewfiles),......
  • Go 100 mistakes - #11: Not using the functional options pattern
      Here,WithPortreturnsaclosure.Aclosureisananonymousfunctionthatreferences variablesfromoutsideitsbody;inthiscase,theportvariable.Theclosurerespectsthe Optiontypeandimplementstheport-validationlogic.Eachconfigfieldr......
  • 8小时golang速成(五)Golang高阶 1、goroutine
    1、goroutine 协程并发协程:coroutine。也叫轻量级线程。与传统的系统级线程和进程相比,协程最大的优势在于“轻量级”。可以轻松创建上万个而不会导致系统资源衰竭。而线程和进程通常很难超过1万个。这也是协程别称“轻量级线程”的原因。一个线程中可以有任意多个......
  • Go 100 mistakes - #10: Not being aware of the possible problems with type embedd
     Becausethemutexisembedded,wecandirectlyaccesstheLockandUnlockmethods fromtheireceiver.Wementionedthatsuchanexampleisawrongusageoftypeembedding.What’s thereasonforthis?Sincesync.Mutexisanembeddedtype,theLockand......
  • 8小时速成golang(四)反射reflect 和 结构体标签
    编程语言中反射的概念在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。每种语言的反射模......
  • Django+nginx+uwsgi
    在云服务器上搭建web网站服务器的系统是CentOS7.6一、安装Python3.8.181、安装gccyuminstallgcc-y2、安装编译python的依赖yuminstallzlibzlib-devel-yyuminstallbzip2bzip2-devel-yyuminstallncursesncurses-devel-yyuminstallreadlinereadline-d......
  • Go 100 mistakes - #9: Being confused about when to use generics
    Go1.18addsgenericstothelanguage.Inanutshell,thisallowswritingcodewithtypes thatcanbespecifiedlaterandinstantiatedwhenneeded. Onelastthingtonoteabouttypeparametersisthattheycan’tbeusedwith methodarguments,onlywith......