SoFunction
Updated on 2025-03-04

Detailed explanation of the basic usage methods of GoLang

1. Basic knowledge

andSame,It's also out of the box.

The purpose of type is mainly to serve as a buffer for byte sequences.

Inside,The type uses a byte slice as the content container and has a field of type int as a read count, which cannot be passedThe provided method is calculated.

	var buffer1 
	contents := "Simple byte buffer for marshaling data"
  // Write contents "Simple byte buffer for marshaling data"
	("Write contents %q\n", contents)
	(contents)
  // The length of buffer: 38
	("The length of buffer: %d\n", ())
  // The capacity of buffer: 64
	("The capacity of buffer: %d\n", ())

andLike the Len method of type, the Len method of buffer1 also returns the length of the unread part in the content container, rather than the total length of the content already stored therein.

The length of the Buffer value is the length of the unread content, not the length of the read content.

	p1 := make([]byte, 7)
	n, _ := (p1)
	// 7 bytes were read. (call Read)
	("%d bytes were read. (call Read)\n", n)
	// The length of buffer: 31
	("The length of buffer: %d\n", ())
	// The capacity of buffer: 64
	("The capacity of buffer: %d\n", ())

The capacity of the Buffer value is the capacity of its content container (that is, that byte slice), which is only related to the write operations above the current value and continues to grow as the content is written.

2. The function of the read count of the type value

When reading content, the corresponding method will find the unread content based on the read count and update the count after reading;

The corresponding methods include all methods whose names start with Read, as well as Next and WriteTo methods.

When writing content, if capacity expansion is required, the corresponding method will implement the capacity expansion strategy based on the read count;

When writing, if there is not enough capacity, the container will be expanded.

When expanding, the method will find the unread part based on the read count when necessary and copy the contents to the head of the expansion container. The method then sets the read count value to 0.

The corresponding methods include all methods whose names start with Write, and ReadFrom methods.

When truncating the content, the read count when the corresponding method truncates represents the unread part after the index;

Truncate, the truncation method, accepts an int-type parameter, indicating how many bytes of the header need to be retained during truncation.

The head here is the head of the unread part, not the head of the content container.

In this case, the sum obtained after the read count value plus the parameter value is the new total length of the content container.

When reading back, the corresponding method will use the read count to record the fallback point;

The methods used for readback are UnreadByte and UnreadRune. These two methods are used to fall back one byte and fall back one Unicode character respectively.

The premise of a fallback is that the operation before they are called must be a "read" and is a successful read, otherwise these methods will only ignore subsequent operations and return a non-nil error value.

The UnreadRune method can be successfully completed only after the ReadRune method is called.

When resetting the content, the corresponding method will set the read count to 0;

When exporting content, the corresponding method will only export the unread part after the index represented by the read count;

The Bytes and String methods of the Buffer value will only access the content of the unread part and return the corresponding result value.

When obtaining the length, the corresponding method will calculate the length of the unread part based on the read count and the length of the content container and return it;

The Len method of the Buffer value returns the length of the unread part of the content container.

3. Scaling expansion strategy

It can be manually expanded or automatically expanded. Unless you have completely determined the number of bytes required for subsequent content, just let the Buffer automatically expand. The expansion strategies of these two methods are the same.

Scaling strategy:

Determine whether the remaining capacity of the content container meets the caller's requirements, and whether it is sufficient to accommodate new content;

If the remaining capacity satisfies the new content, the length expansion will be performed on the current content container;

buf = buf[:length+need]

If the remaining capacity does not meet the capacity to accommodate new content, the new content container will be replaced by the original content container, thereby achieving capacity expansion;

Here is an optimization, if half of the capacity of the current content container is still greater than or equal to the existing length (i.e., the number of unread bytes) plus the sum of the number of other bytes, i.e.:

cap(buf)/2 >= len(buf) + need

Then the expansion code will reuse the existing content container and copy the unread content in the container to its head position.

This means that all read contents in it will be overwritten by unread contents and new contents afterwards.

If the capacity of the current content container is less than twice the new length. At this time, the unread content in the original container will be copied in, and finally the original container will be replaced with a new container. This new container will be twice the original capacity, plus the sum of the number of bytes required.

Capacity of the new container = original capacity * 2 + required bytes

The capacity expansion will also set the read count to 0.

For a Buffer value in a zero-value state, if the number of bytes required for the first expansion is less than or equal to 64, the value will create a content container based on a predefined byte array of length 64.

In this case, the capacity of the container is 64. The purpose of this is to make the Buffer value quickly prepare when it is just used.

4. Which methods will cause the content to be leaked

Content leakage here means that the party using the Buffer value obtains content that should not have been obtained through some non-standard method.

existIn this article, both the Bytes method and the Next method may cause the content to be leaked. The reason is that they all return slices based on content containers directly to the caller of the method.

Through slices, we can directly access and manipulate their underlying arrays, whether this slice is obtained based on a certain array or is obtained by slicing operations on another slice.

The byte slices returned by the Bytes method and Next method are obtained by slicing the slices of the content container.

	contents := "ab"
	buffer1 := (contents)
	// The capacity of new buffer with contents "ab": 8
	// Why is the capacity 8? See runtime/#stringtoslicebyte()	("The capacity of new buffer with contents %q: %d\n", contents, ())
	unreadBytes := ()
	// The unread bytes of the buffer: [97 98]
	("The unread bytes of the buffer: %v\n", unreadBytes)
	("cdefg")
	// The capacity of new buffer with contents "ab": 8
	("The capacity of new buffer with contents %q: %d\n", contents, ())
	unreadBytes = unreadBytes[:cap(unreadBytes)]
	// Get the result value based on the previous content	// The unread bytes of the buffer: [97 98 99 100 101 102 103 0]
	("The unread bytes of the buffer: %v\n", unreadBytes)
	// Manipulate the buffer	unreadBytes[len(unreadBytes)-2] = byte('X')
	// The unread bytes of the buffer: [97 98 99 100 101 102 88 0]
	("The unread bytes of the buffer: %v\n", unreadBytes)

This is the end of this article about the detailed explanation of the basic usage methods of GoLang. For more related Go content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!