1 Overview
In object-oriented programming, an object is actually a simple value or a variable. This object will contain some functions. This function with the receiver is called a method. Essentially, a method is a function associated with a special type.
An object-oriented program will use methods to express its properties and corresponding operations, so that users who use this object do not need to operate the object directly, but use methods to do these things.
In Go, you can add corresponding methods to any custom type (including built-in types, but not pointer types).
The method always binds the object instance and implicitly takes the instance as the first parameter (receiver). The syntax of the method is as follows:
func (receiver ReceiverType) funcName (parameters) (results)
- The parameter receiver can be named arbitrarily. If not used in the method, the parameter name can be omitted.
- The parameter receiver type can be T or *T. Base type T cannot be an interface or pointer.
- Overloading methods are not supported, that is, methods with the same name but different parameters cannot be defined.
2Add method for type
2.1 Basic type as receiver
type MyInt int//Customize the type, change the name of int to MyInt// When defining a function, putting a variable before its name is a methodfunc (a MyInt) Add(b MyInt) MyInt {//Object-oriented return a + b } //Definition of traditional methodsfunc Add(a, b MyInt) MyInt {//Process-oriented return a + b } func main() { var a MyInt=1 // a := MyInt(1) equivalent var b MyInt=1 //Call func (aMyInt) Add(bMyInt)("(b)=",(b))//(b)=2 //Call func Add(a,bMyInt)("Add(a,b)=",Add(a,b))//Add(a,b)=2 }
From the above example, we can see that object-oriented is just a different syntax form to express. Methods are syntactic sugar of functions, because receiver is actually the first parameter received by the method.
Note: Although the names of the methods are exactly the same, if the recipients are different, then the methods are different.
2.2 Structure as receiver
The recipient's field can be accessed in the method, and the method is accessed through the point (. ), just like the field accessed in struct:
package main import "fmt" func main(){ jeff:=user{1,"jeff",18,"Shanghai"} ((10)) } // It is equivalent to defining the user classtype user struct { id int name string age int addr string } // Add the Add method and receive the parameter numfunc (p user) Add(num int)int{ () return +num }
3-value semantics and citation semantics
package main import "fmt" func main() { //Pointer as receiver, reference semantics jeff := Person{"jeff","male",18}//initialization ("Before function call=",jeff)//Before function call = {jeff male 18} (&jeff).Add() // Take effect, (&jeff) get the address of jeff (pointer) //() // Modification does not take effect ("After the function call=",jeff)//After function call = {aaa female 22} ("==========================") chary := Person{"chary","female",18}//initialization //Value as the receiver, value semantics ("Before function call=",chary)//Before function call = {chary female 18} chary.Add2() //Not effective //(&chary).Add() ("After the function call=",chary)//After function call = {chary female 18}} type Person struct { name string sex string age int } //Pointer as receiver, reference semanticsfunc (p *Person) Add(){ // Assign values to members (*p).name = "aaa" = "female" = 22 } //Value as the receiver, value semanticsfunc (p Person) Add2(){ // Assign values to members = "bbb" = "male" = 22 }
4 method set
A method set of types refers to a collection of all methods that can be called by a value of that type.
Calling methods (including anonymous fields) with instance value and pointer is not subject to method set constraints. The compiler always looks for all methods and automatically converts receiver parameters.
4.1 Type *T Method Set
A pointer to a value of a custom type whose method set consists of all methods defined by that type, whether those methods accept a value or a pointer.
If a method that accepts a value is called on a pointer, Go will cleverly dereference the pointer and use the underlying value pointed to by the pointer as the receiver of the method.
The type *T method set contains all receiver T + *T methods:
type Person struct{ name string sex byte age int } //Pointer as receiver, reference semanticsfunc (p *Person) SetInfoPointer(){ (*p).name="yoyo" ='f' =22 } //Value as the receiver, value semanticsfunc (p Person) SetInfoValue(){ ="xxx" ='m' =33 } func main() { //p is pointer type var p*Person = &Person{"mike",'m',18} () //func (p)SetInfoPointer() () //func (*p)SetInfoValue() (*p).SetInfoValue() //func (*p)SetInfoValue() }
4.2 Type T method set
A set of methods for custom type values consists of methods whose receiver type is value type defined for that type, but does not include methods whose receiver type is pointer.
But this limitation is usually not as mentioned here, because if we only have one value, we can still call a method with the receiver of pointer type, which can be achieved with the help of Go's address ability to pass values.
type Person struct{ name string sex byte age int } //Pointer as receiver, reference semanticsfunc (p *Person) SetInfoPointer(){ (*p).name="yoyo" ='f' =22 } //Value as the receiver, value semanticsfunc (p Person)SetInfoValue(){ ="xxx" ='m' =33 } func main() { //p is a normal value type var p Person = Person{"mike",'m',18} (&p).SetInfoPointer() //func(&p)SetInfoPointer() () //func(&p)SetInfoPointer() () //func(p)SetInfoValue() (&p).SetInfoValue() //func(*&p)SetInfoValue() }
5 anonymous fields
5.1 Method inheritance
If an anonymous field implements a method, the struct containing the anonymous field can also call the method.
type Person struct { name string sex byte age int } //Person defines the methodfunc (p *Person) PrintInfo() { ("%s,%c,%d\n",,,) } type Student struct { Person//Anonymous field, then Student contains all fields of Person id int addr string } func main() { p := Person{"mike",'m',18} () s := Student{Person{"yoyo",'f',20},2,"sz"} () }
5.2 Rewriting of method
type Person struct { name string sex byte age int } //Person defines the methodfunc (p *Person) PrintInfo() { ("Person:%s,%c,%d\n",,,) } type Student struct { Person//Anonymous field, then Student contains all fields of Person id int addr string } //Student defines the methodfunc (s *Student) PrintInfo() { ("Student:%s,%c,%d\n",,,) } func main() { p:=Person{"mike",'m',18} () //Person:mike,m,18 s:=Student{Person{"yoyo",'f',20},2,"sz"} () //Student:yoyo,f,20 () //Person:yoyo,f,20 }
6 method values and method expressions
Similar to the way we can assign and pass functions, methods can also assign and pass.
According to the caller, methods are divided into two forms of expression: method value and method expression. Both can be assigned and passed parameters like ordinary functions. The difference is that method values bind instances, while method expressions must be explicitly passed parameters.
6.1 Method value
type Person struct{ name string sex byte age int } func (p *Person) PrintInfoPointer() { ("%p,%v\n",p,p) } func (p Person) PrintInfoValue(){ ("%p,%v\n",&p,p) } func main() { p:=Person{"mike",'m',18} () //0xc0420023e0,&{mike 109 18} pFunc1:= //Method value, implicitly pass receiver pFunc1() //0xc0420023e0,&{mike 109 18} pFunc2:= pFunc2() //0xc042048420,{mike 109 18} }
6.2 Method expression
type Person struct { name string sex byte age int } func (p *Person) PrintInfoPointer() { ("%p,%v\n",p,p) } func (p Person) PrintInfoValue() { ("%p,%v\n",&p,p) } func main() { p:=Person{"mike",'m',18} ()//0xc0420023e0,&{mike 109 18} //Method expression must be explicitly passed parameters //func pFunc1 (p *Person)) pFunc1:=(*Person).PrintInfoPointer pFunc1(&p) //0xc0420023e0,&{mike 109 18} pFunc2:= pFunc2(p) //0xc042002460,{mike 109 18} }
The above is the detailed content of the go language method set and the example analysis of adding methods to types. For more information about adding methods to go language method set type, please pay attention to my other related articles!