【问题标题】:How to iterate list of Charmaps in charmap.All and compare names?如何在charmap.All中迭代Charmaps列表并比较名称?
【发布时间】:2021-12-21 04:30:27
【问题描述】:

我想编写一个小命令行实用程序来解码/编码文本流,例如 iconv,但在 Go 中。用户将提供编码器和解码器名称,实用程序将根据charmap.All 检查它们,以使用户参数在尝试解码/编码流之前有效。

我可以迭代 charmap.All 并打印如下名称:

for _, cmap := range charmap.All {
    fmt.Println(cmap)
}

我可以将我的 cmap var 与已知的 Charmap 进行比较:

if cmap == charmap.ISO8859_1 {
    fmt.Println(charmap.ISO8859_1.String())
}

但我不知道下一步该怎么做,这似乎非常接近(而且容易):

var encoder string
flag.StringVar(&encoder, "encoder", "ISO 8859-1", "name of encoder")
flag.Parse()

for _, cmap := range charmap.All {
    if cmap.String() == encoder {
        // encode based on user's input
    }
}

考虑到 encoding/charmap API,这可能吗?

另外,我的cmap var 和charmap.ISO8859_1 是如何等效的(在cmap == charmap.ISO8859_1 示例中),但cmap 确实是一个编码 接口,我无法转换:

charmap.Charmap(cmap).String()cannot convert cmap (type encoding.Encoding) to type charmap.Charmap

我对 Go 还是很陌生,并没有完全理解类型和接口的这些差异和等效性。

【问题讨论】:

    标签: go text encoding charmap


    【解决方案1】:

    您可以将其分解如下,charmap.AllEncoding 接口的切片,可以使用range 循环进行迭代。

    平等之所以有效是因为Charmap 类型实现了接口,即每个charmap 类型将定义一个NewDecoder() 和一个NewEncoder() 方法实现。根据语言规范,如果一个结构实现了一个接口,它们可以进行比较(参见Comparison operators

    当类型 X 的值是可比较的并且 X 实现了 T 时,非接口类型 X 的值 x 和接口类型 T 的值 t 是可比较的。如果 t 的动态类型与 X 相同并且 t 的动态值是等于 x

    通过上面的推断,我们可以理解func (*Charmap) StringCharmap结构体类型上的方法,而不是接口上的方法。所以正确的做法是Type assert你的接口值,然后调用相同的字符串函数。

    for _, enc := range charmap.All {
        cmap, ok := enc.(*charmap.Charmap)
        if ok && cmap.String() == encoder {
            // encode based on user's input
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      相关资源
      最近更新 更多