当前位置:网站首页>Functions and pointers in 08 go language
Functions and pointers in 08 go language
2022-07-28 12:29:00 【A little boy who loves to write code】
function
Go Support function in language 、 Anonymous functions and closures , And the function is in G Language belongs to “ First class citizen ”.
The basic definition of a function
Go In the language, the definition function uses func keyword , The specific format is as follows :
func Function name ( Parameters )( Return value ){
The body of the function
}
among :
Function name : By letter 、 Numbers 、 Underline composition . But the first letter of a function name cannot be a number . In the same package , Function names can't be duplicated ( The concept of package is described in the following article ).
Parameters : Parameters consist of parameter variables and their types , Use... Between multiple parameters
,Separate .Return value : The return value consists of the return value variable and its variable type , You can also write only the type of the return value , Multiple return values must use
()The parcel , And use,Separate .The body of the function : A block of code that implements a specified function .
Let's define a function for the sum of two numbers :
func intSum(x int,y int)int{ return x+y }
The parameters and return values of the function are optional , For example, we can implement a function that requires neither parameters nor return values :
func sayHello() {
fmt.Println("Hello Shahe ")
}
Function call
After defining the function , We can go through Function name () Call function in the way of . For example, we call the two functions defined above , The code is as follows :
func main() {
sayHello() // Call function
res := initSum(4, 5)
fmt.Println(res)
}
Be careful , When calling a function with a return value , Its return value is not acceptable .
The parameters of the function
Type abbreviation :
If the adjacent variables in the function parameters have the same type , The type can be omitted , for example :
func initSum(x,y int)int{
return x+y
}
In the above code ,intSum Function has two arguments , Both parameters are of type int, Therefore, it can be omitted x The type of , because y There is a description of the type ,x Parameters are also of this type .
Indefinite length parameter :
Variable parameters mean that the number of arguments of a function is not fixed .Go The variable parameter in the language passes after the parameter name ... To mark .
Be careful : Variable parameters are usually used as the last parameter of the function .
// Define variable parameter functions
func initSum2(x ...int) int {
fmt.Println(x) //x It's a slice
sum := 0
for _, v := range x {
sum += v
}
return sum
}
-----------------------------------
// Call the function above :
res1 := initSum2()
res2 := initSum2(10)
res3 := initSum2(10, 20)
res4 := initSum2(10, 20, 30)
fmt.Println(res1, res2, res3, res4)
// Running results :
[]
[10]
[10 20]
[10 20 30]
0 10 30 60
When variable parameters are used with fixed functions , Variable function is after fixed function , The sample code is as follows :
// Fixed parameter + Variable parameters
func initSum3(x int, y ...int) int {
fmt.Println(x, y)
sum := x
for _, v := range y {
sum += v
}
return sum
}
// Call the above function
res5 := initSum3(100)
res6 := initSum3(100, 10)
res7 := initSum3(100, 10, 20)
fmt.Println(res5, res6, res7)
// Running results :
100 []
100 [10]
100 [10 20]
100 110 130
Essentially , The variable parameters of a function are implemented by slicing .
Be careful : There are no default parameters !!!
Function return value
Go Through... In language return Keyword output, return value .
Multiple return values :
GO Functions in language support multiple return values , If the function has multiple return values , Must use () Wrap all return values .
// Multiple return values
func calc(x, y int) (int, int) {
// Define multiple return values
sum := x + y
sub := x - y
return sum, sub
}
Name the return value
When defining a function, you can name the return value , And use these variables directly in the function body , Finally through return Keywords return .
// Return value naming
func calc2(x, y int) (sum, sub int) {
sum = x + y // Because the defined parameters have been declared in the return value , Just use the function body directly
sub = x - y
return sum, sub
}
Return value supplement
When the return value type of one of our functions is slice when ,nil Can be seen as an effective slice, There is no need to show that the returned length is 0 The section of .
func someFunc(x string) []int {
if x == "" {
return nil // There is no need to return []int{}
}
...
}
Function advanced
Scope of variable
Global variables
A global variable is a variable defined outside a function , It works throughout the program's life cycle . Global variables can be accessed in functions .
package main import "fmt" // Define global variables num var num int64 = 10 func testGlobalVar() { fmt.Printf("num=%d\n", num) // Functions can access global variables num } func main() { testGlobalVar() //num=10 }local variable
There are two kinds of local variables : Variables defined in functions and variables defined in statements .
Variables defined in functions :
func testGlobalVar() { // Define a function local variable num, Only in this function num := 10 fmt.Printf("num=%d\n", num) } func main() { testGlobalVar() fmt.Println(num) // Variables cannot be used at this time num }If local variables and global variables have the same name , Priority access to local variables .
package main import "fmt" // Define global variables num var num int64 = 10 func testNum() { num := 100 fmt.Printf("num=%d\n", num) // Local variables are preferred in functions } func main() { testNum() // num=100 }Statement to define variables :
Usually we will be in if conditional ,for loop ,switch This way of defining variables is used in statements .
// Variables defined by the statement block (if Sentence block ) func testlocalVar2(x, y int) { fmt.Println(x, y) // Function parameters can only take effect in this function if x > 0 { z := 10 // Variable z Only in if The statement block takes effect fmt.Println(z) } // fmt.Println(z) // Variables cannot be used here z } // call testlocalVar2(10,20) // Running results : 10 20 10// Variables defined by the statement block (for Sentence block ) func testlocalVar3() { for i := 0; i < 10; i++ { fmt.Println(i) // Variable i Only in the present for Loop statement block takes effect } //fmt.Println(i) Variables cannot be used here i } // Call function testlocalVar3() // Running results : 0 1 2 3 4 5 6 7 8 9Function type and variable
1、 Define function types
We can use
typeKeyword to define a function type , The specific format is as follows :type calculation func(int, int) intThe above statement defines a named calculation The function type of . The function in this function type receives two int Type and has a int Return value of type .
Simply speaking , Any function that satisfies this condition is calculation Function of type , For example, the following add and sub yes calculation type .
func add(x,y int)int{ return x+y } func sub(x,y int)int{ return x+y }add and sub Can be assigned to calculation Variable of type
var c calculation c=add2、 Function type variables
We can declare a variable of function type and assign a value to it
//type Function type type calculation func(int, int) int // Declare function types func testType() { var c calculation // Make a statement calculation Variable of type c c = initSum // hold initSum Assign a value to c fmt.Printf("type of %T\n", c) // type of c:main.calculation fmt.Println(c(2, 4)) // call initsum function f := initSum // Will function add Assign a value to a variable f fmt.Printf("type of %T\n", f) //type of f: func(int, int) int fmt.Println(c(6, 10)) // call initsum function } // Running results : type of main.calculation 6 type of func(int, int) int 16
As long as type The beginning of the keyword is the definition type .
3、 Function signature
Function signature --> Function definition ( Statement ) The format of , It has nothing to do with parameter name and return value name
Function signature --> The parameters of the function 、 The type and number of return values 、 The order should be the same
func fi(name string, age int) {
}
func fj(age int, name string) {
}
type MyFF func(string, int)
func f16() {
var mf MyFF
mf = fi
// mf = fj // Function signatures are inconsistent
mf("ddd", 1)
}
Higher order function
Higher order function is divided into two parts: function as parameter and function as return value .
1、 Function as parameter
// Higher order function - Function as parameter
func add(x, y int) int {
return x + y
}
func calc3(x, y int, op func(int, int) int) int {
// Pass in a name of op The parameters for 2 individual int, Return value int Function of
return op(x, y)
}
// call
func main() {
ret2 := calc(10, 20, add)
fmt.Println(ret2) //30
}
// Running results :
30
2、 Function as return value
// Higher order function - Function as return value
/* 1、 A variable is called inside the function res 2、 The return value is res */
func do(x, y int, s string) (res func(int, int) int) {
switch s {
case "+":
return add
case "-":
return sub
}
return res
}
func do1(x, y int, s string) func(int, int) int {
var res func(int, int) int
switch s {
case "+":
return add
case "-":
return sub
}
return res
}
Anonymous functions and immediate execution functions
Function can also be used as return value , But in GO In language, functions cannot be defined inside functions like before , Only anonymous functions can be defined . Anonymous functions are functions without function names , The definition format of anonymous function is :
func( Parameters )( Return value ){
The body of the function
}
1、 Assigning anonymous functions to variables
// Anonymous functions
//1、 Assigning anonymous functions to variables
func f33() func() {
f1 := func() {
fmt.Println(" The wonderful weekend is coming to an end ")
}
return f1
}
// call
f33()()
// Running results :
The wonderful weekend is coming to an end
2、 Self executing functions
//2、 Self executing functions : The definition of anonymous function is complete () Direct execution
func f34() {
func() {
fmt.Println(" Ha ha ha ha ")
}() // Execute now
}
// Call function
f34()
// Running results :
Ha ha ha ha
Closure
A closure is an entity composed of a function and its associated reference environment . In short , Closure = function + Citation environment . First let's look at an example :
// Closure
func addr() func(int) int {
var x int
// Function variables outside the function are used inside the function x
f := func(y int) int {
x += y
return x
}
// Return anonymous functions as return values
return f
}
// call
func main(){
f1 := addr() // call addr function
fmt.Println(f1(10)) //10
fmt.Println(f1(20)) //10+20=30
}
// Running results :
10
30
Advanced closure examples 1:
// Define an accumulator
// The new value is always used by the returned function
func addr2(x int) func(int) int {
f := func(y int) int {
x += y
return x
}
return f
// return func (y int) int { // Another form of writing
// x +=y
// return x
// }
}
// Call function
func main(){
f1 := addr2(10)
fmt.Println(f1(20)) // 30
fmt.Println(f1(30)) //60
}
// Running results :
30
60
Advanced closure examples 2:
/* Determine whether a name ends with a specified suffix . */
func makeSuffixFunc(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}
// Call function
func main(){
jpg := makeSuffixFunc(".jpg")
txt := makeSuffixFunc(".txt")
fmt.Println(jpg("test")) // test.jpg
fmt.Println(txt("test")) //test.txt
}
// Running results :
test.jpg
test.txt
Advanced closure examples 3:
/* Find two numbers sum and sub */
func calcs(base int) (func(int) int, func(int) int) {
add := func(i int) int {
base += i
return base
}
sub := func(i int) int {
base -= i
return base
}
return add, sub
}
// call
func main(){
f1, f2 := calcs(10)
fmt.Println(f1(1), f2(2)) //11 9
fmt.Println(f1(3), f2(4)) // 12 8
}
// Running results :
11 9
12 8
defer
- What scene will be used defer
- Release resources
- Close file
- Release the connection
- defer Execution order of
- Registered before execution
- defer Execution time of
- After the return value assignment , Bottom RET Before the order
- defer Statement cannot receive a return value
defer x := sub(10, 2)
//defer sentence
func deFer() {
fmt.Println("start")
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
fmt.Println("end")
}
// call
deFer()
// Running results :
start
end
3
2
1
Built in functions
| Built in functions | Introduce |
|---|---|
| close | It's mainly used to close channel |
| len | To find the length , such as string、array、slice、map、channel |
| new | Used to allocate memory , Mainly used to assign value types , such as int、struct. The return is the pointer |
| make | Used to allocate memory , Mainly used to assign reference types , such as channel、map、slice |
| append | Used to append elements to an array 、slice in |
| panic and recover | For error handling |
panic and recover
Go There is currently no exception mechanism in the language , But use panic/recover Mode processing error .panic Can trigger... Anywhere , but recover Only in defer The function called is valid .
func funcA() {
fmt.Println("func A")
}
func funcB() {
panic("panic in B")
}
func funcC() {
fmt.Println("func C")
}
func main() {
funcA()
funcB()
funcC()
}
// Running results :
func A
panic: panic in B
goroutine 1 [running]:
main.funB(...)
/Users/alblue/Documents/ Monkey D Luffy go/day03/ Homework /fun.go:212
main.main()
/Users/alblue/Documents/ Monkey D Luffy go/day03/ Homework /mian.go:52 +0x66
Program duration funcB In the middle of the war, it caused panic Cause the program to crash , Abnormal exit . At this time, we can pass recover Return the program , Keep going back .
func funA() {
fmt.Println("func A")
}
func funB() {
defer func() {
err := recover()
// If the program appears panic, adopt recover Come back
if err != nil {
fmt.Println("recocer ....")
}
}()
panic("panic in B")
}
func funC() {
fmt.Println("func C")
}
func main() {
funcA()
funcB()
funcC()
}
// Running results :
func A
recocer ....
func C
Be careful :
recover()It has to go withdeferUse .deferBe sure to triggerpanicBefore the statement of .
07- The pointer
Any program data is loaded into memory , There are their addresses in memory , This is the pointer . In order to save an address of data in memory , We need pointer variables .
such as ,“ Never overestimate yourself ” This is my motto , I want to write it into the program , As soon as the program starts, this sentence should be loaded into memory ( Suppose the memory address is 0x123456), I assign this to variables in the program A, Assign memory address to variable B. This is the variable B It's a pointer variable . Through the variable A And variables B Can find my motto .
GO The pointer in the language can't be offset and operated . therefore go Pointer operation in language is very simple , We just need to remember two symbols :&( Address fetch ) and *( According to the address ).
Pointer address and pointer type
Each variable has an address at run time , This address represents the location of the variable in memory .Go Used in language & The character is placed in front of the variable to address the variable .GO Value types in languages (int,float,bool,string,array,struct) All have corresponding pointer types , Such as :*int、*string etc. .
The syntax of de variable pointer is as follows :
ptr := &v // v The type of T
among :
- v: The variable representing the address to be taken , The type is
T - ptr: The variable used to receive the address ,ptr The type is
*T, It's called T Pointer type of .* For the pointer .
func poInt(){
a:=10
b:=&a
fmt.Printf("a:%d ptr:%p\n",a,&a) //a:10 ptr:0xc000014080
fmt.Printf("b:%p ptr:%T\n",b,b) //b:0xc000014080 ptr:*int
}
// Running results :
a:10 ptr:0xc000014080
b:0xc000014080 ptr:*int
Let's see b := &a Icon :
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-U80ibcgw-1656580370457)(day03.assets/image-20220116184209206.png)]
Just two operations :
- Take variables x Memory address of :
&xWhat you get is a pointer - With pointer variables p,
*pFind the value according to the memory address
Pointer value
In the use of ordinary variables & The operator takes the address and gets the pointer to the variable , Then you can use... On the pointer * operation , That is, the value of the pointer , The code is as follows .
// Pointer value
func p1() {
// Pointer value
a := 10
b := &a // Take variables a The address of , Save pointer in b in
fmt.Printf("type of b:%T\n", b)
c := *b // Pointer value ( According to the pointer to the memory value )
fmt.Printf("type of c:%T\n", c)
fmt.Printf("value of c:%v\n", c)
}
// Running results :
type of b:*int
type of c:int
value of c:10
summary : Take the address operator & And value operators * It's a pair of complementary operators ,& Take out the address ,* Take the value pointed to by the address .
Variable 、 Pointer address 、 Pointer to the variable 、 Address fetch 、 The relationships and characteristics of values are as follows :
- Address the variable (&) operation , You can get the pointer variable of this variable .
- The value of the pointer variable is the pointer address .
- Take the value of pointer variable (*) operation , You can get the value of the original variable that the pointer variable points to .
Pointer value example :
func modify1(x int) {
x = 100
}
func modify2(x *int) {
*x = 100
}
func main() {
a := 10
modify1(a)
fmt.Println(a) // 10
modify2(&a)
fmt.Println(a) // 100
}
// Running results :
10
100
new and make
new and make Are used to apply for memory ,new Use less
difference :
- new Return pointer type
- make It can only be used for slice、map、channel The initialization , The three reference types themselves are returned ;
- and new Memory allocation for type , And the value used for the pair is of type zero , The return is a pointer to the type .
Let's start with an example :
func main() {
var a *int
*a = 100
fmt.Println(*a)
var b map[string]int
b[" Shahenaza "] = 100
fmt.Println(b)
}
Executing the above code causes panic, Why? ? stay Go For variables of reference type in language , We should not only declare it when we use it , And allocate memory space for it , Otherwise our value can't be stored . The declaration of value type does not need to allocate memory space , Because they have allocated memory space by default at the time of declaration . To allocate memory , Just bring out today's new and make. Go In language new and make It's two built-in functions , Mainly used to allocate memory .
1、new
new Functions are not very common , Use new Function to get a pointer of type , And the corresponding value of the pointer is the zero value of the type . for instance :
//new
func newDemo() {
a := new(int)
b := new(bool)
fmt.Printf("%T\n", a) //*int
fmt.Printf("%T\n", b) //*bool
fmt.Println(*a) //0
fmt.Println(*b) //false
}
// Running results :
*int
*bool
0
false
In the sample code at the beginning of this section var a *int Just declared a pointer variable a But not initialized , Pointer as a reference type needs to be initialized before it has memory space , You can assign it . The built-in... Should be used as follows new Function pair a After initialization, it can be assigned normally :
func newDemo2() {
var a *int
a = new(int)
*a = 10
fmt.Println(*a)
}
// result :
10
2、make
make It's also used for memory allocation , The difference in new, It is only used for slice、map as well as chan Memory creation , And the types it returns are the three types themselves , Not their pointer type , Because these three types are reference types , So there's no need to return their pointers .make The function signature of the function is as follows :
func make(t Type, size ...IntegerType) Type
make Functions are irreplaceable , We are using slice、map as well as channel When , You need to use make To initialize , Then we can operate them . We have explained this in the last chapter , About channel We'll explain it in detail in the following chapters .
In the example at the beginning of this section var b map[string]int Just declare variables b It's a map Variable of type , It needs to be used like the following example code make After the function initializes , It can be assigned a key value pair :
func main() {
var b map[string]int
b = make(map[string]int, 10)
b[" Shahenaza "] = 100
fmt.Println(b)
}
practice
/* Do you have 50 Gold coins , It needs to be assigned to the following people :Matthew,Sarah,Augustus,Heidi,Emilie,Peter,Giana,Adriano,Aaron,Elizabeth. The allocation rules are as follows : a. Every name contains 1 individual 'e' or 'E' branch 1 Gold coins b. Every name contains 1 individual 'i' or 'I' branch 2 Gold coins c. Every name contains 1 individual 'o' or 'O' branch 3 Gold coins d: Every name contains 1 individual 'u' or 'U' branch 4 Gold coins Write a program , Calculate how many gold coins each user gets , And how many gold coins are left in the end ? The program structure is as follows , Please implement ‘dispatchCoin’ function */
var (
coins = 50
users = []string{
"Matthew", "Sarah", "Augustus", "Heidi", "Emilie", "Peter", "Giana", "Adriano", "Aaron", "Elizabeth",
}
distribution = make(map[string]int, len(users))
)
func dispatchCoin() ( int) {
// Count each one user How many gold coins are there
for _, v := range users {
for _, s := range v {
switch s {
case 'e', 'E':
distribution[v] += 1
case 'i', 'I':
distribution[v] += 2
case 'o', 'O':
distribution[v] += 3
case 'u', 'U':
distribution[v] += 4
}
}
}
// Calculate the remaining gold coins
var sum int
for _, v := range distribution {
sum += v
}
return 50 - sum
}
func main() {
left := dispatchCoin()
fmt.Println(" be left over :", left)
}
边栏推荐
- REST风格
- Developing NES games with C language (cc65) 06. Sprites
- 用C语言开发NES游戏(CC65)07、控制器
- 顶级“Redis笔记”,缓存雪崩+击穿+穿透+集群+分布式锁,NB了
- 安徽京准:北斗卫星同步时钟|北斗同步时钟|NTP网络时钟服务器
- Developing NES games with C language (cc65) 08. Background collision
- [try to hack] at, SC, PS command authorization
- 分布式定时器
- Analysys analysis: focus on users, improve the user experience of mobile banking, and help the growth of user value
- 用C语言开发NES游戏(CC65)09、滚动
猜你喜欢

Style conversion model style_ Transformer project instance pytorch implementation

Great! Jd.com developed the highly available website construction technology PDF recommended by the first brother. Prepare the water and chew it slowly

开源汇智创未来 | 2022 开放原子全球开源峰会 OpenAtom openEuler 分论坛圆满召开

Test platform (V) knowledge points supplement

腾讯二面:@Bean 与 @Component 用在同一个类上,会怎么样?

用C语言开发NES游戏(CC65)09、滚动

Developing NES games with C language (cc65) 08. Background collision

Full analysis of seven classical regression analysis methods

Developing NES games with C language (cc65) 10. Game cycle

laravel表单数据验证
随机推荐
Developing NES game (cc65) 07 and controller with C language
华为发布HarmonyOS 3及全场景新品,智慧体验更进一步
WebView详解
Laravel之缓存
How can a novice quickly complete the establishment of a website? Come to the free "fitting room" experience
安徽京准:北斗卫星同步时钟|北斗同步时钟|NTP网络时钟服务器
PHP日期时间运用:添加或减去特定日期的天数
Force deduction solution summary 735 planetary collision
【Try to Hack】AT、SC、PS命令提权
Full resolution of the use of go native plug-ins
云原生机器学习落地难?灵雀云助力企业快速应用 MLOps
Full analysis of seven classical regression analysis methods
8000 字讲透 OBSA 原理与应用实践
Matlab sets the size of graphics window and image and the position of legend
Ruiji takeout - day01
With the continuous waves of infringement, the U.S. patent and trademark office began to study the impact of NFT on copyright
Developing NES games with C language (cc65) 10. Game cycle
PHP timestamp subtraction converts to days, hours, minutes and seconds
php保留两位小数的几种方法介绍
“蔚来杯“2022牛客暑期多校训练营2