函数的使用

01.访问权限

  • Go语言没有像其他语言一样有public、protected、private等访问控制修饰符
  • Go语言通过字母大小写来控制可见性的。
  • 如果定义的常量、变量、类型、接口、结构、函数等的名称是:大写字母开头表示能被其它包访问或调用(相当于public),非大写开头就只能在包内使用(相当于private,变量或常量也可以下划线开头)

在这里插入图片描述

package mycom
import "fmt"
func IsBlank(str string) bool {
        return isEmpty(str)  //调用私有函数
}
func isEmpty(str string) bool {
        if  len(str) >0 {
             return true
        }
        return false
}




//“Public”函数要大写字母开头。
//若以小写字母开头,同包可以访问,其他包不能访问。

本地调用,测试效果:
在这里插入图片描述

02.匿名函数

  • 匿名函数的特点:
  • Go语言支持匿名函数,在Go语言中也称作函数字面量;
  • Go语言支持随时在代码里定义匿名函数;可以在需要使用函数式再定义函数;
  • 函数可以作为一种类型被赋值给函数类型的变量,匿名函数也往往以变量方式传递
  • Go语言中的匿名函数是指不需要定义函数名的一种函数实现方式,由一个不带函数的函数声明和函数体组成。
  • 匿名函数的定义:
    在这里插入图片描述
package main
import (
	"fmt"
)
func main() {
	//定义并调用Go语言的匿名函数
	func(){
		fmt.Println("Hello HaiCoder")
	}()
}



//运算结果为:
Hello HaiCoder

  • 定义了一个匿名函数,并且在该匿名函数的最后使用()的形式来调用该匿名函数,结果输出了匿名函数的函数体内容。
  • 如果该匿名函数最后不加(),那么该匿名函数就不会被执行。
package main
import (
	"fmt"
)
func main() {
	//定义并调用带参数的匿名函数
	func(num1, num2 int){
		fmt.Println(num1, " + ", num2, " = ", num1+num2)
	}(10, 20)
}





//运算结果为:
10 + 20 = 30

  • 定义了一个带两个int类型参数的匿名函数,并且在该匿名函数的最后使用()的形式来调用该匿名函数,在()里面我们传入了10和20,即10和20是这个匿名函数的参数,结果输出了这两个参数的和。
  • 匿名函数的使用总结:
  • 定义并同时调用匿名函数,在定义匿名函数时,可以通过在匿名函数后添加“()”的方式直接传入实参。
  • 匿名函数赋值给函数变量,就可以通过调用函数变量来使用匿名函数。
  • 匿名函数作为参数:
func walk(lis []int, callback func(int)){
}

匿名函数作为参数案例:

  • 定义了一个带两个参数的函数walk,第一个参数是一个int切片,第二个参数是一个带int类型参数的匿名函数callback;
  • 该函数的功能是使用for循环遍历切片里的每一个数,并调用callback。
package main
import "fmt"
func processNumber(num int, callback func(int)) {
        callback(num)  // 调用传入的回调函数
}
func main() {
    processNumber(5, func(n int) {
        fmt.Println("Num = ", n)
    })    
processNumber(10, func(n int) {
        fmt.Println("Num = ", n)
    })
}






//运算结果为:
Num = 5
Num = 10

package main
import "fmt"
func printNumber(num int){
    fmt.Println("Num =", num)
}
func processNumber(num int, callback func(int)) {
    callback(num)
}
func main() {
processNumber(5, printNumber)
    processNumber(10, printNumber)
 }  




//运算结果为:
Num = 5
Num = 10

Go语言中**也可以先定义出函数**,再将函数作为参数

03.闭包

  • 闭包的作用:
  • 函数本身不存储任何信息,只有与引用环境结合后形成的闭包才具有“记忆性”;
  • 函数是编译期静态的概念,而闭包是运行期动态的概念化
  • 闭包(Closure)在某些编程语言中也被称为Lambda表达式。
  • 闭包的特性:
  • 函数 + 引用环境 = 闭包;
  • 闭包是一种特殊匿名函数
  • 闭包是指引用了自由变量的函数,被引用的自由变量和函数一同存在;
  • 即使已经离开了自由变量的环境也不会被释放或者删除,在闭包中可以继续使用这个自由变量。
package main
import "fmt"
func main() {
        f := demo()
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
}
func demo() func() int {
        var x int
        return func()  int {
             x++
             return x * x
        }
}



//运行结果为:
1
4
9
16

fmt.Println(f())表示为在打印时调用f()函数,在demo()函数中给予赋值,多层嵌套形成闭包环境。

04.多返回值函数

  • 在Go语言中定义函数格式时,会存在返回值参数及类型;
  • Go语言中函数可以不返回任何值;
  • Go语言中函数可以返回一个或者多个值,即在定义返回参数时可以定义多个,类型也可以是多个,多返回值能方便地获得函数执行后的多个返回参数。
  • 多返回值定义:
    1.同一种类型返回值;
    2.带有变量名的返回值。

  • 同一种类型返回值:

  • 用括号将多个返回值类型括起来;
  • 用逗号分隔每个返回值的类型;
  • 使用return语句返回时,值列表的顺序需要与函数声明的返回值类型一致
  • 同一种类型返回值定义:
func funcName(param1, param2 paramType1, ...)(returnValue1, returnValue2, ...Type){
	//执行语句...
	return 返回值列表
}

  • 带有变量名的返回值:
  • Go语言中还支持对于返回值进行命名,即返回值就和参数拥有相同的参数变量名称和类型
  • 对于拥有命名的返回值变量的默认值为该类型的默认值,即数值为0,字符串为空字符串,布尔为false,指针为nil等。
  • 带有变量名的返回值定义:
func 函数名(参数列表) (返回值名称1 类型1,返回值名称2 类型2){ 
    return
} 

package main
import (
    "fmt"
    "math"
)
func getPageCount(pageSize int)(isOk bool, pageCount int){
    if pageSize <= 0{
        return
    }
    pageCount = int(math.Ceil(float64(100/pageSize)))
    isOk = true
    return
}
func main() {
    if isOk, pageCount := getPageCount(10); !isOk{
        fmt.Println("Error")
    }else{
        fmt.Println("Ok, PageCount =", pageCount)
    }
}




//运行结果为:
Ok, PageCount = 10

我们定义了一个函数getPageCount,传入一个int类型的参数pageSize,函数返回一个bool类型的变量表示函数是否执行成功,和一个int类型的变量表示最终有多少页数据。

package main
import "fmt"
func calcute(a int, b int) (int, int) {
	if a == 0 && b == 0 {
		return 0, 0
	} else {
		return a * b, a + b
	}
}
func main() {
	fmt.Println(calcute(11, 12))
}




//运行结果为:
132 23

返回值类型有两个,return后面跟了两个返回值。

05.包管理

在这里插入图片描述

  • GOPATH:
  • 在Go语言中是不存在文件的概念的,通过目录结构来体现项目工程的结构关系;
  • Go代码可以放在GOPATH工作中;
  • Go中所有操作基本都是围绕GOPATH来进行的,即GOPATH必须要设置,但并不是固定不变的;
  • GOPATH的目的是为了告知Go需要代码的时候去哪里查找,这里的代码包括本项目和外部项目的代码;
  • 其中工作区类似于目录,这个目录包含三个子目录:src目录、pkg目录、bin目录。

-src目录

  • 用于以代码包的形式组织并保存Go源码文件(如:go.c.h.s等)
  • 是Go编译时查找代码的地方

-pkg目录

  • 用于存放经由go get/install命令构建安装后的代码包的 “.a” 归档文件(分类)
  • 是编译生成的lib文件存储的地方

-bin目录

  • 与pkg目录类似,在通过go get/install 命令完成安装后,保存由Go命令源码文件生成的可执行文件

-目录src用于包含所有的源代码,是Go命令行工具一个强制的规则
-pkg和bin则无须手动创建,必要时Go命令行工具在构建中会自动创建

  • GOROOT:
  • 是Go语言的程序安装目录
  • 目的是告知Go当前的安装位置

在这里插入图片描述

  • 包:
  • Go语言的包借助了目录树的组织形式;
  • 一般包的名称就是其源文件所在目录的名称;
  • 虽然Go语言没有强制要求包名必须和其所在的目录名同名,但还是建议包名和所在目录同名,这样结构更清晰;
  • 同一个目录下的同级的所有go文件应该属于一个包。
  • 包的习惯用法:
  • 包名一般是小写的,使用一个简短且有意义的名称;
  • 包名一般要和所在的目录同名,也可以不同,包名中不能包含-等特殊符号
  • 包一般使用域名作为目录名称,这样能保证包名的唯一性,比如GitHub项目一般会放到GOPATH/src/github.com/userName/projectName目录下
  • 包名作为main的包为应用程序的入口包,编译不包含main包的源码文件时不会得到可执行文件
  • 一个文件夹下的所有源码文件只能属于同一个包,同样属于同一个包的源码文件不能放在多个文件夹下
    -包的标准引用
import fmt

-包的设置别名引用

import format_go fmt

-包的省略方式引用

import . fmt

-仅执行包的初始化函数

import _ fmt

-单行导入

import "package1"
import "package2"

-多行导入

import (
    "package01"
    "package02"
)

  • 注意事项:
  • import导入语句通常放在源码文件开头包声明语句的下面
  • 导入的包名需要使用双引号包裹起来
  • 包名是从GOPATH/src后开始计算的,使用/进行路径分隔
  • 若包是Go语言标准库包,也就是本地包,可以直接调用,如果是远程服务器的包或者第三方接口的包,则需要import加具体路径,在导入之前还需要通过
    go get 命令下载远程包
  • Go Modules:

Go Modules的出现是为了解决GOPATH无法区分依赖项版本和依赖项列表无法数据化的问题,它是语义化版本管理的依赖项的包管理工具。

  • 初始化项目:
go mod init 模块名称

在这里插入图片描述

  • 引入包:
    /learn/demo/demo.go文件:
package demo
import (
    "fmt"
)
func PrintStr() {
    fmt.Println("好好学习,天天向上")
}

/learn/main.go文件:

package main
import (
    "come.center.cn/learn/demo"
)
func main() {
    demo.PrintStr()
}

在这里插入图片描述

  • 包引用注意事项:
  • 使用Go Module可以不在GOPATH目录下创建项目;
  • 使用import语句导入包时,使用的是包所属文件夹的名称;
  • 包中的变量、函数、结构体、方法等如果需要在当前包的外部调用,在命名时需要首字母大写;
  • 自定义包的包名不必与其所在文件夹的名称保持一致,但为了便于维护,建议保持一致;
  • 调用自定义包时,使用“包名.函数名”的方式;
  • 在Go语言中,通过名称首字母大小写来控制变量、函数、结构体等实体的访问关系。如果实体名称以小写字母开头,则只在当前包中可见,可在当前包中直接使用。如果实体名称以大写字母开头,则是公共变量,在其他包中可见,可导入使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值