Go language learning 8-interface type

3.Go language data types

In the last article, we learned about the function types of the Go language , and this article mainly understands the interface types. Mainly as follows:

3.6 Interface

A Go language interface is represented by a collection of methods. As long as a data type (or a pointer type corresponding thereto) is an accompanying set of methods of an interface method set superset , then it can be determined that the type implements this interface.

3.6.1 Type notation

The declaration of the interface type consists of several method declarations. The method declaration consists of the method name and method signature . Duplicate method names are not allowed in the declaration of an interface type.

Interface type is the collective name for all custom interface types. Taking the interface type Interface in the standard library code package sort as an example, the declaration is as follows:

type Interface interface {
    Len() int
    Less(i, j int) bool
    Swap(I, j int)
}

In Go language, one interface type can be embedded in another interface type. The following interface type declaration:

type Sortable interface {
    sort.Interface
    Sort()
}

The above interface type Sortable actually contains 4 method declarations, namely Len , Less , Swap and Sort .

Go language does not provide a typical type-driven subclassing method, but it uses this embedded method to achieve the same effect. Type embedding also embodies the non-embedded style, which is also applicable to the structure types described below.

Note : An interface type only accepts embedding of other interface types.

Regarding the embedding of the interface, one constraint is that it cannot embed itself , including direct embedding and indirect embedding .

Embed directly as follows:

type Interface1 interface {
    Interface1
}

The indirect embedding is as follows:

type Interface2 interface {
    Interface3
}

type Interface3 interface {
    Interface2
}

Wrong interface embedding will cause compilation errors. In addition, the method declared in the current interface type cannot have the same name as any method of the interface type embedded in it, otherwise it will cause compilation errors.

As for a special interface type defined by the Go language-the empty type interface{} , as mentioned earlier, it is an interface that does not contain any method declarations. Moreover, all data types in the Go language are its implementations.

3.6.2 Value notation

There is no corresponding value notation for the interface type of the Go language, because the interface is a specification rather than an implementation. However, a variable of an interface type can be assigned the value of any data type that implements this interface type, so the value of the interface type can be represented by the value of any other data type that implements this interface type.

3.6.3 Properties and basic operations

The most basic attribute of an interface is their method collection.

The implementation of an interface type can be any custom data type, as long as the method set attached to this data type is a superset of the method set of the interface type. Write a custom data type SortableStrings , as follows:

type SortableStrings [3]string

The above custom data type is equivalent to an alias type of [3] string type. Now if you want this custom data type to implement the sort.Interface interface type, you need to implement all the methods declared in sort.Interface . The implementation of these methods requires the type SortableStrings as the receiver type. The declarations of these methods are as follows:

func (self SortableStrings) Len() int {
    return len(self)
}

func (self SortableStrings) Less(i, j int) bool {
    return self[i] < self[j]
}

func (self SortableStrings) Swap(i, j int) {
    self[i], self[j] = self[j], self[i]
}

With the declaration of the above three methods, the SortableStrings type is already an implementation of the sort.Interface interface type. Use the type assertion expression verification described in the Go language study note 2 to write the code as follows:

_, ok := interface{}(SortableStrings{}).(sort.Interface)

Note : To make this statement compile and pass, you first need to import the standard code package sort.

On the right side of the above assignment statement is a type assertion expression, and the two identifiers on the left represent the evaluation result of this expression. Here we don’t care about the result of the conversion, only whether the type conversion is successful, so the first identifier is an empty identifier "_" ; the second identifier ok represents a Boolean variable, true means the conversion is successful, false means Conversion failed. The following figure shows that the result of ok is true , because the SortableStrings type does implement all the methods declared in the interface type sort.Interface .

Write picture description here

An interface type can be implemented by any number of data types. A data type can also implement multiple interface types at the same time.

The above custom data type SortableStrings can also implement the interface type Sortable . Write a method declaration as follows:

func (self SortableStrings) Sort() {
    sort.Sort(self)
}

Now, the SortableStrings type implements the interface type Sort.Interface at the same time as the interface type Sortable . The type assertion expression is verified as follows:

_, ok2 := interface{}(SortableStrings{}).(Sortable)

The result of ok2 is true, as shown in the figure below:

Write picture description here

Now, the SortableStrings contained type Sort method from the recipient type SortableStrings to * SortableStrings , as follows:

func (self *SortableStrings) Sort() {
    sort.Sort(self)
}

The receiver type of this function has been changed to the pointer type corresponding to the SortableStrings type. The Sort method is no longer a value method, it has become a pointer method. Only the pointer value corresponding to the value of SortableStrings can pass the above type assertion, as follows:

_, ok3 := interface{}(&SortableStrings{}).(Sortable)

At this time , the value of ok2 is false and the value of ok3 is true , as shown in the figure below:

Write picture description here

Then add the following test code:

ss := SortableStrings("2", "3", "1")
ss.Sort()
fmt.Printf("Sortable strings: %v\n", ss)

For the usage of the standard library code package fmt that appears above , you can refer to http://docscn.studygolang.com/pkg/fmt

The test results are as follows:

Write picture description here

[2, 3, 1] in the information printed above is the string representation of the SortableStrings type value. From the above results, we can see that the value of the variable ss is not sorted, but the Sort method has been called before printing .

Let's listen to the explanation below
: As mentioned above, in the value method, the change to the receiver's value is invisible outside the method. The Sort method of the SortableStrings type actually sorts the receiver's values through the function sort.Sort . sort.Sort function accepts a type sort.Interface parameter value, and using this value method Len , Less , and Swap to modify the location of each element of its argument to complete the sorting job. For the SortableStrings type, although it implements all the methods declared in the interface type sort.Interface , these methods are all value methods, so the change in the receiver value in these methods does not affect its source value, but only changes It's just a copy of the source value.

For the above problem, the current solution is to SortableStrings type of method Len , Less , and Swap recipient types are changed to * SortableStrings , run the following figure shows the result of:

Write picture description here

But at this time, the SortableStrings type is no longer the implementation of the interface type sort.Interface , and * SortableStrings is the implementation of the interface type sort.Interface . As shown in the figure above , the value of ok is false .

Now we consider another solution, slightly changing the declaration of the SortableStrings type:

type SortableStrings []string //去掉了方括号中的3

At this time , the alias type of the array type of SortableStrings is actually changed to the alias type of the slice type, but it makes the current related methods unable to compile. The main errors are as follows:

Write picture description here

There are two main errors shown above. One is that the parameter of the built-in function len cannot be a pointer type value pointing to a slice value; the other is that index expressions cannot be applied to a pointer type value pointing to a slice value.

The following solution to this is to change the receiver types of the methods Len , Less , Swap and Sort from * SortableStrings back to SortableStrings . This is because the changed SortableStrings is a slice type, and the slice type is a reference type; for a reference type , the change of the value method to the receiver value will also be reflected in its source value. The following figure shows the modified result:

Write picture description here

For the code that appears in the above interface, you can click to download the Go source code file , modify it yourself, and experience the usage of the interface. You only need to put the following source code files in any package in the src directory of your workspace (the packages are meaningful), enter the command line and enter the above command in the file directory, of course, first of all your Go language environment variables Be well equipped.

This article will stop here, and the next article will continue the unfinished Go language data type...

Guess you like

Origin blog.51cto.com/huazie/2679339