1. Function
The Go language functions belong to "first-class", that is:
- The function itself can be passed as a value.
- Supports anonymous functions and closures.
- Functions can satisfy interfaces.
1.1 Function returns value
Return value of the same type
func typedTwoValues() (int, int) { return 1, 2 } a, b := typedTwoValues() (a, b)
Return value with variable name
func named Ret Values() (a, b int) { a = 1 b = 2 return }
When a function uses named return value, you can not fill in the return list, if it is filled in, it is also feasible.
Parameter passing in a function
In Go language, the incoming and returning parameters are used when calling and returning.Value pass, It should be noted here that the content pointed to by reference objects such as pointers, slices and maps will not be copied during parameter passing, but will copy the pointer, similar to creating a reference once.
Function variables
In Go language, functions are also a type that can be saved in variables like other types
func fire() { ("fire") } func main() { var f func() //Declare the variable f as func() type, and f is commonly known as the "callback function". At this time, the value of f is nil. f = fire f() }
1.2 Anonymous functions - functions without function names
Go language supports anonymous functions, that is, when you need to use functions, you define the function again. Anonymous functions do not have a function name.Only function body, a function can be assigned to a variable of the function type as a type.Anonymous functions are also often passed in variables 。
Call anonymous functions when defining
Anonymous functions can be called after declaration, for example:
func(data int) { ("hello", data) }(100)
Assign anonymous functions to variables
Anonymous function body can be assigned values, for example:
// Save the anonymous function body into f()f := func(data int) { ("hello", data) } // Call with f()f(100)
Anonymous functions are used as callback functions
Define anonymous functions when using them. If you do not use them, declare them in the called function first. This is the essence of callbacks.
// Iterate through each element of the slice and access elements through the given function func visit(list []int, f func(int)) { for _, v := range list { f(v) } } func main() { // Use anonymous function to print the slice content visit([]int{1, 2, 3, 4}, func(v int) { (v) }) }
Variable parameters—function form with unfixed number of parameters
All parameters are variable parameters:
func Println(a ...interface{}) (n int, err error) { return Fprintln(, a...) }
When used, the type of value passed in is not restricted.For example:
(5, "hello", &struct{ a int }{1}, true)
When the variable parameter isinterface{}
When type, you can pass in any type of value
Some parametersIt is variable parameters:
The first parameter of the parameter list, and the following parameters are variable parameters:
func Printf(format string, a ...interface{}) (n int, err error) { return Fprintf(, format, a...) } ------------------------------------------------------ ("pure string\n") ("value: %v %f\n", true, )
1.3 Closure
A closure can be understood as a function defined inside a function. In essence, closures are bridges connected to the inside and outside of the function. Simply put, closure = function + reference environment
func main() { var f = add() ("f(10): %v\n", f(10)) ("f(20): %v\n", f(20)) // f(10): 10 // f(20): 30 } func add() func(int) int { var x int return func(y int) int { x += y return x } }
1.4 defer statement
The defer statement delays the following statements, and the deferred statement is executed in the first-in-and-out mode (the deferred statement is finally executed, and then executed by the deferred statement).
characteristic:
- The keyword defer is used to register delayed calls
- It is not executed until the return is called (so it can be used for resource cleaning)
- Multiple defer statements, FILO execution
- The variables in defer are defined when defer is declared
use:
- Close the file handle
- Lock resource release
- Database connection release
Handle errors that occur at runtime
The Go language error handling ideas and design include the following characteristics:
- A function that may cause an error needs to return one of the return valuesError interface (error). If the call is successful, the error interface will return nil, otherwise the error will be returned.
- After the function call, you need to check for errors. If an error occurs, you can perform necessary error handling.
The format of the error interface definition
error is the interface type declared by the Go system, and the code is as follows:
type error interface { Error() string // Returns a specific description of the error.}
All interfaces that comply with the Error() string format can implement error interfaces.
Define an error
In Go language, errors package is used to define errors in the following format:
var err = ("this is an error")
Because the error string is relatively fixed, it is generally declared in the package scope.The use of the return should be minimized directly when used.
Panic - program terminates running
Manually triggering downtime
Go language can manually trigger a downtime in the program, causing the program to crash, so that developers can detect errors in a timely manner while reducing possible losses.
When the Go language program goes down, it will output the stack and goroutine information to the console, so it can also be convenient to know where the error occurred when the downtime occurs.
package main func main() { panic("crash") }
The arguments of panic() can be of any type.
When a downtime triggered by panic() occurs, the code behind panic() will not be run, but the defer statement that has been run in front of the panic() function will still work when the downtime occurs.
1.5 Recover - Prevent program crashes
Whether it is a panic crash thrown by the Runtime layer by the code running error or a panic crash triggered by the active, it can be used to cooperate with defer and recover to implement error capture and recovery, so that the code is allowed to continue running after a crash occurs.
Go does not have an exception system, and its use of panic to trigger downtime is similar to throwing exceptions in other languages. Then the recovery's downtime recovery mechanism corresponds to the try/catch mechanism.
The relationship between panic and recover:
- There is panic but no recovery, the program is down.
- There are panic and recover captures, and the program will not crash. After executing the corresponding defer, exit the current function from the downtime point and continue execution.
hint:Although panic/recover can simulate exception mechanisms in other languages, it is not recommended that this feature is often used in writing ordinary functions.
2. Structure
A structure member is composed of a series of member variables, also known as "fields".
Fields have the following characteristics:
- Fields have their own type and value.
- The field name must be unique.
- The type of a field can also be a structure, or even a type of the structure where the field is located.
There is no concept of "class" in the Go language, nor does it support object-oriented concepts such as inheritance of "class".
The structures and "classes" of Go language are both composite structures, but the embedded matching interfaces of structures in Go language have higher scalability and flexibility than object-oriented.
Go not only believes that structures can have methods, but each custom type can also have its own methods.
2.1 Definition and assign values to structures
Basic form:
type Point struct { X int Y int } var p Point = 10 = 20
The definition of a structure is just a description of memory layout. Memory is only allocated when the structure is instantiated.
Create a structure of pointer type:
type Player struct { name string age int } p = new(Player) = "james" = 40
Take the address of the structure to instantiate:
//Use a structure to define a command line command, which contains name, variable association and comments, etc.type Command struct { name string Var *int comment string } var version int = 1 cmd := &Command{} = "version" = &version = "show version"
Use key-value pairs to fill the structure:
type People struct { name string child *People } relation := &People{ name: "grandfather" child: &People{ name: "dad" child: &People{ name: "I" }, } }
3. Method
Methods in Go are functions that act on variables of a specific type. This type of variable is called a receiver (Receiver )。
If a particular type is understood as a structure or "class", the concept of a receiver is similar to that in other languagesthis
orself
。
3.1 Structural method
Create a backpackBag
The structure defines the method of putting items into the backpackinsert
:
type Bag struct { items[] int } func (b *Bag) insert(itemid int) { = append(, itemid) } func main() { b := new(Bag) (1001) }
(b*Bag)
Represents the receiver, i.e.Insert
Actual of the object to function. Each method can only have one receiver.
3.2 Receiver
The receiver is the goal of the method
Receivers can be divided into:
- Pointer Receiver
- Non-pointer receiver
- The two receivers have different effects when used. Depending on the effect, the two receivers will be used in codes with different performance and functional requirements.
Pointer Receiver
Due to the characteristics of the pointer, when calling a method, modifying any member variable of the receiver pointer is valid after the method is finished.
// Define the attribute structuretype Property struct { value int } // Set the attribute value methodfunc (p *Property) setVal(val int) { = val } // Get the attribute value methodfunc (p *Property) getVal() int { return } func main() { p := new(Property) = 123 (()) (666) (()) }
Non-pointer type receiver
When the method acts on a non-pointer receiver, Go will be run while the code is running.Copy the receiver's value in one copy. In a non-pointer receiver method, the member value of the receiver can be obtained.But it is invalid after modification 。
type Point struct { x, y int } func (p Point) add(other Point) Point { return Point{ + , + } } func main() { // Initialization point p1 := Point{1, 1} p2 := Point{2, 2} res := (p2) (res) p3 := Point{3, 3} p4 := (p2).add(p3) (p4) }
Use of pointer receivers and non-pointer receivers:
Pointer and non-pointer receivers are used in computers,Small objectBecause the speed of copying values is faster, it is suitable for using non-pointer receivers.Big objectBecause of the low replication performance, it is suitable for using pointer receivers. When passing between the receiver and parameters, it does not copy, but only passes the pointer.
4. Interface
Interface is a cooperation agreement agreed upon by both parties. Interface implementers do not need to care about how the interface will be used, and callers do not need to care about the implementation details of the interface. An interface is a type and an abstract structure that will not expose the format, type and structure of the data contained.
4.1 Declare interface
type Interface type name interface { method1(Parameter list) Return value ... }
When naming the Go language interface, an er is usually added after the word. For example, the interface with write operation is called Writer, the interface with string function is called Stringer, the interface with close function is called Closer, etc.
Method name: When the initial letter of the method name is capitalized and the initial letter of the interface type name is also capitalized, this method can be accessed by code outside the package where the interface is located.
Writer interface provided in the io package:
type Writer interface { Write(p []type) (n int, err error) }
4.2 Implementing the interface
Conditions for implementing interfaces:
- The interface method is the same as the type method that implements the interface
- All methods in the interface are implemented
example:In order to abstract the process of data writing, the Data Writer interface is defined to describe the methods that data writing needs to be implemented.
// Define a data writer interfacetype DataWriter interface { WriteData(data interface{}) error } // Define the file structure to implement DataWritertype file struct { } // Methods to implement DataWriter interfacefunc (d *file) WriteData(data interface{}) error { // Simulate writing data ("Write Data:", data) return nil } func main() { // Instantiate file f := new(file) // Declare a DataWriter interface var writer DataWriter // Assign the interface value, that is, *file writer = f ("one line data") }
The interface implementation of Go language is implicit, and there is no need to write down what interfaces are implemented. This design is called a non-invasive design.
This is the end of this article about Go language learning functions + structures + methods + interfaces. For more related Go function content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!