英文:
Closing an io.Reader that might be an os.Stdin
问题
我正在尝试根据给定的文件名设置文件输入,如果没有给定文件名,则使用标准输入。我原以为可以这样做:
var input io.Reader
if filename == "" {
input = os.Stdin
} else {
input, err = os.Open(filename)
if err != nil {
log.Fatalf("failed to open file: %v", err)
}
}
传递给input
的函数期望符合io.Reader
接口的内容,并且一切都正常工作。以上代码是有效的...
直到我尝试找出一种关闭input
的方法。尽管os.Stdin和os.Open返回的两种方式都可以关闭(当然,关闭stdin可能并不真正有意义,但也是无害的)。但编译器不知道创建input
的两种方式都给我提供了实现Close()方法的内容。所以我想知道是否有一种方法可以告诉编译器Close()
方法已经实现了input
。
英文:
I am trying to set a file as input if a file name is given or use standard input if no file name is given. I would have thought that this is the way to do so:
var input io.Reader
if filename == "" {
input = os.Stdin
} else {
input, err = os.Open(filename)
if err != nil {
log.Fatalf("failed to open file: %v", err)
}
}
The function that is passed input
expects something that conforms to the io.Reader
interface and all behaves well. That is the above works ...
It works until I try to figure out a way to close input
. Although both things returned by os.Stdin and os.Open (sure, closing stdin might not really mean much, but it is harmless). The compiler doesn't know that both ways of creating input
give me something that implements Close(). So I was wondering there there is a way to tell the compiler that Close()
is implemented for input
.
答案1
得分: 4
使用 io.ReadCloser 来声明 input
具有 Read 和 Close 方法:
var input io.ReadCloser
if filename == "" {
input = os.Stdin
} else {
input, err = os.Open(filename)
if err != nil {
log.Fatalf("failed to open file: %v", err)
}
}
如果在函数返回之前关闭文件,另一种选择是使用 defer 关闭文件:
var input io.Reader
if filename == "" {
input = os.Stdin
} else {
f, err := os.Open(filename)
if err != nil {
log.Fatalf("failed to open file: %v", err)
}
defer f.Close()
input = f
}
英文:
Use io.ReadCloser to declare that input
has Read and Close methods:
var input io.ReadCloser
if filename == "" {
input = os.Stdin
} else {
input, err = os.Open(filename)
if err != nil {
log.Fatalf("failed to open file: %v", err)
}
}
If the file is closed just before return from the function, then another option is to defer the file close:
var input io.Reader
if filename == "" {
input = os.Stdin
} else {
f, err := os.Open(filename)
if err != nil {
log.Fatalf("failed to open file: %v", err)
}
defer f.Close()
input = f
}
答案2
得分: 0
在撰写问题并努力解释清楚的过程中,我意识到使用以下方式声明输入可以解决问题:
var input *os.File
我在开始撰写问题之前没有注意到os.Stdin
的类型。因此,我根据将使用该输入的函数所需的最通用接口声明了input
。
英文:
Well in the course of writing up my question for others and working to spell things out, I realized that declaring input with
var input *os.File
fixes everything.
I have failed to look at the type of os.Stdin
until I started to write up the question. And so I declared input
in terms of the most general interface required by the function that will use it.
答案3
得分: -1
要检查io.Reader
是否实现了Close
方法,可以使用类型断言,代码如下:
if closer, ok := reader.(io.Closer); ok {
err := closer.Close()
}
这段代码会将reader
转换为io.Closer
类型,并检查转换是否成功。如果成功,就可以调用Close
方法关闭reader
。
英文:
The way to check if an io.Reader
implements Close
is to use type assertion as:
if closer, ok:=reader.(io.Closer); ok {
err:=closer.Close()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论