在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、函数
函数声明 // 声明语法:Go 中函数传递的参数都是值传递(将形参的值拷贝一份给函数内部使用, 形参与实参是相互独立互不影响的),其包括普通函数、lambda函数(匿名函数)、方法 func 函数名(参数) 返回值 { 函数体 } // eg: 斐波那契数列(递归) func fibonacci(n int) int { if n < 2 { return n } else { return fibonacci(n-2) + fibonacci(n-1) } }
函数返回值 // 一个返回值的函数 func max(num1 int, num2 int) int { if num1 > num2 { return num1 } else { return num2 } } // 多个返回值的函数 func allValue(num int, name string) (int, string) { fmt.Println("In allValue function num: ", num) fmt.Println("In allValue function name: " + name) return num, name } func main() { num1 := 10 num2 := 22 result := max(num1, num2) fmt.Println("result: ", result) num, name := allValue(num2, "power") fmt.Println("In main function num: ", num) fmt.Println("In main function name: ", name) }
函数参数
func valueFunc(num1 int, num2 int) { num1, num2 = num2, num1 } // 当参数中多个参数类型一致时, 可简写参数的类型 func f1(x, y int, m, n string, i, j bool) int { return x + y } func main() { fmt.Println("值传递交换前 num1 的值: ", num1) fmt.Println("值传递交换前 num2 的值: ", num2) valueFunc(num1, num2) fmt.Println("值传递交换后 num1 的值: ", num1) fmt.Println("值传递交换后 num2 的值: ", num2) } // [Output]:值传递交换前 num1 的值: 20 // [Output]:值传递交换前 num2 的值: 10 // [Output]:值传递交换后 num1 的值: 20 // [Output]:值传递交换后 num2 的值: 10
func pointFunc(prt1 *int, prt2 *int) { *prt1, *prt2 = *prt2, *prt1 } func main(){ num1, num2 := 10, 20 var prt1 *int = &num1 var prt2 *int = &num2 fmt.Println("交换前 num1 的值: ", num1) fmt.Println("交换前 num2 的值: ", num2) pointFunc(prt1, prt2) // 指针作为函数参数,传递的是参数的地址 fmt.Println("交换后 num1 的值: ", num1) fmt.Println("交换后 num2 的值: ", num2) } // [Output]: 交换前 num1 的值: 10 // [Output]: 交换前 num2 的值: 20 // [Output]: 交换后 num1 的值: 20 // [Output]: 交换后 num2 的值: 10
可变参数:必须放在函数参数的最后, Go 语言中没有默认参数概念 // 接收相同类型的可变参数的函数 func argsSameFunc(args ... string) { fmt.Print("same type elem: ") for _, param := range args { fmt.Print(param, ", ") } fmt.Println() } // 接受不同类型的可变参数的函数 func argsDifferenceFunc(args ... interface{}) { fmt.Print("difference type elem: ") for _, param := range args { fmt.Print(param, ",") } fmt.Print("\n") } // 接收可变数量的参数, 类型约束为字符串 func joinStrings(slist ...string) string { // 定义一个字节缓冲, 快速地连接字符串 var b bytes.Buffer // 遍历可变参数列表slist, 类型为[]string for _, s := range slist { // 将遍历出的字符串连续写入字节数组 b.WriteString(s) } // 将连接好的字节数组转换为字符串并输出 return b.String() } func main() { // 接受相同类型的可变参数函数 argsSameFunc("power") argsSameFunc("forever", "topOne") argsSameFunc("selina", "hebe", "ella") // 接受不同类型的可变参数函数 argsDifferenceFunc("power", 220) argsDifferenceFunc("selina", 1031, "hebe", 330, "ella", 618) fmt.Println(joinStrings("Asia ", "sky", " crops:", "S.H.E")) fmt.Println(joinStrings("They ", "gave ", "me ", "the ", "courage ")) fmt.Print(reflect.TypeOf(num1)) // 可获取变量的类型 }
函数作为参数、返回值 // 函数作为参数传递 func calc(x, y int, op func(int, int) int) int { // 接收两个int类型的参数, 和 一个拥有 2个int类型参数、1个int类型返回值的函数类型 参数 return op(x, y) }
全局、局部变量 1、全局变量:定义在函数外部的变量, 在程序的整个运行周期内都有效, 在函数中可访问到全局变量。 2、局部变量: 分为两种, 第一种 函数内定义的变量无法在该函数外使用; 如果局部变量和全局变量重名,优先访问局部变量 3、局部变量: 第二种 语句块内定义的变量只能在语句块中生效(if、for、switch)
闭包
// 闭包: 闭包是一个函数 它包含这个函数 和 它外部作用域的变量(与其相关的引用环境) 组合而成的实体, 闭包=函数+引用环境; 底层原理: 函数可作为返回值; 函数内部查找变量的顺序, 先在函数内部找, 再往函数外部找 // 无参闭包 func adder() func(int) int { // 返回值的函数声明 与 return后的匿名函数 是一样的 var x int return func(y int) int { x += y return x } } // 带参闭包 func adder2(x int) func(int) int { return func(y int) int { x += y return x } } // 参数为函数引用的闭包 func ft(x, y int) { fmt.Println("\nThis is ft function.") fmt.Printf("ft(x - %v, y - %v)", x, y) } func adders(f func(int, int), x, y int) func() { tmp := func() { f(x, y) } return tmp }
匿名函数 // 匿名函数: 没有函数名的函数, 它无法像普通函数那样调用, 需要将匿名函数保存到某个变量, 或作为立即执行的函数 [匿名函数多用于回调函数和闭包] // 定义语法 func(参数列表)(返回参数列表){ // 函数体 } // 匿名函数 -- 作为执行函数(只执行一次), 函数定义完之后 加上() 将会立即执行 func(a, b int) { fmt.Println("self excuting function a*b result: ", a*b) }(2, 3) // 匿名函数 -- 作为回调函数 func visit(list []int, f func(int)) { for _, elem := range list { f(elem) } } func main() { // 匿名函数 // 声明时调用 func(name string) { fmt.Println("Hello ", name) } ("power") // ---> 括号内是匿名函数执行传递的参数 // 将匿名函数赋值给变量,通过 变量() 调用 innominateFunc := func(name string) string { fmt.Println("Hello ", name) receiving := "Hello" + name return receiving } innominateFunc("hebe") // 匿名函数作为回调函数 打印切片中的所有元素 visit([]int {313, 618, 1031}, func(v int) { // params: 切片,匿名函数(注意,此处的匿名函数在 visit函数的参数括号内,是作为参数传递给 visit 的) fmt.Println(v) }) }
方法 // 结构体 type Circle struct { radius float64 } // 方法 func (circle Circle) method(msg string) float64 { fmt.Println("The radius of the circle is: ", circle.radius) return 3.14 * circle.radius * circle.radius } func main() { var circle Circle circle.radius = 10.00 area := circle.method("This is a way of finding the area of a circle") fmt.Println("The area of the circle is: ", area) fmt.Print("\n") ?
二、指针 package main import "fmt" const count int = 5 func pointFunc(prt1 *int, prt2 *int) { *prt1, *prt2 = *prt2, *prt1 } func main() { // 指针声明 var ip *int var fp *float32 var ipNum int var fpFloat float32 ipNum = 618 fpFloat = 3.13 // 指针赋值 ip = &ipNum fp = &fpFloat fmt.Println("ip: ", ip) fmt.Println("fp: ", fp) // 空指针 var prt *string fmt.Println("prt: ", prt) if (prt != nil){ fmt.Println("prt isn't empty pointer.") } else { fmt.Println("prt is empty pointer.") } fmt.Print("\n") // 指针数组 var array = [] int{1, 3, 5, 7, 9} var ptr [count]*int zero := 0 for t:=0; t<count; t++ { ptr[t] = &array[t] } for r:=0; r<count; r++ { // 打印数组内元素内存地址赋值给指针数据后的所有内存地址 fmt.Print(array[r], "\t") fmt.Print(*ptr[r], "\t") fmt.Print(ptr[r], "\t") // 修改指针数组内所有元素的内存地址 ptr[r] = &zero fmt.Print(ptr[r], "\t") fmt.Println(*ptr[r]) } fmt.Print("\n") // 指向指针的指针变量 var a = 22 var aptr1 *int var aptr2 **int aptr1 = &a aptr2 = &aptr1 fmt.Println("a value: ", a) fmt.Println("a memory address: ", &a) fmt.Println("aptr1 value: ", aptr1) fmt.Println("*aptr1 value: ", *aptr1) fmt.Println("&aptr1 memory address: ", &aptr1) fmt.Println("aptr2 value: ", aptr2) fmt.Println("*aptr2 value: ", *aptr2) fmt.Println("**aptr2 value: ", **aptr2) fmt.Println("&aptr2 memory address: ", &aptr2) fmt.Print("\n") // 指针作为函数的参数 num1, num2 := 10, 20 var prt1 *int = &num1 var prt2 *int = &num2 fmt.Println("指针传递交换前 num1 的值: ", num1) fmt.Println("指针传递交换前 num2 的值: ", num2) pointFunc(prt1, prt2) fmt.Println("指针传递交换后 num1 的值: ", num1) fmt.Println("指针传递交换后 num2 的值: ", num2) }
三、结构体 // 声明语法 type 结构体名称 struct { 字段名1 字段1类型 字段名2 字段2类型 字段名3 字段3类型 ... } // 示例1:每行声明一个字段 type Member struct { name string age int weight float64 height float32 } // 示例2:同类型字段声明在同一行 type Test struct { one, two, three int four string five float32 six float64 seven bool } // 第一种方式实例化结构体 var members Member members.name = "power" members.age = 20 members.weight = 47 // 第二种方式实例化结构体 member := Member{"top", 18, 45, 1.65} member := Member{"name": "top", "age": 18, "weight": 45, "height": 1.65} returnValue := member.method(param)
|
请发表评论