更具体地说:
我有2位读者。一个是从os.Open(“ someExistingFile”)获取的,另一个是从strings.NewReader(“ hello world”)获取的。
其中一个实现了Name(),而另一个则没有。我想让另一个也实现Name()(例如,返回“”),或者(最好)仅在实际参数类型支持的情况下才调用Name()。
我希望下面的代码片段清楚地表明我要解决的问题。
我在不同的接收器之间玩耍,即使有反射,但我听不懂...
package main
import (
"io"
"os"
"strings"
)
func main() {
stringReader := strings.NewReader("hello world")
fileReader, _ := os.Open("someExistingFile") // error handling omitted
fileReader.Name()
printFilenameIfReaderIsFile(stringReader)
printFilenameIfReaderIsFile(fileReader)
}
func printFilenameIfReaderIsFile(reader io.Reader) {
// here I want to ...
// ... either check if this reader is of type os.File and in this case call its Name() method (preferred)
// ... or use a custom type instead of io.Reader.
// This type's Name() method should return the filename for fileReader and nil for stringReader.
}
答案 0 :(得分:2)
您正在寻找type switch控件结构。
您的printFilenameIfReaderIsFile
函数应如下所示(未实际检查):
func printFilenameIfReaderIsFile(reader io.Reader) {
switch f := reader.(type) {
case *os.File:
// f is now *os.File (not a os.File!)
fmt.Printf("%s\n", f.Name())
}
}
编辑:别忘了,os.Open
返回*os.File
而不是os.File
see docs!