如何为结构提供字符串格式?

时间:2014-02-02 02:09:39

标签: string struct go

我有一个名为item

的结构
type Item struct {
    Limit int
    Skip int
    Fields string
}



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

如何获取字段名称,值并将其加入字符串。

类似的东西:

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

到类似

的字符串
"Limit=3&Skip=5&Fields=Valuie"

到目前为止,我尝试将反射转换为字段值映射。我走对了路吗?因为我认为可能有更好的解决方案。谢谢!

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 : Valuie

4 个答案:

答案 0 :(得分:9)

您可以使用%v代替%s。 %s将假定一个字符串,可以转换为字符串(即字节数组)或具有String()方法的对象。 使用%v将检查类型并正确显示它。

带有%s的String()方法调用示例:http://play.golang.org/p/bxE91IaVKj

答案 1 :(得分: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()
}

此代码简单易读,您无需考虑编写代码。除非你有一个 lot 的类型,你将要转换为值,否则我甚至不会考虑基于魔法反射的解决方案。

答案 2 :(得分: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())

Example on play

当然,此代码不处理嵌套数据结构或切片,因此您需要扩展 代码,如果您使用其他数据结构使其更通用。但是,这个例子应该 让你开始。

答案 3 :(得分:0)

看看go-querystring。它将结构转换为URL查询参数(您的预期输出)。

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"