在使用套接字时重用读取缓冲区

I'd like to know the proper way to reuse the []byte buffer in go. I declare it like this

buf := make([]byte, 1024)

and then use like this

conn, _ := net.Dial("tcp", addr)
_, err = conn.read(buf)

I heard that declaring a new buffer isn't efficient since it involves memory allocations and that we should reuse existing buffers instead. However I am not sure if I just can pass the buffer again and it will be wiped or it can hold parts of previous messages (especially if the current message from socket is shorter than prev.one)?

In practice you rarely use io.Reader.Read(), instead you pipe it down where io.Reader needed in code. Buffer will not be wiped, you must do it by hand. Or if you want a buffer you can use bufio

conn, _ := net.Dial("tcp", addr)
r:=bufio.NewReader(conn)

which you can

r.WriteTo(io.Writer) //for example for further processing

and you can reset

r.Reset(NewConn)

Package io

import "io"

type Reader

type Reader interface {
        Read(p []byte) (n int, err error)
}

Reader is the interface that wraps the basic Read method.

Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.

When Read encounters an error or end-of-file condition after successfully reading n > 0 bytes, it returns the number of bytes read. It may return the (non-nil) error from the same call or return the error (and n == 0) from a subsequent call. An instance of this general case is that a Reader returning a non-zero number of bytes at the end of the input stream may return either err == EOF or err == nil. The next Read should return 0, EOF.

Callers should always process the n > 0 bytes returned before considering the error err. Doing so correctly handles I/O errors that happen after reading some bytes and also both of the allowed EOF behaviors.

Implementations of Read are discouraged from returning a zero byte count with a nil error, except when len(p) == 0. Callers should treat a return of 0 and nil as indicating that nothing happened; in particular it does not indicate EOF.

Implementations must not retain p.

Read may use all of the buffer as scratch space during the call.

For example,

buf := make([]byte, 4096)
for {
    n, err := r.Read(buf[:cap(buf)])
    buf = buf[:n]
    if err != nil {
        // handle error
    }
    // process buf
}

The Read method reads up to the len(buf) bytes to the buffer and returns the number of bytes read.

The Read method does not modify length of the caller's slice. It cannot because the slice is passed by value. The application must use the returned length to get a slice of the bytes actually read.

n, err = conn.Read(buf)
bufRead := buf[:n]

The application can call Read multiple times using the the same buffer.

conn, err := net.Dial("tcp", addr)
if err != nil {
    // handle error
}

buf := make([]byte, 1024)
for {
    n, err = conn.Read(buf)
    if err != nil {
        // handle error
    }
    fmt.Printf("Read %s
", buf[:n]) // buf[:n] is slice of bytes read from conn
}