在Go语言中遍历所有接口方法。

huangapple go评论92阅读模式
英文:

iterate over all interface methods in go

问题

如何对一个 XML 文件运行一系列检查?每个检查都是一个返回两个字符串的方法:它的名称和通过或失败的结果。我尝试将所有的方法放在一个接口中,但是无法弄清如何进行迭代。

在这个代码示例中,尝试为注释"WANT"找到一些可行的解决方案:

package main

import (
        "fmt"
        "github.com/antchfx/xmlquery"
)

type node xmlquery.Node

type XmlChecks interface {
        checkUTC() (string, string)
        checkSugPresDel() (string, string)
        checkStartNum() (string, string)
        // ... 还会有很多其他方法
}

type XmlVerify struct {
        doc node
}

func (xver XmlVerify) checkUTC() (string, string) {
        //TBD
        return "cUTC", "pass"
}

func (xver XmlVerify) checkSugPresDel() (string, string) {
        //TBD
        return "cSugPresDel", "pass"
}

func (xver XmlVerify) checkStartNum() (string, string) {
        //TBD
        return "cStartNum", "pass"
}

func main() {
        var vrfy XmlVerify
        vrfy.doc, _ := xmlquery.Parse("myfile.xml")
        for each_method := range "vrfy.XmlChecks 中的所有方法" { // <--WANT
                fmt.Printf("%s %s\n", vrfy.each_method()) // <--WANT
        }

}
英文:

How to run a suite of checks on an xml file? Each check is a method
that returns 2 strings: it's name and pass or fail.
Using xmlquery. I tried putting all the methods in an interface but
can't figure out how to iterate.

In this code sample, trying to get something to work for comment "WANT":

package main

import (
        &quot;fmt&quot;
        &quot;github.com/antchfx/xmlquery&quot;
)

type node xmlquery.Node

type XmlChecks interface {
        checkUTC() (string, string)
        checkSugPresDel() (string, string)
        checkStartNum() (string, string)
        // ... there will be many
}

type XmlVerify struct {
        doc node
}

func (xver XmlVerify) checkUTC() (string, string) {
        //TBD
        return &quot;cUTC&quot;, &quot;pass&quot;
}

func (xver XmlVerify) checkSugPresDel() (string, string) {
        //TBD
        return &quot;cSugPresDel&quot;, &quot;pass&quot;
}

func (xver XmlVerify) checkStartNum() (string, string) {
        //TBD
        return &quot;cStartNum&quot;, &quot;pass&quot;
}

func main() {
        var vrfy XmlVerify
        vrfy.doc, _ := xmlquery.Parse(&quot;myfile.xml&quot;)
        for each_method := range &quot;all the methods in vrfy.XmlChecks&quot; { //&lt;--WANT
                fmt.Printf(&quot;%s %s\n&quot;, vrfy.each_method()) //&lt;--WANT
        }

}

答案1

得分: 2

这是一个使用reflect包的示例,展示了如何进行操作。只需更改XmlVerify内部的值,就可以使示例变得更简单一些。还要确保方法名是导出的(首字母大写)。

package main

import (
	"fmt"
	"reflect"
)

type XmlVerify struct {
	value string
}

func (xver XmlVerify) CheckUTC() (string, bool) {
	return "cUTC", xver.value == "one"
}

func (xver XmlVerify) CheckSugPresDel() (string, bool) {
	return "cSugPresDel", xver.value == "two"
}

func (xver XmlVerify) CheckStartNum() (string, bool) {
	return "cStartNum", xver.value == "three"
}

func verify(xmlverify XmlVerify) {
	t := reflect.TypeOf(xmlverify)

	for i := 0; i < t.NumMethod(); i++ {
		method := t.Method(i)
		ret := reflect.ValueOf(xmlverify).MethodByName(method.Name).Call(nil)
		fmt.Printf("%s checks passed: %t\n", ret[0], ret[1])
	}
}

func main() {
	v := XmlVerify{"two"}
	verify(v)
}

输出结果:

cStartNum checks passed: false
cSugPresDel checks passed: true
cUTC checks passed: false
英文:

Here is an example of how you can do it with reflect. Only changed the value inside XmlVerify to make the example a bit easier. Also make sure the method names are exported (capitalize).

package main

import (
	&quot;fmt&quot;
	&quot;reflect&quot;
)

type XmlVerify struct {
	value string
}

func (xver XmlVerify) CheckUTC() (string, bool) {
	return &quot;cUTC&quot;, xver.value == &quot;one&quot;
}

func (xver XmlVerify) CheckSugPresDel() (string, bool) {
	return &quot;cSugPresDel&quot;, xver.value == &quot;two&quot;
}

func (xver XmlVerify) CheckStartNum() (string, bool) {
	return &quot;cStartNum&quot;, xver.value == &quot;three&quot;
}

func verify(xmlverify XmlVerify) {
	t := reflect.TypeOf(xmlverify)

	for i := 0; i &lt; t.NumMethod(); i++ {
		method := t.Method(i)
		ret := reflect.ValueOf(xmlverify).MethodByName(method.Name).Call(nil)
		fmt.Printf(&quot;%s checks passed: %t\n&quot;, ret[0], ret[1])
	}
}

func main() {
	v := XmlVerify{&quot;two&quot;}
	verify(v)
}

output:

cStartNum checks passed: false
cSugPresDel checks passed: true
cUTC checks passed: false

huangapple
  • 本文由 发表于 2021年10月27日 01:02:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/69727223.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定