Check if any variable conforms any interface using generics in Go

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

Check if any variable conforms any interface using generics in Go

问题

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

错误信息如下:

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

我想这样调用该函数:

  1. type CreateTaskDF struct {
  2. Target string `json:"target"`
  3. Deepness int `json:"deepness"`
  4. }
  5. func CreateTask(c *fiber.Ctx) error {
  6. data, err := checkDataConformsInterface[CreateTaskDF](&CreateTaskDF{}, c)
  7. if err != nil {
  8. log.Fatal(err)
  9. }
  10. // 在这里处理数据
  11. ...

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

英文:

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.

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

The errors say

  1. src/endpoints/v1/tasks.go:36:10: cannot use nil as I value in return statement
  2. 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:

  1. type CreateTaskDF struct {
  2. Target string `json:"target"`
  3. Deepness int `json:"deepness"`
  4. }
  5. func CreateTask(c *fiber.Ctx) error {
  6. data, err := checkDataConformsInterface[CreateTaskDF](&CreateTaskDF{}, c)
  7. if err != nil {
  8. log.Fatal(err)
  9. }
  10. // work with data here
  11. ...

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

答案1

得分: 3

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

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

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:

  1. func checkDataConformsInterface[I any](format I, c *fiber.Ctx) bool {
  2. if err := c.BodyParser(&format); err != nil {
  3. return false
  4. }
  5. return true
  6. }
  7. </details>
  8. # 答案2
  9. **得分**: 1
  10. 所以我想出了以下解决方案
  11. ```go
  12. func checkDataConformsInterface[I any](format *I, c *fiber.Ctx) error {
  13. if err := c.BodyParser(&format); err != nil {
  14. return err
  15. }
  16. err := c.JSON(format)
  17. if err != nil {
  18. return err
  19. }
  20. return nil
  21. }

可以像这样调用

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

如果有问题,请指出。

英文:

So I came up with the following solution

  1. func checkDataConformsInterface[I any](format *I, c *fiber.Ctx) error {
  2. if err := c.BodyParser(&amp;format); err != nil {
  3. return err
  4. }
  5. err := c.JSON(format)
  6. if err != nil {
  7. return err
  8. }
  9. return nil
  10. }

which can be called like

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

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:

确定