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

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

iterate over all interface methods in go

问题

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

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

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/antchfx/xmlquery"
  5. )
  6. type node xmlquery.Node
  7. type XmlChecks interface {
  8. checkUTC() (string, string)
  9. checkSugPresDel() (string, string)
  10. checkStartNum() (string, string)
  11. // ... 还会有很多其他方法
  12. }
  13. type XmlVerify struct {
  14. doc node
  15. }
  16. func (xver XmlVerify) checkUTC() (string, string) {
  17. //TBD
  18. return "cUTC", "pass"
  19. }
  20. func (xver XmlVerify) checkSugPresDel() (string, string) {
  21. //TBD
  22. return "cSugPresDel", "pass"
  23. }
  24. func (xver XmlVerify) checkStartNum() (string, string) {
  25. //TBD
  26. return "cStartNum", "pass"
  27. }
  28. func main() {
  29. var vrfy XmlVerify
  30. vrfy.doc, _ := xmlquery.Parse("myfile.xml")
  31. for each_method := range "vrfy.XmlChecks 中的所有方法" { // <--WANT
  32. fmt.Printf("%s %s\n", vrfy.each_method()) // <--WANT
  33. }
  34. }
英文:

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":

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;github.com/antchfx/xmlquery&quot;
  5. )
  6. type node xmlquery.Node
  7. type XmlChecks interface {
  8. checkUTC() (string, string)
  9. checkSugPresDel() (string, string)
  10. checkStartNum() (string, string)
  11. // ... there will be many
  12. }
  13. type XmlVerify struct {
  14. doc node
  15. }
  16. func (xver XmlVerify) checkUTC() (string, string) {
  17. //TBD
  18. return &quot;cUTC&quot;, &quot;pass&quot;
  19. }
  20. func (xver XmlVerify) checkSugPresDel() (string, string) {
  21. //TBD
  22. return &quot;cSugPresDel&quot;, &quot;pass&quot;
  23. }
  24. func (xver XmlVerify) checkStartNum() (string, string) {
  25. //TBD
  26. return &quot;cStartNum&quot;, &quot;pass&quot;
  27. }
  28. func main() {
  29. var vrfy XmlVerify
  30. vrfy.doc, _ := xmlquery.Parse(&quot;myfile.xml&quot;)
  31. for each_method := range &quot;all the methods in vrfy.XmlChecks&quot; { //&lt;--WANT
  32. fmt.Printf(&quot;%s %s\n&quot;, vrfy.each_method()) //&lt;--WANT
  33. }
  34. }

答案1

得分: 2

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

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. type XmlVerify struct {
  7. value string
  8. }
  9. func (xver XmlVerify) CheckUTC() (string, bool) {
  10. return "cUTC", xver.value == "one"
  11. }
  12. func (xver XmlVerify) CheckSugPresDel() (string, bool) {
  13. return "cSugPresDel", xver.value == "two"
  14. }
  15. func (xver XmlVerify) CheckStartNum() (string, bool) {
  16. return "cStartNum", xver.value == "three"
  17. }
  18. func verify(xmlverify XmlVerify) {
  19. t := reflect.TypeOf(xmlverify)
  20. for i := 0; i < t.NumMethod(); i++ {
  21. method := t.Method(i)
  22. ret := reflect.ValueOf(xmlverify).MethodByName(method.Name).Call(nil)
  23. fmt.Printf("%s checks passed: %t\n", ret[0], ret[1])
  24. }
  25. }
  26. func main() {
  27. v := XmlVerify{"two"}
  28. verify(v)
  29. }

输出结果:

  1. cStartNum checks passed: false
  2. cSugPresDel checks passed: true
  3. 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).

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;reflect&quot;
  5. )
  6. type XmlVerify struct {
  7. value string
  8. }
  9. func (xver XmlVerify) CheckUTC() (string, bool) {
  10. return &quot;cUTC&quot;, xver.value == &quot;one&quot;
  11. }
  12. func (xver XmlVerify) CheckSugPresDel() (string, bool) {
  13. return &quot;cSugPresDel&quot;, xver.value == &quot;two&quot;
  14. }
  15. func (xver XmlVerify) CheckStartNum() (string, bool) {
  16. return &quot;cStartNum&quot;, xver.value == &quot;three&quot;
  17. }
  18. func verify(xmlverify XmlVerify) {
  19. t := reflect.TypeOf(xmlverify)
  20. for i := 0; i &lt; t.NumMethod(); i++ {
  21. method := t.Method(i)
  22. ret := reflect.ValueOf(xmlverify).MethodByName(method.Name).Call(nil)
  23. fmt.Printf(&quot;%s checks passed: %t\n&quot;, ret[0], ret[1])
  24. }
  25. }
  26. func main() {
  27. v := XmlVerify{&quot;two&quot;}
  28. verify(v)
  29. }

output:

  1. cStartNum checks passed: false
  2. cSugPresDel checks passed: true
  3. 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:

确定