Go----GoLand注意事项三

注意事项三

1)Go语言函数本身可以作为值进行传递,支持匿名函数、闭包、满足接口;

2)函数声明

	func funcName(parameters type1,parameters type2...) (output1 type1,output1 type2...) {
	//逻辑代码
	//返回多个值
	return value1,value2...
}
参数列表中,多个参数变量且相邻变量是同类型---语法格式:func add(a,b int){      }
可变参数---有着不定数量的参数---语法格式:func add(arg...int){    }       //参数类型全是int、函数体中的arg是一个int的slice(切片)

3)作用域:全局变量和局部变量同名时,函数内的局部变量会被优先考虑;

4)函数变量(函数作为值)—函数也是一种类型,可以被保存在变量中

使用步骤:1---定义函数类型    2---实现定义的函数类型    3---作为参数调用

案例一

package main
import "fmt"
import "strings"
func main(){
	result:=StringToLower("AbcdefG",processCase)//第二个参数传入了在13行声明的函数processCase,
	fmt.Println(result)
	result=StringToLower2("AbcdefG",processCase)
	fmt.Println(result)
}
//处理字符串,奇数偶数依次显示为大小写
func processCase(str string) string{
	result:=""
	for i,value:=range str{
		if i%2==0{
			result+=strings.ToUpper(string(value))
		} else{
			result+=strings.ToLower(string(value))
		}
	}
	return result
}
func StringToLower(str string,f func(string) string) string{//第二个传入参数为一个函数类型变量f
	fmt.Printf("%T\n",f)
	return f(str)
}
type caseFunc func(string) string//声明一个函数类型,通过type关键字,caseFunc会形成一种新的类型,caseFunc就代表着这一种函数变量使用在StringToLower2中
func StringToLower2(str string,f caseFunc) string{
	fmt.Printf("%T \n",f)//打印f的类型
	return f(str)
}

案例二

package main
import "fmt"
type processFunc func(int) bool//声明了一个函数类型
func main()  {
	slice:=[]int{1,2,3,4,5,7}
	fmt.Println("slice=",slice)
	odd:=filter(slice,isOdd)//函数当作值来传递
	fmt.Println("奇数元素:",odd)
	even:=filter(slice,isEven)//函数当作值来传递
	fmt.Println("偶数元素:",even)
}
//判断元素是否是偶数
func isEven(integer int) bool {
	if integer%2==0{
		return true
	}
	return false
}
//判断元素是否是奇数
func isOdd(integer int) bool  {
	if integer%2==0{
		return false
	}
	return true
}
//根据函数来处理切片,根据元素奇数偶数分组,返回新的切片
func filter(slice []int,f processFunc) []int  {
	var result []int
	for _,value :=range slice{
		if f(value){
			result = append(result,value)
		}
	}
	return result
}

5)匿名函数—需要时再定义函数—没有函数名(只有函数体)—作为一种类型被赋值给变量(匿名函数以变量方式传递);
匿名函数—被用于实现回调函数、闭包等;

语法格式:
func(参数列表)  (返回参数列表){
	//函数体
}
package main
import "fmt"
//定义时调用匿名函数
func main()  {
	func(data int){
		fmt.Println("hello",data)
	}(100)
}
package main
import "fmt"
//将匿名函数赋值给变量
func main()  {
	f:= func(data string) {
		fmt.Println(data)
	}
	f("你就是最优秀的!")
}
package main
import (
	"fmt"
	"math"
)
//匿名函数用作回调函数
func main()  {
	arr:=[]float64{1,4,9,16,25,40}
	//调用函数对每个元素进行求平方根操作
	fmt.Println("每个元素的平方根:")
	visit(arr, func(v float64) {
		v=math.Sqrt(v)
		fmt.Printf("%.2f\n",v)
	})
	//调用函数对每个元素进行求平方操作
	fmt.Println("每个元素的平方:")
	visit(arr, func(v float64) {
		v=math.Pow(v,2)
		fmt.Printf("%.2f\n",v)
	})
}
//定义一个函数,遍历切片元素,对每个元素进行处理
func visit(list []float64,f func(float64)){
	for _,value:=range list{
		f(value)
	}
}

6)闭包=函数+引用环境
函数—编译器静态的概念 闭包—运行期动态的概念
对象—附有行为的数据 闭包—附有数据的行为
闭包优点:加强模块化----抽象----简化代码

package main
import "fmt"
//闭包是实现计数器
func main()  {
	pos:=adder()
	for i:=0;i<10;i++{
		fmt.Printf("i=%d\t",i)//第一列数据
		fmt.Println(pos(i))//第四列数据
	}
	fmt.Println("-----------------------")

	for i:=0;i<10;i++{
		fmt.Printf("i=%d\t",i)
		fmt.Println(pos(i))
	}
}
func adder() func(int) int{
	sum:=0
	return func(x int) int {
		fmt.Printf("sum1=%d\t",sum)//第二列数据
		sum+=x
		fmt.Printf("sum2=%d\t",sum)//第三列数据
		return sum
	}
}

7)可变参数

	语法格式:
	func 函数名(参数名 ...类型)  [(返回值列表)]   {
		//函数体
	}
	传递若干值到可变参数函数中,可手动书写每个参数,也可将一个slice传递给改函数,通过“...”可以将slice中的参数对应地传递给函数;
	注意事项:一个函数最多只能有一个可变参数;若参数列表中还有类型参数,则可变参数写在所有参数的最后;
package main
import "fmt"
func main()  {
	//第一种手动书写每个参数
	sum,avg,count:=GetScore(97,82.5,99.3,69.5)
	fmt.Printf("共有%d门成绩,总成绩为:%.2f,平均成绩为:%.2f",count,sum,avg)
	fmt.Println()
	//第二种切片传递
	score:=[]float64{78.6,88,89.6,98.6,100,96.1}
	sum,avg,count=GetScore(score...)
	fmt.Printf("共有%d门成绩,总成绩为:%.2f,平均成绩为:%.2f",count,sum,avg)
}

func GetScore(scores ...float64) (sum,avg float64,count int){//分别返回总成绩、平均成绩、门数
	for _,value:=range scores{
		sum+=value
		count++
	}
	avg=sum/float64(count)
	return
}

8)指针

定义:存储另一个变量内存地址的变量;---&---取地址符获取变量的地址;
Go语言指针的特点:指针不能运算(不同于C语言);

声明指针---*T是指针变量的类型,指向T类型的值---var  指针变量名  *指针类型---*号用于指定变量是一个指针;
使用流程---定义指针变量;为指针变量赋值;访问指针变量中指向地址的值;

空指针---被定义后没有分配任何变量---nil(空指针)---等价于其他语言的null、None、NULL;
package main
import "fmt"
func main()  {
	var a int=20//声明实际变量
	var ip *int//声明指针变量
	ip=&a//给指针变量赋值
	//打印a、&a、ip、*ip、*&a的值和类型---其中&a=ip、*ip=*&a
	fmt.Printf("a的类型是%T,值是%v\n",a,a)
	fmt.Printf("&a的类型是%T,值是%v\n",&a,&a)
	fmt.Printf("ip的类型是%T,值是%v\n",ip,ip)
	fmt.Printf("*ip的类型是%T,值是%v\n",*ip,*ip)
	fmt.Printf("*&a的类型是%T,值是%v\n",*&a,*&a)
	fmt.Println(a,&a,*&a)//a值---a值地址---a值
	fmt.Println(ip,&ip,*ip,*(&ip),&(*ip))//a值地址---ip地址---a值---a值地址---a值地址
}
package main
import "fmt"
//基本数据类型指针作为函数参数
//只是复制了一个指针,指针指向的内存没有改变
func main()  {
	a:=13
	fmt.Println("调用函数前的值为:",a)
	fmt.Printf("类型是:%T\n",a)
	fmt.Printf("地址是:%x\n",&a)
	var b *int =&a
	change(b)
	fmt.Println("函数调用后的值为:",a)
}
func change(val *int)  {//形参是指针变量
	*val=173
}

9)指针数组

定义:元素为指针类型的数组;
语法格式:var ptr [3]*string
一个指针数组与一个数组完全对应,通过*指针变量获取该地址对应的数值;
package main
import "fmt"
const count int=6
func main()  {
	a:=[count]string{"ni","jiu","shi","zui","shuai","de"}
	var ptr [count]*string//定义指针数组
	fmt.Printf("%T, %v\n",ptr,ptr)
	for i:=0;i<count;i++{
		ptr[i]=&a[i]//将数组中每个元素地址赋给指针数组
	}
	fmt.Printf("%T, %v\n",ptr,ptr)
}

上一篇:GoLand 2021最新激活教程,激活码,永久激活GoLand免费获取


下一篇:Golang搭建Windows开发环境