Methods in Go language

Keywords: Go

1.1 method statement

    The declaration of the method is similar to that of a normal function, except that a parameter is added before the function name. This parameter binds this method to the type corresponding to this parameter
  import (
       "fmt"
   )

  type Point struct {
       x, y int
  }

  func fun() {
      fmt.Println("I'm a normal fun")
  }

  func (p Point) fun() {     //The additional parameter p is called the receiver of the method.
      fmt.Println("I'm a way")
  }

  func main() {

      p := Point{                                                                                                                                                     
          x: 1,
          y: 2,
      }

      fun()
      p.fun()  //Method

  }
//Program output: I am a normal fun
        //I'm a way

The above declaration of the fun() function does not conflict. The first is a package level function. The second is the method of type Point.

1.2 method of pointer receiver

    Because the main function copies an argument variable, if the function needs to update a variable, or if an argument is too large and we want to avoid copying the entire argument, we must use a pointer to pass the address of the variable.
package main
import(
    "fmt"
)
type Point struct {
    a int
    b int
}

func (p *Point) fun(val int) {
    p.a *= val
    p.b *= val
}

func main() {

    p := Point{
        a: 5,
        b: 10,
    }
    (&p).fun(2)
    fmt.Println(p)

}

//Program output:{10,20}

Note: a named type (Point) and a pointer to its people (* Point) are the only types that can appear at the receiver declaration. Furthermore, to prevent confusion, method declarations of types that themselves are pointers are not allowed:

type P *int 
func (P) f(){    //Compilation error: illegal recipient type
    /* ... */
}

nil is a legal receiver

//Intlist is a plastic linked list
//*Intlist's type nil represents an empty list
type Intlist struct{
    value int
    tail *Intlist
}

// Sum returns the sum of linked list elements

func (list *Intlist) sum() int{
    if nil == list{
        return 0
    }
    return list.value + list.tail.sum()
}

//Note: when defining a type to allow nil as the receiver, it should be indicated in the document annotation

1.3 type of embedded composition through structure

package main

import (
    "fmt"
)

type Point struct {
    x int
    y int
}

type P_point struct {
    Point
    z int
}

func (p Point) fun1() {
    fmt.Println("I am point Method")
}

func (p P_point) fun1() {
    fmt.Println("I am P_point Method")
}

func main() {

    var p Point
    var P_p P_point

    p.fun1()
    P_p.Point.fun1()
    P_p.fun1()

}

//Output result: I am the method of point
        //I'm the point method
        //I'm P point's method

1.4 method variables and expressions

    Usually we use and call methods in the same expression, just like in p.Distance(), but it's OK to separate the two operations.
p := point{1,2}
q := point{2,3}

fun := p.Distance   //Method variables
fun()               //It can be executed. Same as function

1.5 encapsulation of methods (sometimes called data hiding)

    If a variable or method cannot be accessed through an object, this is called an encapsulated variable or method.
    There is only one way to control the visibility of naming in GO language: when defining, identifiers with capitals can be exported from packages, otherwise they cannot be exported. The same mechanism applies to methods in fields and types within a structure. The conclusion is that to encapsulate an object, you must use a structure.

Posted by ngoweb on Sat, 28 Mar 2020 09:22:16 -0700