【问题标题】:Writing a struct's fields and values of different types to a file in Go在 Go 中将结构的不同类型的字段和值写入文件
【发布时间】:2017-04-16 13:21:54
【问题描述】:

我正在编写一个简单的程序,它接收来自表单的输入,用接收到的数据填充结构的实例,并将接收到的数据写入文件。

我现在有点卡住了,想找出迭代填充结构并将其内容写入文件的最佳方法。

有问题的结构包含 3 种不同类型的字段(整数、字符串、[] 字符串)。

我可以遍历它们,但我无法获得它们的实际类型。

用 print 语句检查我在下面发布的代码会发现它们的每种类型都作为结构返回,而不是前面提到的字符串、int 等。

所需的输出格式是纯文本。

例如:

field_1="value_1"
field_2=10
field_3=["a", "b", "c"]

有人有什么想法吗?也许我完全走错了路?

func (c *Config) writeConfigToFile(file *os.File) {

    listVal := reflect.ValueOf(c)
    element := listVal.Elem()

    for i := 0; i < element.NumField(); i++ {
        field := element.Field(i)
        myType := reflect.TypeOf(field)

        if myType.Kind() == reflect.Int {
            file.Write(field.Bytes())
            } else {
                file.WriteString(field.String())
            }
        }
}

【问题讨论】:

  • reflect.Value.Bytes 不会返回您认为返回的内容。见这里golang.org/pkg/reflect/#Value.Bytes
  • 您希望生成的文件是什么格式? JSON、XML 还是纯文本?如果是纯文本,您希望如何格式化数据?一切都在一条线上?还是每个字段一行?以及如何格式化切片?
  • 只是为了扩展我的第一条评论,如果您的字段是 int 类型,在其 reflect.Value 上调用 Bytes 会恐慌,因为 Bytes 方法仅适用于类型为[]byte。这是一个例子play.golang.org/p/g4UWNhbbzM
  • @mkopriva 格式将是纯文本 - 我已编辑问题以包含更多详细信息。

标签: go struct


【解决方案1】:

您可以使用strconv 包或fmt 来格式化您的字段,而不是使用reflect.Value 上的Bytes 方法(它不能按您最初的预期工作)。

这是一个使用fmt的例子:

var s string
switch fi.Kind() {
case reflect.String:
    s = fmt.Sprintf("%q", fi.String())
case reflect.Int:
    s = fmt.Sprintf("%d", fi.Int())
case reflect.Slice:
    if fi.Type().Elem().Kind() != reflect.String {
        continue
    }

    s = "["
    for j := 0; j < fi.Len(); j++ {
        s = fmt.Sprintf("%s%q, ", s, fi.Index(i).String()) 
    }
    s = strings.TrimRight(s, ", ") + "]"
default:
    continue
}

sf := rv.Type().Field(i)
if _, err := fmt.Fprintf(file, "%s=%s\n", sf.Name, s); err!= nil {
    panic(err)
}

游乐场:https://play.golang.org/p/KQF3CicVzA

【讨论】:

    【解决方案2】:

    为什么不使用built-in gob package 来存储您的结构值?

    我用它在文件中存储不同的结构,每行一个。在解码期间,您可以测试类型转换或在包装器中提供提示 - 对于您的给定用例,以更快的速度为准。

    在回读行时,在编码和解码时,您会将每一行视为缓冲区。您甚至可以实时地对流进行 gzip/zlib/压缩、加密/解密等。

    如果您已经拥有一个抛光且装甲齐全的轮子,那么重新发明轮子是没有意义的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-23
      • 2014-07-19
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 2016-02-04
      • 1970-01-01
      相关资源
      最近更新 更多