SoFunction
Updated on 2025-03-05

Detailed explanation of the core interface example of io package in Go language

Preface

IO operations are inevitable in programming, such as reading and writing files. The Go language io package provides related interfaces and defines corresponding specifications. Different data types can implement corresponding methods according to the specifications, providing richer functions.

The Go language advocates the combination of small interfaces + interfaces to extend the behavior of programs and increase program flexibility. The io code package can be used as such a benchmark, and it can become a reference standard when using this technique. The io package contains a large number of interfaces. In this article, we will first learn about the four core interfaces and the corresponding interface combination.

Reader

The interface defines the Read method to read data into a byte array:

  • Enter parameter: byte array p, the data will be read into p
  • Return value: the number of bytes read this time n, and the error encountered err
type Reader interface {
	Read(p []byte) (n int, err error)
}

Detailed explanation of the method and function

  1. Method read data and write it to byte array p. Since p is of size, it can read up to len(p) bytes at a time.
  2. The method returns the number of data bytes n(0 <= n <= len(p)) read, as well as the error encountered during the reading process.
  3. Even if the data read by one call is less than len(p), it may occupy the entire byte array p as temporary space.
  4. If the data volume of the data source is less than len(p) bytes, the method will only read the currently available data and will not wait for more data to arrive

When to return to error

  1. After successfully reading n (n>0) bytes, if error is generated or end-of-file is read, this call must return the number of bytes read n, but for the value of err, you can choose to return err directly this time (err!=nil), or return err (n=0, err!=nil) when the next call is called. A common example is that after reading n bytes, it reaches the end of the file (EOF). At this time, it can return err=EOF or err=nil, and the next call returns n=0, err=EOF.
  2. The caller needs to pay attention that after each call, if n>0, the data should be processed first, and then consider whether err is nil. Because the previous point has pointed out that if an error is encountered after reading n>0 bytes, it will return n>0 and err!=nil at the same time. At this time, the data needs to be processed first and then err is considered.

Method implementation and call attention to

  1. If you want to implement this method, it is not recommended to return both n=0 and err=nil, unless len(p)=0
  2. If the method is called returns n=0 and err=nil, it can be considered that nothing has happened, and it cannot be considered that it has been read to the end of the file (end-of-file)
  3. After implementing this method, do not hold the byte array p (keep the address for other use)

Writer

The interface defines the Write method, used to write data into a file

  • Enter parameter: byte array p, the data in p will be written to the file
  • Return value: the number of bytes that were successfully written to complete, and the error encountered err
type Writer interface {
	Write(p []byte) (n int, err error)
}

Detailed explanation of the method and function

  1. This method writes the data in p to a file
  2. Method returns the number of bytes that were successfully written n (0 <= n <= len(p)), as well as errors encountered during writing err
  3. If n<len(p), the method must return err!=nil
  4. The method must not modify the byte array p, and it will not be allowed even if it is temporarily modified.

Method implementation needs attention

After implementing this method, do not hold the byte array p, but just use it to read the data.

Closer

The interface defines the Close method, which is used to close the connection.

Method implementation needs attention

After calling the method for the first time, what behavior should be generated when calling the method again? The interface is not defined and depends on the implementation of method customization.

type Closer interface {
	Close() error
}

Seeker

The interface defines the Seek method, which specifies the offset when the next read or writes

Input parameter: calculate the starting value of the new offset, offset based on whence

Return value: New offset value calculated based on whence and offset, and possible errors

type Seeker interface {
	Seek(offset int64, whence int) (int64, error)
}

Detailed explanation of the method and function

The following three types of whences are defined in the io package

const (
	SeekStart   = 0 // Based on file start location	SeekCurrent = 1 // Based on the current offset	SeekEnd     = 2 // Based on file end location)

If the new offset is calculated, return error!=nil before the file start position

The offset of any positive number is legal, but how to perform I/O operations on the data source depends on the specific implementation method.

Combination interface

In the go language, the combination of interfaces can be used to encompass methods in other interfaces, similar to defining a parent interface and can contain multiple child interfaces. If a struct implements methods of all child interfaces, it is equivalent to implementing the parent interface. The method of combining small interfaces + interfaces greatly increases the flexibility of the program, and we can learn from this practice in our own business development process.

For the above four minimal granular interfaces, the io package defines the following combination interfaces:

// ReadWriter is a combination of Read and Write methodstype ReadWriter interface {
	Reader
	Writer
}

// ReadCloser is a combination of Read and Close methodstype ReadCloser interface {
	Reader
	Closer
}

// WriteCloser is a combination of Write and Close methodstype WriteCloser interface {
	Writer
	Closer
}

// ReadWriteCloser is a combination of Read, Write and Close methodstype ReadWriteCloser interface {
	Reader
	Writer
	Closer
}

// ReadSeeker is a combination of Read and Seek methodstype ReadSeeker interface {
	Reader
	Seeker
}

// WriteSeeker is a combination of Write and Seek methodstype WriteSeeker interface {
	Writer
	Seeker
}

// ReadWriteSeeker is a combination of Read, Write and Seek methodstype ReadWriteSeeker interface {
	Reader
	Writer
	Seeker
}

Summarize

This article introduces the four core interfaces in the io package:

  • Reader: Read data from a file into a byte array
  • Writer: Write data from a byte array to a file
  • Closer: Used to close the connection
  • Seeker: Given when and offset, a new offset is calculated to start reading and writing at a specific location.

It can be seen that the methods defined in the Reader and Writer interfaces all have byte array p, while the files to be operated at the bottom are not reflected in the method. The Read method is to read the data of the file into the byte array p, and Write is to write the data of the byte array p to the file. Don't worry about this.

This is the article about the core interface of the io package in Go language. For more related content of the io package in Go language, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!