We know that there are no inheritance in Go, the usage of the interface is different from the meanings of the Java, a lot of fit, we need to use the OO ideas to organize us to reach the project, but the Java OO thoughts will be more pain, in the Go Go the method and object oriented, but also many beginners to understand definition, For example, the definition of methods is outside the structure, and the assembly looks arbitrary. In fact, Go is only object-oriented, not really object-oriented language.
methods
Go supports several object-oriented programming features, and methods are one of those supported features. This article introduces various concepts related to methods in Go
Method statement
In Go, we can explicitly declare a method for type T and *T, where type T must satisfy four conditions:
-
T must be a defined type;
-
T must be defined in the same package as the method declaration;
-
T cannot be a pointer type;
-
T cannot be an interface type.
Types T and *T are called receiver types for their respective methods. Type T is called the receiver Base type for all methods declared by type T and *T.
If we declare a method for a type, we can later say that the type owns the method. A method declaration is similar to a function declaration, but with an extra parameter declaration section. This additional parameter declaration section can contain only one parameter of type the owner type of this method, called the receiver Parameter declared by this method. The owner argument declaration must be wrapped in a pair of parentheses (). The owner argument declaration section must be between the func keyword and the method name
Here is an example of a method declaration:
Age and int are two different types. We can't be int and *int
// Type declares methods, but can declare methods for Age and *Age types.
type Age int
func (age Age) LargerThan(a Age) bool {
return age > a
}
func (age *Age) Increase(a) {
*age++
}
// Declare methods for custom function type FilterFunc.
type FilterFunc func(in int) bool
func (ff FilterFunc) Filte(in int) bool {
return ff(in)
}
// Declare methods for the custom mapping type StringSet.
type StringSet map[string]struct{}
func (ss StringSet) Has(key string) bool {
_, present := ss[key]
return present
}
func (ss StringSet) Add(key string) {
ss[key] = struct{}{}
}
func (ss StringSet) Remove(key string) {
delete(ss, key)
}
Declare methods for the custom structure type Book and its pointer type *Book.
type Book struct {
pages int
}
func (b Book) Pages(a) int {
return b.pages
}
func (b *Book) SetPages(pages int) {
b.pages = pages
}
Copy the code
Each method corresponds to an implicitly declared function
For each method declaration, the compiler automatically implicitly declares a corresponding function. For example, for the two methods declared for the types Book and *Book in the example in the previous section, the compiler will automatically declare the following two functions:
func Book.Pages(b Book) int {
return b.pages // This function body is the same as the Pages method body of type Book
}
func (*Book).SetPages(b *Book, pages int) {
b.pages = pages // The body of this function is the same as that of the SetPages method of type *Book
}
Copy the code
In the above two implicit function declarations, the generic argument declarations of their corresponding method declarations are inserted first in the normal argument declarations. Their function bodies are the same as those of their corresponding explicit methods.
The two implicit function names book.pages and (*Book).setPages are both of the form aType.MethodName. We cannot explicitly declare functions with names of this form, because this form is not a legal identifier. Such functions can only be declared implicitly by the compiler. But we can call these implicitly declared functions in our code
Method Prototype and Method Set
A method prototype can be thought of as a function prototype without the func keyword. We can think of each method declaration as consisting of a func keyword, a owner parameter declaration part, a method stereotype, and a method body
Method values and method calls
Methods are actually special functions. Methods are also often referred to as member functions. When a type has a method, each value of that type has an unmodifiable member of the function type (similar to a struct’s field). The name of this member is the method name, and its type is the same as that of the function declaration in the method declaration that does not include the owner part. A member function of a value can also be called a method of that value.
A method call is actually a member function that calls a value. Suppose that a value v has a method named m, then the method can be represented by the selector syntax form v.m.
The following example shows how to call methods declared for Book and *Book types:
package main
import "fmt"
type Book struct {
pages int
}
func (b Book) Pages(a) int {
return b.pages
}
func (b *Book) SetPages(pages int) {
b.pages = pages
}
func main(a) {
var book Book
fmt.Printf("%T \n", book.Pages) // func() int
fmt.Printf("%T \n", (&book).SetPages) // func(int)
// &book values have an implicit method called Pages.
fmt.Printf("%T \n", (&book).Pages) // func() int
// Call these three methods.
(&book).SetPages(123)
book.SetPages(123) // equivalent to the previous line
fmt.Println(book.Pages()) / / 123
fmt.Println((&book).Pages()) / / 123
}
Copy the code
Just like ordinary parameter transmission, parameter transmission is a value replication process. Therefore, the modification of the direct part of the main parameter in the method body will not be reflected in the method body
reference
More details can be viewed gfw.go101.org/article/101… Check your profile for more.