How to provide string formatting for structs?

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

How to provide string formatting for structs?

问题

我有一个名为Item的结构体:

type Item struct {
    Limit  int
    Skip   int
    Fields string
}

我想要获取字段名和值,并将它们拼接成一个字符串,类似于:

item := Item{
    Limit:  3,
    Skip:   5,
    Fields: "Value",
}

转换为字符串后的结果应该是:

"Limit=3&Skip=5&Fields=Value"

我尝试使用反射(reflections)将接口转换为字段值映射,但我想知道是否有更好的解决方案。谢谢!

m, _ := reflections.Items(data)
for k, v := range m {
    fmt.Printf("%s : %s\n", k, v)
}

我得到了以下结果:

Limit : %!s(int=3)
Skip : %!s(int=5)
Fields : Value
英文:

I've a struct called item

type Item struct {
    Limit int
    Skip int
    Fields string
}



item := Item {
            Limit: 3,
            Skip: 5,
            Fields: "Valuie",
    }

how could I get the field name, value and join it into a string.

something like:

item := Item {
            Limit: 3,
            Skip: 5,
            Fields: "Valuie",
    }

to a string something like

"Limit=3&Skip=5&Fields=Valuie"

And I've try reflections to get convert interface to field value map so far. Am I going the right way? Cause I think there might have some better solutions. And thanks!

m, _ = reflections.Items(data)
for k, v := range m {
	fmt.Printf("%s : %s\n", k, v)
}

I've got

Limit : %!s(int=3)
Skip : %!s(int=5)
Fields : Valuie

答案1

得分: 10

你可以使用%v代替%s。%s会假设是一个字符串,可以转换为字符串的内容(比如字节数组)或者具有String()方法的对象。
使用%v会检查类型并正确显示。

以下是使用%s和你的示例调用String()方法的示例:http://play.golang.org/p/bxE91IaVKj

英文:

You can use %v instead of %s. %s will assume a string, something that can be converted to a string (i.e. byte array) or an object with a String() method.
Using %v will check the type and display it correctly.

Example of the String() method call with %s with your example: http://play.golang.org/p/bxE91IaVKj

答案2

得分: 3

这里不需要使用反射。只需编写出你所拥有的类型的代码。

func (i *Item) URLValues() string {
    uv := url.Values()
    uv.Set("Limit", strconv.Itoa(i.Limit))
    uv.Set("Skip", strconv.Itoa(i.Skip))
    uv.Set("Fields", i.Fields)
    return uv.Encode()
}

这段代码简单易读,你不需要思考就能编写出来。除非你有很多类型需要转换为值,否则我甚至不会考虑基于反射的解决方案。

英文:

There's no need to use reflection for this. Just write out the code for the types you have.

func (i *Item) URLValues() string {
    uv := url.Values()
    uv.Set("Limit", strconv.Itoa(i.Limit))
    uv.Set("Skip", strconv.Itoa(i.Skip))
    uv.Set("Fields", i.Fields)
    return uv.Encode()
}

This code is simple, readable, and you don't need to think to write it. Unless you have a lot of types that you're going to be converting to values then I'd not even think about the magic reflection-based solution to this problem.

答案3

得分: 1

对于任何结构体,您可以使用反射和net/url包中的url.Values

i := Item{1, 2, "foo"}

v := url.Values{}
ri := reflect.ValueOf(i)

ri.FieldByNameFunc(func(name string) bool {
	v.Set(name, fmt.Sprintf("%v", ri.FieldByName(name).Interface()))
	return false
})

fmt.Println(v.Encode())

在playground上的示例

当然,这段代码不处理嵌套的数据结构或切片,所以如果您使用其他数据结构,您需要扩展代码以使其更通用。不过,这个示例应该能帮助您入门。

英文:

For any struct you can use reflection and url.Values from the net/url package:

i := Item{1, 2, "foo"}

v := url.Values{}
ri := reflect.ValueOf(i)

ri.FieldByNameFunc(func(name string) bool {
	v.Set(name, fmt.Sprintf("%v", ri.FieldByName(name).Interface()))
	return false
})

fmt.Println(v.Encode())

Example on play.

Of course, this code does not handle nested data structures or slices so you would need to extend
the code if you use other data structures to make it more general. However, this example should
get you started.

答案4

得分: 0

请看一下go-querystring。它可以将一个结构体转换为URL查询参数(你期望的输出)。

type Item struct {
  Limit  int    `url:"limit"`
  Skip   int    `url:"skip"`
  Fields string `url:"fields"`
}

item := Item {
  Limit: 3,
  Skip: 5,
  Fields: "Value",
}

v, _ := query.Values(item)
fmt.Print(v.Encode()) 
// 输出结果为:"limit=3&skip=5&fields=Value"

以上代码将输出:"limit=3&skip=5&fields=Value"。

英文:

Take a look at go-querystring. It converts a struct into URL query parameters (your expected output).

type Item struct {
  Limit  int    `limit:"limit"`
  Skip   int    `url:"skip"`
  Fields string `url:"fields"`
}

item := Item {
  Limit: 3,
  Skip: 5,
  Fields: "Valuie",
}

v, _ := query.Values(item)
fmt.Print(v.Encode()) 
// will output: "limit=3&skip=5&fields=Valuie"

huangapple
  • 本文由 发表于 2014年2月2日 10:09:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/21506216.html
匿名

发表评论

匿名网友

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

确定