如何为2个(或更多)类型的联合实现接口?

时间:2019-02-03 00:33:28

标签: go

更具体地说:

我有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.
}

1 个答案:

答案 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