Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 使用分隔符打印结构中的字段列表_String_Go_Struct - Fatal编程技术网

String 使用分隔符打印结构中的字段列表

String 使用分隔符打印结构中的字段列表,string,go,struct,String,Go,Struct,我有一个有三个字段的类型 type Person结构{ 名字字符串 姓氏字符串 年龄智力 } 创建实例并使用defaultfmt.Sprint()返回{John Smith 45}。然而,对于我的用例,我需要一个格式字符串John,Smith,45。不被大括号包围的逗号分隔的列表。是否有比以下方法更可重用和有效的方法: fmt.Sprintf(“%s,%s,%d”,x.FirstName,x.LastName,x.Age) 我将在其他类型中大量使用此方法,我更喜欢通用方法,而不必为我使用的每

我有一个有三个字段的类型

type Person结构{
名字字符串
姓氏字符串
年龄智力
}
创建实例并使用default
fmt.Sprint()
返回
{John Smith 45}
。然而,对于我的用例,我需要一个格式字符串
John,Smith,45
。不被大括号包围的逗号分隔的列表。是否有比以下方法更可重用和有效的方法:

fmt.Sprintf(“%s,%s,%d”,x.FirstName,x.LastName,x.Age)
我将在其他类型中大量使用此方法,我更喜欢通用方法,而不必为我使用的每种类型键入格式:

func asFields(数据接口{})字符串{
//这里的待办事项逻辑
}

包的谓词不支持确切的格式

最接近的是

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()
}
试一下上面的例子

请注意,这个
asFields()
函数处理所有结构类型,当然不仅仅是您的
Person
。当然,处理指针和struct-of-structs需要进行调整

另请注意,除此之外,您也可以使用Direct to the buffer(指向我们正在组装字符串的缓冲区):

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()
}
func asFields(数据接口{})字符串{
v:=反射值(数据)
b:=&strings.Builder{}
对于i:=0;i0{
b、 写字符串(“,”)
}
fmt.Fprint(b,v.Field(i.Interface())
}
返回b.String()
}

这当然会产生相同的结果(可能更快,也可能不更快,通过基准测试)。在上尝试。

我们可以使用这种方法吗,它只适用于
人员类型结构

输出:

John, Doe, 25
类似问题:

还要注意,它会产生反射成本,并且会比OP已经使用的静态解决方案慢。
package main

import (
    "fmt"
)

type Person struct {
    FirstName string
    LastName  string
    Age       int
}

func (p Person) String() string {
    return fmt.Sprintf("%s, %s, %d", p.FirstName, p.LastName, p.Age)
}

func main() {
    p := Person{FirstName: "John",LastName: "Doe", Age: 25}
    fmt.Printf("%v", p)
}
John, Doe, 25