string - 使用分隔符打印结构中的字段列表
问题描述
我有一个包含三个字段的类型
type Person struct {
FirstName string
LastName string
Age int
}
创建实例并使用默认fmt.Sprint()
返回{John Smith 45}
。但是对于我的用例,我需要一串格式John, Smith, 45
。没有被花括号包围的逗号分隔列表。有没有比以下更可重用和有效的方法:
fmt.Sprintf("%s, %s, %d", x.FirstName, x.LastName, x.Age)
我将在其他类型中大量使用此方法,并且我更喜欢通用方法,而不是必须为我使用的每种类型输入格式:
func asFields(data interface{}) string {
// TODO logic here
}
解决方案
包的动词不支持该确切格式fmt
。
最接近的是
s := fmt.Sprintf("%#v", p)
这会生成一个字符串,如:
main.Person{FirstName:"John", LastName:"Smith", Age:45}
如果您确实需要您在问题中发布的内容,您可以使用反射来迭代字段并构建如下结果:
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()
}
这确实给出了:
John, Smith, 45
试试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()
}
这当然会给出相同的结果(并且可能会或可能不会更快,对其进行基准测试)。在Go Playground上尝试一下。
推荐阅读
- json - 带双引号的 JSON 数据
- elasticsearch - 在具有多个节点的弹性搜索中创建快照时出现“只读文件系统”错误
- php - 文件获取内容花费太多时间
- c# - 我可以添加用于打印的纸张尺寸 (A6)
- c - 如何将项目添加到 while 循环内的 [500]][4] 数组
- android - 如何找到 React Native App 的包名
- javascript - 如何根据js中的父位置动态调整div大小
- javascript - 使用 VueJS 和 Firebase 检索和过滤子集合
- javascript - 视频字幕不起作用我的字幕文件是 .txt
- r - 检查两列的组合和两列的交换是否相同,为其创建一个数字