net.Conn是否存在可恢复的读取错误?

If the .Read() method of a net.Conn returns an error, does this imply that future reads also will fail with an error? Or are there recoverable errors? If so, how do I know whether/when to retry reads?

See the specific error type of the net package https://golang.org/pkg/net/#OpError

It provides a specific Temporary() method to figure out if it is a non-terminal error.

To manually figure out which error is Temporary you have to go through each defined error within the net, os and some other internal packages.

To programmatically check for a temporary error, you might declare your own local temporary interface{ Temporary() bool }, or you can rely on this interface provided by the net package https://golang.org/pkg/net/#Error

The OpError.Temporary method test if its internal error implements the net.temporary interface (https://golang.org/src/net/net.go?s=16056:16090#L501), and if so returns the result of the call to Temporary() of the internal error, for example https://golang.org/src/net/net.go?s=19122:19157#L605.

I am unsure which read retry you are thinking about, however, internal fd.read methods implements retries for eagain https://golang.org/src/internal/poll/fd_unix.go#L165

In general, you're not going to have any errors from a conn.Read operation that can be retried. Most uses of the io.Reader interface will assume that all errors are final.

Any net package errors that are assured to be retry-able will conform to the net.Error interface, and expose a Temporary method.

This is most often used in an Accept loop, like this paraphrased example from the http package

for {
    rw, e := l.Accept()
    if e != nil {
        if ne, ok := e.(net.Error); ok && ne.Temporary() {
            if tempDelay == 0 {
                tempDelay = 5 * time.Millisecond
            } else {
                tempDelay *= 2
            }
            if max := 1 * time.Second; tempDelay > max {
                tempDelay = max
            }
            time.Sleep(tempDelay)
            continue
        }
        return e
    }
}

Any other possible cases need to be handled on an individual basis, with knowledge of the protocol and situation at hand.

Timeout is the only recoverable error on read from a net.Conn and that error will only be returned when a read deadline is set on the connection.

Use Error.Timeout() to check for timeouts:

 n, err := c.Read(buf)
 // process buf[:n] bytes
 if e.(net.Error); ok && e.Timeout() && e.Temporary() {
    // handle recoverable read deadline expiration
 } else if err != nil {
    // handle other errors
 }