SoFunction
Updated on 2025-03-05

Go language method set adds method example analysis to type

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!