Study Notes -container package those containers

Reference: https://time.geekbang.org/column/article/14117

1, then the list Go language is what it?

Go language implemented in the list of standard library container / list code package. This code package includes two entities --List and procedures disclosed Element, List implements a doubly linked list (hereinafter referred to as the list), and Element list represents the structure elements.

2, can generate their own values ​​to the list of types of Element it?

Here we used four methods of List.
MoveBefore MoveAfter methods and methods, which are given for the front and back elements to the other element. MoveToFront MoveToBack methods and methods, respectively, for the given element is moved to the forefront and the rearmost end of the list. In these processes, "given element" is the Element type, type Element Element type is a pointer type, * pointer value is the element of Element.

If we ourselves generate such value, and then use it as "a given element" method that the list, then what happens? The list will accept it anyway?

func (l *List) MoveBefore(e, mark *Element)
func (l *List) MoveAfter(e, mark *Element)

func (l *List) MoveToFront(e *Element)
func (l *List) MoveToBack(e *Element)

The answer: not to accept, these methods will not make any changes to the list. Because of our own generation Element value is not in the list, so it is far from "moving in the list of elements." Not to mention the list does not allow us to build yourself Element values ​​inserted.

In the method comprising List, a method for inserting a new element that accepts only the value type interface {}. These methods will be used internally Element value, a new element of the received package. Doing so precisely in order to avoid the direct use of the elements of our own generation, and the main reason is to avoid the associated internal linked list, the outside world has been destroyed, which lists itself as well as for those of us who are beneficial to users.

3. List the following method as well as these types:

Front and Back Methods for obtaining the list element most distal end and the last
InsertBefore InsertAfter and methods are used prior to the specified elements and inserting the new element after
PushFront PushBack and methods for insertion respectively in the forefront and the rearmost end of the list new element.

These methods will put a pointer Element values ​​returned as a result, they are left to our security chain "Interface." These internal pointers to get the elements, we can go call the method used to move the previously mentioned elements.

func (l *List) Front() *Element
func (l *List) Back() *Element

func (l *List) InsertBefore(v interface{}, mark *Element) *Element
func (l *List) InsertAfter(v interface{}, mark *Element) *Element

func (l *List) PushFront(v interface{}) *Element
func (l *List) PushBack(v interface{}) *Element

4, why the linked list can be done out of the box?

List and Element are the type of structure. Type structure has a feature that they have a value of zero will be the specific structure, but has no value any custom content, equivalent to an empty shell. Values ​​in the field will also be assigned a zero value of each type, respectively.

Broadly speaking, the so-called zero value is only a statement but has not yet done defaults initialized variables are given. Zero value of each type according to the types of features will be set. For example, the value after the statement var a [2] The variable int a declaration, will be an integer array containing two zero. As another example, the statement after var s [] value of the variable s, would be a statement int [] int slice type, the value is nil.

Then the value of the variable l after the statement var l list.List statement of what will be? [1] This zero value will be a length 0 of the list. This list will also hold a root element is an empty shell, which will contain the default content. Such a list that we can be directly used to use it?

The answer is: Yes. This is called "out of the box." Go language standard library structure many types of program entities have done it out of the box. This is also writing code package available for others to use (or library), we recommend one of the best practices to follow. So, the statement var l list.List declaration l list can be used directly, this is how to do it?

The key lies in its "lazy initialization" mechanism. The so-called lazy initialization, you can be understood as the initialization delay, is performed only when actually needed. Initialization advantage is that the delay "delay", which can be dispersed computation and storage space caused by consumption of the initialization operation.

For example, if we need to focus a lot of high-capacity declare slice, then the amount of CPU time and memory space will definitely a surge, and only managed to get their slice of the underlying array which is recovered, memory usage will decreased.

If the array is initialized may be delayed, the pressure of computation and memory space can be dispersed when they are actually used. These arrays are more dispersed actual time of use, the initialization delay the benefits will be more obvious.

Indeed, sliced ​​Go language played a lazy initialization of the role of the underlying array, you can think about the reason why say so. The disadvantage is that lazy initialization is precisely the "delayed." You can imagine, if if I was in the list of calling each method, they need to go to determine the list has been initialized, then this would be a waste of a computation. In the case of these methods is called very frequently, the impact of waste began to appear, the performance of the program will be reduced.

In the list to achieve here, some methods there is no need to make a judgment of whether to initialize. Front and Back methods such as a method, the length of the list if it is found to 0, like a direct return nil.

As another example, in a delete elements, moving elements, as well as some methods for inserting elements, as long as the incoming determine what belongs to the list of elements pointing pointer is equal to the current list pointer on it.

If not equal, it must explain the element passed in is not in this list, and follow-up operation would not have done. On the contrary, it must explain this list has been initialized.

The reason is that, PushFront list methods, PushBack, methods, PushBackList PushFrontList method and a method to determine the status of the list always and initialized, if necessary, which is a delay initialized.

Moreover, we add a new element to the list when empty, will certainly call one of these four methods, then point to the new element belongs list pointer, it will be set to the current pointer list. Therefore, the pointer is equal to the necessary and sufficient condition list has been initialized.

5, where the difference in the Ring and List?

container / ring package Ring type implements a circular chain, what we called the ring. In fact, within the List is a circular list. It holds the root element never any real value of the element, and that the presence of this loop is connected to both ends of the head and tail of the list element.

So it can be said, is a zero value List contains only the root element, but does not contain any actual empty list element values. Well, since the Ring cycle chain and List are, in essence, that they in the end what difference will it make?

(1) Ring type of data structure to represent only by itself, and the List type will Element and jointly represented by its type. This is different on the different ways, but also structural complexity.

(2) the value of a Ring type strictly speaking, represents only one element of circular linked list to which it belongs, and a value of type List represents a complete list. This was stated on different dimensions.
(3) create and initialize a Ring in value, we can specify the number of elements it contains, but for a List value but it can not do so (there is no need to do so). Once the circular linked list is created, whose length is immutable. This is the code included in New two different functions in function, but also a different type of the first two in terms of the initial value.
(4) only by declaration statement var r ring.Ring r will be a circular linked list of length 1, and a zero value is a List type of list 0 of length. Remember List root element not hold the actual value of the element, it is thus not included when calculating the length. This is the initialization of the second aspect of the two different types.
Len algorithm complexity method (5) Ring values is O (N), and the algorithm complexity Len List value method is O (1) is. This is both in terms of performance of the most obvious differences.
Other methods are basically different aspects of the. For example, the circular list is also used to insert, move, or delete elements of the method, but with some of them have become more abstract, and so on.

Extended knowledge:

[1]: List This type of structure has two fields, a type of field is the root Element, the other field is of type int len. As the name suggests, it is that the former represents the root element, and the length of which is used to store the linked list. Note that they are packet-level private, which means users can not view and modify them.

L as previously declared as its root and len field will be given a corresponding value of zero. Len zero value is 0, may indicate that the list has not just comprise any elements. , So its value is zero since this type of shell is root Element type, represented by the literal word is Element {}.

Element types include several package-level private field, respectively, for a storage element before, after, and belongs to a pointer value of the list element. There is also disclosed a field called Value, the role of this field is to hold the actual value of the element, which is the type of interface {}. Element type at a zero value, the values ​​of these fields will be nil.

Guess you like

Origin blog.51cto.com/daixuan/2450171