如何访问指向函数的接口

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

How to access to interface of a pointered function

问题

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

type validatorInterface interface {
	IsValid() error
}

func customValidation(fl validator.FieldLevel) bool {
	field := fl.Field().Interface()
	validatorObject, ok := field.(validatorInterface)
	if !ok {
		return false
	}
	err := validatorObject.IsValid()
	if err != nil {
		return false
	}

	return true
}

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

func (s s) IsValid()

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

func (s *s) IsValid()

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

英文:

For the validator I have the following interface

type validatorInterface interface {
	IsValid() error
}

func customValidation(fl validator.FieldLevel) bool {
	field := fl.Field().Interface()
	validatorObject, ok := field.(validatorInterface)
	if !ok {
		return false
	}
	err := validatorObject.IsValid()
	if err != nil {
		return false
	}

	return true
}

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

func (s s) IsValid()

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

func (s *s) IsValid()

How can I improve the customValidation to solve the problem

答案1

得分: 1

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

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

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

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

英文:

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

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

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:

确定