Use of Golang-based functions

Hello, today I will share with you the content of Go Language function usage combed out. Please give us some advice. Thank you.

The content of Go Language Function Use is divided into three chapters, which is the third chapter.

Contents of this chapter

  • init function
  • Method

init function

introduce

For example, in some scenarios, we need to initialize some variables or logic code in advance. In this case, we can use a special init initialization function to simplify the initialization, and each file can contain one or more init initialization functions.

func init() {} // init() function syntax

Init initialization functions behave like normal functions except they cannot be called or referenced. The init initialization functions in each file are called automatically at the beginning of program execution in the order they are declared.

The init function precedes the main function

Note: Each package is initialized in the order in which declarations are imported, provided dependencies are resolved, and each package is initialized only once. Therefore, if a p-package imports a q-package, then the q-package must have been initialized when the p-package is initialized.

Characteristics of init function

  • The init function is a function used to initialize a package prior to program execution, such as initializing variables in the package, etc.
  • init function has no input parameter, return value
  • Each package can have multiple init functions
  • Each source file of a package can also have multiple init functions
  • Execution order of multiple init functions in the same package The go language is not clearly defined (explained)
  • The init functions of different packages determine the order in which they are executed based on the dependencies of the package import
  • The init function cannot be called by other functions, but is called automatically before the main function executes

Initialization process

  1. Initialize imported packages (order is not top-down), runtime needs to resolve package dependencies, no dependent packages are initialized first;
  2. Initialize variables for package scope (runtime resolves variable dependencies rather than initializing dependent variables first in order of top-down, left-to-right);
  3. Execute the init function of the package;

runtime is the infrastructure required for the go language to run and is a core feature of go. This content will be shared with you in a subsequent chapter, The Features of the Go Foundation.

Use

Case: init initialization order

package main

import "fmt"

var Num int = Call() // Global variable declaration

func init() { // Initialization function
    fmt.Println("init()")
}

func Call() int {
    fmt.Println("Call()")
    return 1
}

func main() {
    fmt.Println("main()")
}

output

Call()
init()
main()

Conclusion, the initialization process: Num variable initialization -> init () -> main ()

Case: init initialization order of different sources for the same package

First create three files, main. The go code contains global variables, init initialization function definitions, and main function entries. In the a.go and b.go code files, only global variables and definitions of init initialization functions are included.

main.go file

package main

import (
    "fmt"
)

var _ int = m()

func init() {
   fmt.Println("init in main.go")
}

func m() int {
   fmt.Println("call m() in main.go")
   return 1
}

func main() {
   fmt.Println("main()")
}

a.go file

package main

import "fmt"

var _ int = a()

func init() {
   fmt.Println("init in a.go")
}

func a() int {
   fmt.Println("call a() in a.go")
   return 1
}

b.go file

package main

import "fmt"

var _ int = b()

func init() {
   fmt.Println("init in b.go")
}

func b() int {
   fmt.Println("call b() in b.go")
   return 1
}

Because a.go and b.go belong to the main package, there are no main function entries in either file. When executing, you need to use go run main.go a.go b.go is executed in this manner, and runtime initializes all files for loading.

output

call m() in main.go
call a() in a.go
call b() in b.go
init in main.go
init in a.go
init in b.go
main()

In conclusion, golang did not give an official explanation of the init function execution order for the same package with different source files. The loading process is sorted by the go run file.

Case: Initialization order of multiple init functions

package main

import "fmt"

func init() {
   fmt.Println("init 1")
}

func init() {
   fmt.Println("init 2")
}

func main() {
   fmt.Println("main")
}

output

init 1
init 2
main

Conclusion: The init function is special and can be defined multiple times in the package.

Method

introduce

The method in Golang implements binding an object instance and implicitly taking the instance as the first argument (receiver).

Definition Description

  • Methods can only be defined for named types within the current package;
  • The parameter receiver can be named arbitrarily; if it is not used in a method, the parameter name can be omitted;
  • The parameter receiver type can be T or *T, and the base type T cannot be an interface or pointer;
  • Method overloading is not supported, receiver is only part of parameter signature;
  • All methods can be invoked with an instance value or pointer, and the compiler automatically converts them

One method is a function that contains the recipient, who can be a value of a named type or struct type or a pointer.

Method Definition

func (recevier type) methodName(parameter list) (Return Value List) {} // Parameters and return values can be omitted

Use

Define a structure type and a method of that type

package main

import "fmt"

// structural morphology
type Info struct {
    Name  string
    Desc string
}

// Method
func (u Info) Output() {
    fmt.Printf("%v: %v \n", u.Name, u.Desc)
}

func main() {
    // Value Type Call Method
    u1 := Info{"Gunners in Mao Er Shan", "Share technical articles"}
    u1.Output()
    // Pointer type call method
    u2 := Info{"Gunners in Mao Er Shan", "Share technical articles"}
    u3 := &u2
    u3.Output()
}

output

Gunners in Mao Er Shan: Share technical articles 
Gunners in Mao Er Shan: Share technical articles

Anonymous Methods

If type S contains an anonymous field *T, the S and *S method sets contain T + *T methods.

This rule says that when we embed a pointer of a type, the method in which the recipient of the embedded type is a value type or pointer type will be promoted and can be called by an external type of value or pointer.

package main

import "fmt"

type S struct {
    T
}

type T struct {
    int
}

func (t T) testT() {
    fmt.Println("Such as type S Include anonymous types *T, be S and *S Method Set Contains T Method")
}

func (t *T) testP() {
    fmt.Println("Such as type S Include anonymous fields *T, be S and *S Method Collection Contains *T Method")
}

func main() {
    s1 := S{T{1}}
    s2 := &s1
    fmt.Printf("s1 is : %v\n", s1)
    s1.testT()
    s1.testP() // Promote pointer type call

    fmt.Printf("s2 is : %v\n", s2)
    s2.testT() // Promotion type call
    s2.testP()
}

output

s1 is : {{1}}
Such as type S Include anonymous types *T, be S and *S Method Set Contains T Method
 Such as type S Include anonymous fields *T, be S and *S Method Collection Contains *T Method
s2 is : &{{1}}
Such as type S Include anonymous types *T, be S and *S Method Set Contains T Method
 Such as type S Include anonymous fields *T, be S and *S Method Collection Contains *T Method

Expression

Method is divided into two forms depending on the caller

instance.method(args...) ---> <type>.func(instance, args...)

The former is called method value, while the latter method expression has to be passed in explicitly.

package main

import "fmt"

type User struct {
    id   int
    name string
}

func (self *User) Test() {
    fmt.Printf("%p, %v\n", self, self)
}

func main() {
    u := User{1, "Gunners in Mao Er Shan"}
    u.Test()

    mValue := u.Test
    mValue() // Implicit delivery receiver

    mExpression := (*User).Test
    mExpression(&u) // Explicit pass receiver
}

output

0xc00000c018, &{1 Gunners in Mao Er Shan}
0xc00000c018, &{1 Gunners in Mao Er Shan}
0xc00000c018, &{1 Gunners in Mao Er Shan}

In conclusion, the method is the pointer type, and the method value copies the receiver.

Technical articles are continuously updated. Please pay more attention to them~~

Search for the WeChat Public Number, follow me

Tags: Go Back-end

Posted by chrisio on Wed, 18 May 2022 19:01:20 +0300