我有一个包含三个字段的类型
type Person struct {
FirstName string
LastName string
Age int
}
Run Code Online (Sandbox Code Playgroud)
创建一个实例并使用默认fmt.Sprint()返回{John Smith 45}。但是对于我的用例,我需要一串 format John, Smith, 45。逗号分隔的列表,没有被大括号包围。有没有比以下更可重用和有效的方法:
fmt.Sprintf("%s, %s, %d", x.FirstName, x.LastName, x.Age)
Run Code Online (Sandbox Code Playgroud)
我将在其他类型中大量使用此方法,我更喜欢通用方法,而不必为我使用的每种类型输入格式:
func asFields(data interface{}) string {
// TODO logic here
}
Run Code Online (Sandbox Code Playgroud)
fmt包的动词不支持这种确切的格式。
最接近的是
s := fmt.Sprintf("%#v", p)
Run Code Online (Sandbox Code Playgroud)
它生成一个字符串,如:
main.Person{FirstName:"John", LastName:"Smith", Age:45}
Run Code Online (Sandbox Code Playgroud)
如果您确实需要您在问题中发布的内容,则可以使用反射来迭代字段并构建如下结果:
func asFields(data interface{}) string {
v := reflect.ValueOf(data)
b := &strings.Builder{}
for i := 0; i < v.NumField(); i++ {
if i > 0 {
b.WriteString(", ")
}
b.WriteString(fmt.Sprint(v.Field(i).Interface()))
}
return b.String()
}
Run Code Online (Sandbox Code Playgroud)
这确实给出了:
John, Smith, 45
Run Code Online (Sandbox Code Playgroud)
试试Go Playground上的例子。
请注意,此asFields()函数处理所有结构类型,当然不仅仅是您的Person. 当然,需要调整来处理指针和结构的结构。
另请注意,fmt.Sprint()您也可以使用fmt.Fprint()定向到我们组装字符串的缓冲区:
func asFields(data interface{}) string {
v := reflect.ValueOf(data)
b := &strings.Builder{}
for i := 0; i < v.NumField(); i++ {
if i > 0 {
b.WriteString(", ")
}
fmt.Fprint(b, v.Field(i).Interface())
}
return b.String()
}
Run Code Online (Sandbox Code Playgroud)
这当然会给出相同的结果(并且可能会或可能不会更快,对其进行基准测试)。在Go Playground上试一试。
| 归档时间: |
|
| 查看次数: |
281 次 |
| 最近记录: |