如何迭代 charmap.All 中的 Charmap 列表并比较名称?

How to iterate list of Charmaps in charmap.All and compare names?

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

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

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

我可以将我的 cmap 变量与已知的 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 还是很陌生,还没有完全理解这些类型和接口的区别和等价。

可以分解如下,charmap.All is a slice of Encoding接口,可以用range循环迭代

相等性有效,因为类型 Charmap, implements the interface, i.e. each charmap type will have a NewDecoder() and a NewEncoder() method implementation defined. By the language specification, if a struct implements an interface, they can be compared (See Comparison operators)

A value x of non-interface type X and a value t of interface type T are comparable when values of type X are comparable and X implements T. They are equal if t's dynamic type is identical to X and t's dynamic value is equal to x

通过上面的推断,我们可以理解func (*Charmap) String is a method on the Charmap struct type and not on the interface. So the right way to do this, would be to Type assert你的接口值和调用string函数就一样了。

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