Check if any variable conforms any interface using generics in Go

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

Check if any variable conforms any interface using generics in Go

问题

我正在使用go-fiber编写一个API,并且我想检查传递的JSON是否符合我想要的接口。所以我决定使用1.18版本的特性-泛型。以下是我所做的,但由于类型问题,它无法正常工作。

错误信息如下:

src/endpoints/v1/tasks.go:36:10: 无法在返回语句中使用nil作为I类型的值
src/endpoints/v1/tasks.go:39:9: 无法将c.JSON(format)(类型为error)作为I类型的值在返回语句中使用

我想这样调用该函数:

type CreateTaskDF struct {
	Target string `json:"target"`
	Deepness int `json:"deepness"`
}

func CreateTask(c *fiber.Ctx) error {
	data, err := checkDataConformsInterface[CreateTaskDF](&CreateTaskDF{}, c)
	if err != nil {
		log.Fatal(err)
	}
    // 在这里处理数据
    ...

请问我应该如何转换函数的返回值以使其正常工作?谢谢!

英文:

I am writing an API using go-fiber, and I want to check, if passed JSON conforms an interface that I want to see. So I decided to use 1.18's feature - generics. Here is what I did, but it does not work due to type problem.

func checkDataConformsInterface[I any](format I, c *fiber.Ctx) (I, error) {
	if err := c.BodyParser(&format); err != nil {
		return nil, err
	}

	return c.JSON(format), nil
}

The errors say

src/endpoints/v1/tasks.go:36:10: cannot use nil as I value in return statement
src/endpoints/v1/tasks.go:39:9: cannot use c.JSON(format) (value of type error) as type I in return statement

And I want to call the function like this:

type CreateTaskDF struct {
	Target string `json:"target"`
	Deepness int `json:"deepness"`
}

func CreateTask(c *fiber.Ctx) error {
	data, err := checkDataConformsInterface[CreateTaskDF](&CreateTaskDF{}, c)
	if err != nil {
		log.Fatal(err)
	}
    // work with data here
    ...

How should I convert the return value in the function to make it work? Thanks!

答案1

得分: 3

这可能可以这样工作(如果你不考虑任何基于库的有效负载验证器,这几乎存在于每个 Golang 路由库或 Web 框架中)。所以,为了仅验证你的数据,你可以使用以下代码:

func checkDataConformsInterface[I any](format I, c *fiber.Ctx) bool {
	if err := c.BodyParser(&format); err != nil {
		return false
	}
	return true
}
英文:

It probably could work like this(if you do not consider any lib-based payload validators, which exist in almost every golang routing lib or web framework). So, to just validate your data you can use this:

func checkDataConformsInterface[I any](format I, c *fiber.Ctx) bool {
	if err := c.BodyParser(&format); err != nil {
		return false
	}
	return true
}


</details>



# 答案2
**得分**: 1

所以我想出了以下解决方案

```go
func checkDataConformsInterface[I any](format *I, c *fiber.Ctx) error {
	if err := c.BodyParser(&format); err != nil {
		return err
	}
	err := c.JSON(format)
	if err != nil {
		return err
	}

	return nil
}

可以像这样调用

func CreateTask(c *fiber.Ctx) error {
	parsedData := CreateTaskDF{}
	err := checkDataConformsInterface[CreateTaskDF](&parsedData, c)
	if err != nil {
		c.SendStatus(400)
		return c.SendString("Wrong data")
	}

如果有问题,请指出。

英文:

So I came up with the following solution

func checkDataConformsInterface[I any](format *I, c *fiber.Ctx) error {
	if err := c.BodyParser(&amp;format); err != nil {
		return err
	}
	err := c.JSON(format)
	if err != nil {
		return err
	}

	return nil
}

which can be called like

func CreateTask(c *fiber.Ctx) error {
	parsedData := CreateTaskDF{}
	err := checkDataConformsInterface[CreateTaskDF](&amp;parsedData, c)
	if err != nil {
		c.SendStatus(400)
		return c.SendString(&quot;Wrong data&quot;)
	}

Please, point me the problems if any

huangapple
  • 本文由 发表于 2022年4月3日 01:08:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/71719574.html
匿名

发表评论

匿名网友

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

确定