Explain the difference between methods and functions in Go

Below, the golang tutorial section will give you a detailed explanation of the difference between methods and functions in Go. I hope it will be helpful to friends in need!

This article will introduce the main differences between functions and methods in Go, and how to best use them.



Functions and methods are widely used in Go to provide abstractions, making our programs easier to read and reason about. On the surface, functions and methods look similar, but there are some important semantic differences, which may greatly affect the readability of the code.

Syntax
Declaration syntax
Declare a function by specifying the parameter type, return value and function body:

1

2

3

4

5

6

7

8

9

10

11

12

type Person struct {   Name string   Age int } // This function returns a new object `Person ` func NewPerson(name string, age int) *Person {   return &Person{     Name: name,     Age: age,   } } On the other hand, by additionally specifying the "receiver" (in OOP terminology, it will be the "class class”) to declare the method:







 

















1

2

3

4

// The `isAdult method of the receiver of the `Person` pointer type

func (p *Person) isAdult() bool {   return p.Age> 18 } In the above method declaration, we declared on the *Person type isAdult method. Execution syntax Function calls use independent parameters, and method calls use receiver types. 1 2 3 4 p := NewPerson("John", 21) fmt.Println(p.isAdult()) // true interchangeability Functions and methods are interchangeable in theory. For example, we can convert the isAdult method to a function and use the NewPerson function as a method: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 type PersonFactory struct {} // NewPerson is now a method of the PersonFactory structure




















 






































 



func (p *PersonFactory) NewPerson(name string, age int) *Person {   return &Person{     Name: name,     Age: age,   } } // Now, isAdult is a function. In this function, we use `Person` as The parameter is passed instead of the receiver func isAdult(p *Person) bool {   return p.Age> 18 } In this case, the execution syntax looks a little strange: 1 2 3 4 5 6 factory := &PersonFactory{} p: = factory.NewPerson("John", 21) fmt.Println(isAdult(p)) // true The above code looks more complicated than necessary. This shows us that the differences between methods and functions are mainly grammatical differences, and appropriate abstractions should be used according to the scene. Use cases Let's take a look at some common use cases encountered in Go applications, and the appropriate abstractions (functions or methods) applicable to each application: method chain











 

























 



 











A very useful feature of methods is the ability to chain them together while still keeping the code clean. Let's take the example of setting Person to use some attributes of the link:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

type Person struct {     Name string     Age int } func (p * Person) withName(name string) *Person {     p.Name = name     return p } func (p *Person) withAge(age int) *Person {     p.Age = age     return p } func main() {







 









 









 



    p := &Person{}

 

    p = p.withName("John").withAge(21)

 

  fmt.Println(*p)

  // {John 21}

}

If we use the function for the same thing, it will look very Terrible:

1

p = withName(withAge(p, 18), "John")

Stateful and stateless execution
In the interchangeability example, we saw the use of a PersonFactory object to create a new instance of Person. It turns out that this is an anti-pattern and should be avoided.

It is best to use functions such as the functions previously declared by NewPerson for stateless execution.

"Stateless" here refers to any code

that always returns the same output for the same input. The corollary is that if you find that a function reads and modifies many values ​​of a particular type, it should probably be defined as a method of that type.

Semantics
Semantics refers to the way the code is read. If you read the code aloud in spoken language, which one is more meaningful?

Let's take a look at the function and method implementation of isAdult

1

2

3

4

5

6

7

customer := NewPerson("John", 21)

 

// Method

customer.isAdult()

 

// Function

isAdult(customer)

here customer.isAdult() has a much better understanding of asking "Is the customer an adult?" than isAdult(customer). In addition, when you ask "Is x an adult?", you will always be asked in the context of x.

Conclusion
Although we discussed some key differences and use cases of functions and methods in Go, there are always exceptions! It is important not to use any of these rules as basic principles.

Finally, the difference between functions and methods is how the result code is read. If you or your team think that one method reads better than the other, then this is the correct abstraction!

Guess you like

Origin blog.csdn.net/benli8541/article/details/112739919