Hi, I’m Xingzhou, today we are going to learn the way of Go language.

In Go language, a method is a function of a certain type. Methods are similar to functions in that they are repeated calls through the encapsulation of a code logic. But there are differences:

  1. Functions and methods are declared differently.
  2. Functions can be passed as arguments, methods can’t.
  3. Functions can be anonymous, methods can’t.

Let’s look at how to use the method.

The declarative approach

func (t Type)The method name(Passed parameter) (Return value){method body}Copy the code

In contrast to declaring functions, declaring methods requires adding t of Type after func, which can be accessed in methods.

Basic usage

Initialize the

Case 1:

// Declare the animal structure
type animal struct {
   name string
   age int
   class string
   weight float32
}

// Declare the animal type method getName
func (a animal) getName(a) {
   fmt.Printf("I am %s. \n" , a.name)
}

func main(a)  {
   a1 := animal{name:"Tom",age:3,weight:11.5,class:"Cat"}
   a1.getName() // Calls the animal structure instance method
}
Copy the code

As in the example above, we declare a structure of type Animal and a method getName of type Animal. It then declares an instance of the Animal structure a1, which has animal properties and methods.

Methods can belong not only to a structure type, but also to any other custom type that is not an interface or pointer type. Example 2:

// Declare the custom type test as the basic type int of the GO language
type test int

// Declare the method printTest of type test
func (t test) printTest(a)  {
   fmt.Println("I am t",  t)
}

func main(a)  {
   var t test
   t = 10
   t.printTest() // print I am t 10
}
Copy the code

In the example above, we use the keyword type to define the test type, which belongs to the basic type int of the GO language. The method printTest of type test is then declared

A custom type is a data type declared using the type keyword. It can be a struct, a primitive data type, or a function. Example: type I int, type f func.

Method names of the same type are not allowed to duplicate, nor are method names and field names allowed to duplicate. Duplicate definitions will cause errors at compile time.

Function substitution method

In example 1 above, we can use functions to achieve the same effect. Example 3:

// Declare the animal structure
type animal struct {
   name string
   age int
   class string
   weight float32
}

// Declare the function getName
func getName(a animal) {
   fmt.Printf("I am %s. \n" , a.name)
}

func main(a)  {
   a1 := animal{name:"Tom",age:3,weight:11.5,class:"Cat"}
   getName(a1) // Call getName
}
Copy the code

We define getName, which receives animal, and call getName, passing a1, to achieve the same purpose as in example 1.

Why have methods when functions can do the same thing? I think there are two main reasons:

  1. Go is not a traditional object-oriented language; it has no concept of classes. The structure and methods can enhance the object-oriented characteristics of Go language and simulate the role of classes. Golang.org/doc/faq#Is_…
  2. Methods belonging to different types may have the same name, but functions may not.

Methods of nested types

In the structure section, we said that when the structure itself does not have a field, we look “deeper” into the nested structure. Go language search layer by layer, find the corresponding field to return its value, and stop the search. The same logic applies to methods. The Go language uses a nested structure to find the method layer by layer and invoke the corresponding method based on the method name. Example 4:

// Declare the animalName structure
type animalName struct {
   firstName string
   lastName string
}

// Declare the animal structure
type animal struct {
   animalName
   age int
   class string
   weight float32
}

func (an animalName) getAnimalName(a)  {
   fmt.Printf("My name is %s %s", an.firstName, an.lastName)
}

func main(a)  {
   a1 := animal{
      animalName: animalName{
         firstName:"tom",
         lastName:"steven",
      },
      age: 3,
      class:"Cat",
      weight:12.5,
   }
   a1.getAnimalName() // print My name is tom steven
}
Copy the code

In the example above, we define the Animal structure type and the nested animalName structure type. GetAnimalName method is defined for the animalName type. When executing a1.getAnimalName(), Go language finds the getAnimalName method layer by layer and calls it.

Value type and pointer type

The methods we declared in the previous example are of value type, and methods can also be of pointer type.

Similar to function parameter types, value types are copies of values. When we change the value of a copy in a method, we do not change the original value if it is a non-reference type, but we change the original value if it is a reference type. The pointer type is a copy of the pointer address, so any changes we make in the method will change the original value. Example 5:

// Declare the animalName structure
type animalName struct {
   firstName string
   lastName string
}

// Declare the animal structure
type animal struct {
   animalName
   age int
   class string
   weight float32
}

func (an animalName) setAnimalName(firstName,lastName string)  {
   an.firstName =  firstName
   an.lastName = lastName
}

func (an *animalName) setAnimalNamePoint(firstName,lastName string)  {
   an.firstName =  firstName
   an.lastName = lastName
}

func main(a)  {
   a1 := animal{
      animalName: animalName{
         firstName:"tom",
         lastName:"steven",
      },
      age: 3,
      class:"Cat",
      weight:12.5,}Print a1. FirstName = Tom a1. LastName = Steven
   fmt.Printf(A1. firstName=%s a1.lastName=%s \n", a1.firstName,a1.lastName)
   a1.setAnimalName("jerry"."williams"// change a1 firstName and lastName
   Print a1. FirstName = Tom a1. LastName = Steven
   fmt.Printf(A1. FirstName =%s a1. LastName =%s \n", a1.firstName,a1.lastName) 

   a2 := animal{
      animalName: animalName{
         firstName:"tom",
         lastName:"steven",
      },
      age: 3,
      class:"Cat",
      weight:12.5,}FirstName = Tom a2.lastname = Steven
   fmt.Printf("Before modification: a2.firstName=%s a2.lastName=%s \n", a2.firstName,a2.lastName)
   a2.setAnimalNamePoint("jerry"."williams"// change a2 firstName and lastName
   FirstName =jerry a2.lastname = Williams
   fmt.Printf("Alter: a2.firstName=%s a2.lastName=%s \n", a2.firstName,a2.lastName)
}
Copy the code

In the example above, we declare the Animal structure and its nested animalName structure, and then declare two methods of the animalName structure type: setAnimalName (value type) and setAnimalNamePoint (pointer type).

The setAnimalName method is used to modify a1’s firstName and lastName. It can be seen from the printed information that a1’s firstName and lastName values are not modified.

Call setAnimalNamePoint to change firstName and lastName of A2. The printed information shows that the values of firstName and lastName of A2 are successfully modified.

In our example, firstName and lastName are both strings, and the value will be modified in both cases if the value is a reference. You can test it yourself.

As the reader may have noticed, how can a method called a2, which is a value type, succeed when setAnimalNamePoint is a pointer?

This is because the Go language does automatic translation for us, allowing us to call methods of pointer type through values as well. SetAnimalNamePoint (” Jerry “,” Williams “) in the above example is equivalent to (&a2).setAnimalNamePoint(” Jerry “,” Williams “).

When do we use value methods and when do we use pointer methods?

  1. We can consider using pointer methods if we want the object calling the method itself to be changed.
  2. We can also use Pointers when the type is particularly complex to prevent excessive copying of values.

In other cases, value methods can be used.

Automatic conversion of value and pointer types

A value of a custom datatype contains only all of its value methods, but a pointer type of a custom datatype contains both value methods and pointer methods. Because the Go language automatically interprets value types when calling pointer methods, this is not a good example to verify, but we will prove it later when we talk about interfaces.

conclusion

In this article, we mainly introduce how to declare method, the basic usage of method, method and function difference and connection, value method and pointer method relationship and so on. Constructs and methods play a similar role to other language classes in Go, so we can say that Go is a programming language that supports object-oriented thinking.

Invite attention to the public number: a row of weekly update technical articles, and we progress together.