英文:
How can I get os.Errno from os.Error? Other ways to use os.Timeout?
问题
The net.Conn interface provides the SetTimeout methods and I am supposed to check the returned error with os.Timeout. However I see no way of calling os.Timeout on the returned os.Error.
(The os.Error I've got is read unix @: Resource temporarily unavailable
which seem to consists of two parts: description of the function which timed out and the strerror
description of the EAGAIN
. I've tried err == os.EAGAIN
and it doesn't work, probably because of the extra information in os.Error).
英文:
The net.Conn interface provides the SetTimeout methods and I am supposed to check the returned error with os.Timeout. However I see no way of calling os.Timeout on the returned os.Error.
(The os.Error I've got is read unix @: Resource temporarily unavailable
which seem to consists of two parts: description of the function which timed out and the strerror
description of the EAGAIN
. I've tried err == os.EAGAIN
and it doesn't work, probably because of the extra information in os.Error).
答案1
得分: 1
"An I/O Package"部分的Go教程中有以下代码片段:
func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) {
r, e := syscall.Open(name, mode, perm)
if e != 0 {
err = os.Errno(e)
}
return newFile(r, name), err
}
syscall.Open()
的签名如下:
func Open(path string, mode int, perm uint32) (fd int, errno int)
所以我认为可以安全地假设os.Error
仍然只是整数错误代码,只是添加了一些额外的内容,你检查它的方法是正确的。
为了调查为什么err == os.EAGAIN
对你不起作用,我会将错误打印为int
类型的值,然后在你的平台的errno.h
文件中搜索打印的值。
英文:
The "An I/O Package" section of the Go tutorial has this snippet:
func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) {
r, e := syscall.Open(name, mode, perm)
if e != 0 {
err = os.Errno(e)
}
return newFile(r, name), err
}
syscall.Open()
has this signature:
func Open(path string, mode int, perm uint32) (fd int, errno int)
So I think it's safe to assume os.Error
is still just that integer error code, just with the added fluff and your approach to check it is correct.
To investigate why err == os.EAGAIN
did not work for you, I'd print the error as a value of type int
and then grepped your platform's errno.h
file for the value printed.
答案2
得分: 0
你需要进行类型断言。假设kon是net.Conn类型,你将读取到缓冲区buf。然后:
if numread, err := kon.Read(buf); err != nil {
if val, ok := err.(os.Errno); ok {
if val.Timeout() {
println("连接到:", kon.RemoteAddr().String(), "超时。")
}
}
}
当然,这只是一个简要的想法。在实践中,你可能希望做一些更优雅(更复杂)的事情,并使用类型切换同时考虑更多情况。
英文:
You need to do a type assertion. Let's say kon is type net.Conn and you read into buffer buf. Then:
if numread, err := kon.Read(buf); err != nil {
if val, ok := err.(os.Errno); ok {
if val.Timeout() {
println("Connection to:", kon.RemoteAddr().String(), "timed out.")
}
}
}
That's of course only a gist of the idea. In practice you probably want to do something more elegant (aka more RL complexleete) and consider more cases at once with Type switches.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论