如何访问指向函数的接口

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

How to access to interface of a pointered function

问题

对于验证器,我有以下接口:

  1. type validatorInterface interface {
  2. IsValid() error
  3. }
  4. func customValidation(fl validator.FieldLevel) bool {
  5. field := fl.Field().Interface()
  6. validatorObject, ok := field.(validatorInterface)
  7. if !ok {
  8. return false
  9. }
  10. err := validatorObject.IsValid()
  11. if err != nil {
  12. return false
  13. }
  14. return true
  15. }

如果要验证的字段实现的函数没有指针,它可以完美地工作,就像这样:

  1. func (s s) IsValid()

但是,如果实现的函数是这样的:

  1. func (s *s) IsValid()

将其转换为接口时会失败。我该如何改进customValidation来解决这个问题?

英文:

For the validator I have the following interface

  1. type validatorInterface interface {
  2. IsValid() error
  3. }
  4. func customValidation(fl validator.FieldLevel) bool {
  5. field := fl.Field().Interface()
  6. validatorObject, ok := field.(validatorInterface)
  7. if !ok {
  8. return false
  9. }
  10. err := validatorObject.IsValid()
  11. if err != nil {
  12. return false
  13. }
  14. return true
  15. }

It work perfect if the field to validate has the function implemented without pointer. Like that:

  1. func (s s) IsValid()

but the conversion to the interface fails if it is implemented like that

  1. func (s *s) IsValid()

How can I improve the customValidation to solve the problem

答案1

得分: 1

好的,以下是翻译好的内容:

好的,最终我找到了答案。我记得 encoding/json 库可以做到这一点,所以我查看了它,找到了以下代码:

  1. // 如果 v 是一个命名类型并且是可寻址的,
  2. // 首先使用它的地址,这样如果该类型有指针方法,
  3. // 我们就可以找到它们。
  4. if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() {
  5. haveAddr = true
  6. v = v.Addr()
  7. }

我按照这种方式实现了它,并且它可以正常工作。

英文:

OK, finally I found and answer. I remember that the encoding/json library do that so I looked at it and I found

  1. // If v is a named type and is addressable,
  2. // start with its address, so that if the type has pointer methods,
  3. // we find them.
  4. if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() {
  5. haveAddr = true
  6. v = v.Addr()
  7. }

I implemented that in that way and it works correctly.

答案2

得分: 0

如果是通过引用实现的,你需要fl.Field().Interface()返回一个引用。

https://go.dev/play/p/iYTibDNrH5E

嗯,这样也更准确,因为如果方法是通过引用传递的,你可能想要传递一个对象的引用。

英文:

If it is implemented by reference, you need that fl.Field().Interface() will return an reference.

https://go.dev/play/p/iYTibDNrH5E

Well, it's also more accurate, since if the method is by reference, you probably want to pass a reference to the object.

huangapple
  • 本文由 发表于 2023年6月6日 18:30:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76413714.html
匿名

发表评论

匿名网友

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

确定