结构字段标签`name`与reflect.StructTag.Get不兼容:结构标签对的语法错误。

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

Struct field tag `name` not compatible with reflect.StructTag.Get: bad syntax for struct tag pair

问题

我阅读了这个,但它与我的情况不同,我有以下代码:

  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "reflect"
  6. "strconv"
  7. "strings"
  8. )
  9. type User struct {
  10. Name string `name`
  11. Age int64 `age`
  12. }
  13. func main() {
  14. var u User = User{"bob", 10}
  15. res, err := JSONEncode(u)
  16. if err != nil {
  17. panic(err)
  18. }
  19. fmt.Println(string(res))
  20. }
  21. func JSONEncode(v interface{}) ([]byte, error) {
  22. refObjVal := reflect.ValueOf(v)
  23. refObjTyp := reflect.TypeOf(v)
  24. buf := bytes.Buffer{}
  25. if refObjVal.Kind() != reflect.Struct {
  26. return buf.Bytes(), fmt.Errorf(
  27. "不支持类型为%s的值",
  28. refObjVal.Kind(),
  29. )
  30. }
  31. buf.WriteString("{")
  32. pairs := []string{}
  33. for i := 0; i < refObjVal.NumField(); i++ {
  34. structFieldRefObj := refObjVal.Field(i)
  35. structFieldRefObjTyp := refObjTyp.Field(i)
  36. switch structFieldRefObj.Kind() {
  37. case reflect.String:
  38. strVal := structFieldRefObj.Interface().(string)
  39. pairs = append(pairs, `"`+string(structFieldRefObjTyp.Tag)+`":"`+strVal+`"`)
  40. case reflect.Int64:
  41. intVal := structFieldRefObj.Interface().(int64)
  42. pairs = append(pairs, `"`+string(structFieldRefObjTyp.Tag)+`":`+strconv.FormatInt(intVal, 10))
  43. default:
  44. return buf.Bytes(), fmt.Errorf(
  45. "不支持名称为%s和类型为%s的结构字段",
  46. structFieldRefObjTyp.Name,
  47. structFieldRefObj.Kind(),
  48. )
  49. }
  50. }
  51. buf.WriteString(strings.Join(pairs, ","))
  52. buf.WriteString("}")
  53. return buf.Bytes(), nil
  54. }

它完美地工作,并输出为:

  1. {"name":"bob","age":10}

但在使用VS Code时,它给我以下问题:

结构字段标签`name`与reflect.StructTag.Get不兼容:结构标签对的语法错误。

可能是什么问题?

英文:

I read this, but it is different than my case, I've the below code:

  1. package main
  2. import (
  3. &quot;bytes&quot;
  4. &quot;fmt&quot;
  5. &quot;reflect&quot;
  6. &quot;strconv&quot;
  7. &quot;strings&quot;
  8. )
  9. type User struct {
  10. Name string `name`
  11. Age int64 `age`
  12. }
  13. func main() {
  14. var u User = User{&quot;bob&quot;, 10}
  15. res, err := JSONEncode(u)
  16. if err != nil {
  17. panic(err)
  18. }
  19. fmt.Println(string(res))
  20. }
  21. func JSONEncode(v interface{}) ([]byte, error) {
  22. refObjVal := reflect.ValueOf(v)
  23. refObjTyp := reflect.TypeOf(v)
  24. buf := bytes.Buffer{}
  25. if refObjVal.Kind() != reflect.Struct {
  26. return buf.Bytes(), fmt.Errorf(
  27. &quot;val of kind %s is not supported&quot;,
  28. refObjVal.Kind(),
  29. )
  30. }
  31. buf.WriteString(&quot;{&quot;)
  32. pairs := []string{}
  33. for i := 0; i &lt; refObjVal.NumField(); i++ {
  34. structFieldRefObj := refObjVal.Field(i)
  35. structFieldRefObjTyp := refObjTyp.Field(i)
  36. switch structFieldRefObj.Kind() {
  37. case reflect.String:
  38. strVal := structFieldRefObj.Interface().(string)
  39. pairs = append(pairs, `&quot;`+string(structFieldRefObjTyp.Tag)+`&quot;:&quot;`+strVal+`&quot;`)
  40. case reflect.Int64:
  41. intVal := structFieldRefObj.Interface().(int64)
  42. pairs = append(pairs, `&quot;`+string(structFieldRefObjTyp.Tag)+`&quot;:`+strconv.FormatInt(intVal, 10))
  43. default:
  44. return buf.Bytes(), fmt.Errorf(
  45. &quot;struct field with name %s and kind %s is not supprted&quot;,
  46. structFieldRefObjTyp.Name,
  47. structFieldRefObj.Kind(),
  48. )
  49. }
  50. }
  51. buf.WriteString(strings.Join(pairs, &quot;,&quot;))
  52. buf.WriteString(&quot;}&quot;)
  53. return buf.Bytes(), nil
  54. }

It works perfectly, and give output as:

  1. {&quot;name&quot;:&quot;bob&quot;,&quot;age&quot;:10}

But as VS code, it gives me the below problems:

结构字段标签`name`与reflect.StructTag.Get不兼容:结构标签对的语法错误。

What could be the issue?

答案1

得分: 7

请注意,这只是一个警告,告诉你没有遵循惯例。代码,正如你已经知道的那样,可以编译、运行,并输出你想要的结果:https://go.dev/play/p/gxcv8qPVZ6z。

为了避免这个警告,你可以禁用你的代码检查工具,或者更好的做法是按照惯例使用key:"value"在结构体标签中,然后使用Get方法提取值:https://go.dev/play/p/u0VTGL48TjO。


https://pkg.go.dev/reflect@go1.18.3#StructTag

结构体标签(StructTag)是结构体字段中的标签字符串。

按照惯例,标签字符串是可选地用空格分隔的key:"value"对的串联。 每个键是一个非空字符串,由非控制字符组成,除了空格(U+0020 ' ')、引号(U+0022 '"')和冒号(U+003A ':')。每个值都使用U+0022 '"'字符和Go字符串字面值语法进行引用。

英文:

Note that that's just a warning telling you that you're not following convention. The code, as you already know, compiles and runs and outputs the result you want: https://go.dev/play/p/gxcv8qPVZ6z.

To avoid the warning, disable your linter, or, better yet, follow the convention by using key:&quot;value&quot; in the struct tags and then extract the value by using the Get method: https://go.dev/play/p/u0VTGL48TjO.


https://pkg.go.dev/reflect@go1.18.3#StructTag

> A StructTag is the tag string in a struct field.
>
> By convention, tag strings are a concatenation of optionally
> space-separated key:"value" pairs.
Each key is a non-empty string
> consisting of non-control characters other than space (U+0020 ' '),
> quote (U+0022 '"'), and colon (U+003A ':'). Each value is quoted using
> U+0022 '"' characters and Go string literal syntax.

答案2

得分: 4

结构标签应该是key:"value",field:"name"的形式,例如:

  1. type User struct {
  2. Name string `field:"name"`
  3. Age int64 `field:"age"`
  4. }
英文:

Struct tag supposed to be a key:&quot;value&quot;, field:&quot;name&quot; for example.

  1. type User struct {
  2. Name string `field:&quot;name&quot;`
  3. Age int64 `field:&quot;age&quot;`
  4. }

答案3

得分: 3

你可以使用json:"keyname"来代替另一个回答中提到的field

  1. type User struct {
  2. Name string `json:"name"`
  3. Age int64 `json:"age"`
  4. }
英文:

instead of field as in another answer you can use json:&quot;keyname&quot;

  1. type User struct {
  2. Name string `json:&quot;name&quot;`
  3. Age int64 `json:&quot;age&quot;`
  4. }

huangapple
  • 本文由 发表于 2022年6月29日 18:38:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/72799988.html
匿名

发表评论

匿名网友

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

确定