妙用interface来判断是否实现某些函数

前端之家收集整理的这篇文章主要介绍了妙用interface来判断是否实现某些函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

零、前言

看到一段代码,发现以前没有这样来使用golang的interface,因此,写了一小段代码来验证。

一、问题

有一个struct,如何判断这个struct是否实现了某个函数

举例说:

type GG struct { name string }

func (g *GG)Get() { …… }

func (g *GG)Set(name string) { …… }

func (g *GG)……等等一堆函数



如何判断GG是否实现了Print()函数呢?

二、解决方法

1、查看源代码或者doc或者说明文档或者写邮件代码的原作者等。这是人工方法,简单有效。

2、使用reflection方法。这也是现在常用的方法代码在网上有很多,不举例了。这是自动方法

3、使用接口。这也是本文要做的事情。基本思路是:

在自己的代码中定义一个私有的interface,在该interface中定义需要查询代码,然后借用interface的typeassertion来判断。

package main

import (
	"fmt"
)

type V1 struct {
	name string
}

func (v *V1) Print() {
	fmt.Printf("V1 name=%s\n",v.name)
}

type V2 struct {
	score int
}

func (v *V2) PPrint() {
	fmt.Printf("V2 score=%d\n",v.score)
}

func main() {
	type P interface {
		Print()    // 需要是否实现了Print函数
	}

	type PP interface {
		PPrint()  // 需要是否实现了PPrint函数
	}
	
		T := func(t interface{}) {  // 判断函数
			if v,ok := t.(P); ok {   // 如果实现了P接口,也就是判断是否实现了Print函数
				v.Print()   // 判断后可以根据需要实现代码
			} else if vv,ok2 := t.(PP); ok2 {  // 如果实现了PP接口,也就是判断是否实现了PPrint函数
				vv.PPrint()  // 判断后可以根据需要实现代码
			}
		}
	
	// 以下为测试代码
	v1 := &V1{"Jack"}
	v2 := &V2{100}

	T(v1)
	T(v2)
}



输出为:

V1 name=Jack
V2 score=100



最后,在测试中,需要注意的是:判断是否实现了某个interface,需要为interface{}类型,如果直接使用:

if t,ok := v1.(P);ok { …… }



会出现“invalid type assertion: v1.(<inter>) (non-interface type *V1 on left)”。

解决方法为:

var vv interface{} = v1

if t,ok := vv.(P);ok { …… }

猜你在找的Go相关文章