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

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

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

问题

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

package main

import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

type User struct {
	Name string `name`
	Age  int64  `age`
}

func main() {
	var u User = User{"bob", 10}

	res, err := JSONEncode(u)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(res))

}

func JSONEncode(v interface{}) ([]byte, error) {
	refObjVal := reflect.ValueOf(v)
	refObjTyp := reflect.TypeOf(v)
	buf := bytes.Buffer{}
	if refObjVal.Kind() != reflect.Struct {
		return buf.Bytes(), fmt.Errorf(
			"不支持类型为%s的值",
			refObjVal.Kind(),
		)
	}
	buf.WriteString("{")
	pairs := []string{}
	for i := 0; i < refObjVal.NumField(); i++ {
		structFieldRefObj := refObjVal.Field(i)
		structFieldRefObjTyp := refObjTyp.Field(i)

		switch structFieldRefObj.Kind() {
		case reflect.String:
			strVal := structFieldRefObj.Interface().(string)
			pairs = append(pairs, `"`+string(structFieldRefObjTyp.Tag)+`":"`+strVal+`"`)
		case reflect.Int64:
			intVal := structFieldRefObj.Interface().(int64)
			pairs = append(pairs, `"`+string(structFieldRefObjTyp.Tag)+`":`+strconv.FormatInt(intVal, 10))
		default:
			return buf.Bytes(), fmt.Errorf(
				"不支持名称为%s和类型为%s的结构字段",
				structFieldRefObjTyp.Name,
				structFieldRefObj.Kind(),
			)
		}
	}

	buf.WriteString(strings.Join(pairs, ","))
	buf.WriteString("}")

	return buf.Bytes(), nil
}

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

{"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:

package main

import (
	&quot;bytes&quot;
	&quot;fmt&quot;
	&quot;reflect&quot;
	&quot;strconv&quot;
	&quot;strings&quot;
)

type User struct {
	Name string `name`
	Age  int64  `age`
}

func main() {
	var u User = User{&quot;bob&quot;, 10}

	res, err := JSONEncode(u)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(res))

}

func JSONEncode(v interface{}) ([]byte, error) {
	refObjVal := reflect.ValueOf(v)
	refObjTyp := reflect.TypeOf(v)
	buf := bytes.Buffer{}
	if refObjVal.Kind() != reflect.Struct {
		return buf.Bytes(), fmt.Errorf(
			&quot;val of kind %s is not supported&quot;,
			refObjVal.Kind(),
		)
	}
	buf.WriteString(&quot;{&quot;)
	pairs := []string{}
	for i := 0; i &lt; refObjVal.NumField(); i++ {
		structFieldRefObj := refObjVal.Field(i)
		structFieldRefObjTyp := refObjTyp.Field(i)

		switch structFieldRefObj.Kind() {
		case reflect.String:
			strVal := structFieldRefObj.Interface().(string)
			pairs = append(pairs, `&quot;`+string(structFieldRefObjTyp.Tag)+`&quot;:&quot;`+strVal+`&quot;`)
		case reflect.Int64:
			intVal := structFieldRefObj.Interface().(int64)
			pairs = append(pairs, `&quot;`+string(structFieldRefObjTyp.Tag)+`&quot;:`+strconv.FormatInt(intVal, 10))
		default:
			return buf.Bytes(), fmt.Errorf(
				&quot;struct field with name %s and kind %s is not supprted&quot;,
				structFieldRefObjTyp.Name,
				structFieldRefObj.Kind(),
			)
		}
	}

	buf.WriteString(strings.Join(pairs, &quot;,&quot;))
	buf.WriteString(&quot;}&quot;)

	return buf.Bytes(), nil
}

It works perfectly, and give output as:

{&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"的形式,例如:

type User struct {
    Name string `field:"name"`
    Age  int64  `field:"age"`
}
英文:

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

type User struct {
Name string `field:&quot;name&quot;`
Age  int64  `field:&quot;age&quot;`
}

答案3

得分: 3

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

type User struct {
    Name string `json:"name"`
    Age  int64  `json:"age"`
}
英文:

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

type User struct {
    Name string `json:&quot;name&quot;`
    Age  int64  `json:&quot;age&quot;`
}

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:

确定