英文:
How to iterate list of Charmaps in charmap.All and compare names?
问题
我想写一个小的命令行实用程序来解码/编码文本流,类似于 iconv
,但是使用 Go 语言。用户将提供编码器和解码器的名称,实用程序将使用 charmap.All
来检查它们是否有效,然后再尝试解码/编码流。
我可以遍历 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 {
// 根据用户的输入进行编码
}
}
在 encoding/charmap API 的帮助下,这种操作是否可行?
另外,为什么我的 cmap
变量和 charmap.ISO8859_1
是等价的(在 cmap == charmap.ISO8859_1
的示例中),但是 cmap
实际上是一个 Encoding 接口,我无法进行转换:
charmap.Charmap(cmap).String()
→ 无法将类型为 encoding.Encoding 的 cmap 转换为类型 charmap.Charmap
我对 Go 语言还不太熟悉,对于类型和接口之间的这些差异和等价性还不太理解。
英文:
I'd like to write a little command-line utility to decode/encode streams of text, like iconv
, but in Go. The user will provide the encoder and decoder names and the utility will check them against charmap.All
to make the user args are valid before trying to decode/encode the stream.
I can iterate charmap.All
and print the names like:
for _, cmap := range charmap.All {
fmt.Println(cmap)
}
I can compare my cmap
var to a known Charmap:
if cmap == charmap.ISO8859_1 {
fmt.Println(charmap.ISO8859_1.String())
}
But I don't know how to do the next step, which seems so tantalizingly close (and easy):
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
}
}
Is that possible, given the encoding/charmap API?
Also, how is it that my cmap
var and charmap.ISO8859_1
are equivalent (in the cmap == charmap.ISO8859_1
example), but cmap
is really an Encoding interface, and I cannot convert:
charmap.Charmap(cmap).String()
→ cannot convert cmap (type encoding.Encoding) to type charmap.Charmap
I'm still pretty new to Go, and don't fully understand these differences and equivalencies in types and interfaces.
答案1
得分: 3
你可以按如下方式进行拆解,charmap.All 是一个 Encoding 接口的切片,可以使用 range
循环进行迭代。
相等性成立是因为 Charmap 类型实现了该接口,也就是说每个 charmap 类型都会有一个定义了 NewDecoder()
和 NewEncoder()
方法实现的接口。根据语言规范,如果一个结构体实现了一个接口,它们可以进行比较(参见比较运算符)。
> 当非接口类型 X 的值 x 和接口类型 T 的值 t 可比较时,当类型 X 可比较且 X 实现了 T 时,它们是可比较的。如果 t 的动态类型与 X 相同且 t 的动态值等于 x,则它们相等。
通过上述推断,我们可以理解 func (*Charmap) String 是 Charmap
结构体类型的方法,而不是接口的方法。因此,正确的做法是对接口值进行类型断言,然后在其上调用字符串函数。
for _, enc := range charmap.All {
cmap, ok := enc.(*charmap.Charmap)
if ok && cmap.String() == encoder {
// 根据用户的输入进行编码
}
}
英文:
You can break it down as follows, charmap.All is a slice of Encoding interfaces, which can be iterated using a range
loop.
The equality works because the type 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
With the above inference, we can understand that the 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 your interface value and then call the string function on the same.
for _, enc := range charmap.All {
cmap, ok := enc.(*charmap.Charmap)
if ok && cmap.String() == encoder {
// encode based on user's input
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论