Golang基础-函数
一、引入函数
提高代码的复用性,减少代码的冗余,提高代码的维护性
为完成某一功能的程序指令(语句)的集合,称为函数
基本语法:
func 函数名(形参列表)(返回值类型列表){ 执行语句 return + 返回值列表 }
完整代码
package main
import "fmt"
func main() {
	// 调用函数
	sum := cal(10, 20)
	fmt.Println(sum)
	// 求两个数的和
	//var n1 int = 10
	//var n2 int = 20
	// 求和
	//sum := n1 + n2
	//fmt.Println(sum)
	// 30+40
	//var n3 int = 30
	//var n4 int = 40
	//求和:
	//sum1 := n3 + n4
	//fmt.Println(sum1)
}
// 自定义函数:功能:两个数相加
// 使用func关键字来定义函数
// cal为函数名称
// (num1,num2)为形参列表
// (int) 为函数返回值类型
func cal(num1 int, num2 int) (int) { // 如果返回值类型只有一个的话,() 可以省略不写
	sum := num1 + num2
	return sum
}
二、函数的细节1
函数名
遵循标识符命名规范:见名知意、驼峰命名(addNum)
首字母不能是数字
首字母大写该函数可以被本包文件和其他包文件使用
首字母小写只能被本包文件使用,其他包不能使用
形参列表:
可以是一个参数,可以是n个参数,可以是0个参数
作用:接收外来数据
返回值类型列表:
可以返回0个数据
package main import "fmt" // 返回0个数据,直接使用fmt.Println打印结果 func cal1(num1 int, num2 int) { sum := num1 + num2 fmt.Printf("num1:%v + num2:%v 的和为:%v", num1, num2, sum) }可以返回1个数据,如果返回值只有一个,() 可以省略不写
可以返回多个数据
package main
import "fmt"
// 返回两个数据
func cal1(num1 int, num2 int) (int, int) {
	// 求和
	sum := num1 + num2
	// 求差
	result := num1 - num2
	return sum, result
}
func main() {
	// 接收 cal1 的返回值
	// sum 接收和的结果,result 接收 差的结果
	sum, result := cal1(20, 10)
	fmt.Println("和为:", sum)
	fmt.Println("差为:", result)
}
三、函数的细节2
函数不支持重载
函数支持可变参数
package main import "fmt" // 可变参数,参数的数量是可变的 // nums... int:可以传入任意多个数量的 int 类型数据 func test(nums ...int) { // 函数内部处理可变参数,把可变参数当作切片处理 // 使用for range 进行遍历 for _, v := range nums { fmt.Println(v) } } func main() { test(1) test(1, 2, 3, 4) test(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) }基本数据类型和数组默认都是值传递,即进行值拷贝。在函数内修改不会影响原来的值
package main
import "fmt"
// 值传递
func test1(num int) {
	num = 30
	fmt.Println("test---", num)
}
func main() {
	var num int = 10
	test1(num)
	fmt.Println("main---", num)
}
以值传递方式的数据类型,如果希望在函数内的变量能修改函数外的变量,可以传入变量的地址,函数内以指针的方式操作变量。从效果看似引用传递
package main
import "fmt"
// 参数的类型为指针
func test1(num *int) {
	*num = 30
	fmt.Println("test---", *num)
}
func main() {
	var num int = 10
	// 调用 test1函数时,传入的是num的地址
	test1(&num)
	fmt.Println("main---", num)
}
四、函数的细节3
在 Go 中,函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型的变量,通过该变量可以对函数调用
package main
import "fmt"
// 定义一个函数
func test(num int){
    fmt.Println(num)
}
func main(){
    // 函数也是一种数据类型,可以赋值给一个变量
    a := test
    // 输出结果:
    //  a对应的类型为:func(int)
    //  test函数对应的类型为:func(int)
    fmt.Printf("a对应的类型为:%T,test函数对应的类型为:%T\n",a,test)
    // 调用函数
    a(10) // 等价:test(10)
}
函数既然是一种数据类型,因此在 Go 中函数可以作为形参,并且调用
package main
import "fmt"
// 定义一个函数
func test(num int){
    fmt.Println(num)
}
// 定义一个函数:形参列表类型为 int float32 func(int)
func test02(num1 int,num2 float32,testFunc func(int) ){
    fmt.Println("test02函数调用成功")
}
func main(){
    // 函数也是一种数据类型,可以赋值给一个变量
    a := test
    // 输出结果:
    //  a对应的类型为:func(int)
    //  test函数对应的类型为:func(int)
    fmt.Printf("a对应的类型为:%T,test函数对应的类型为:%T\n",a,test)
    // 调用函数
    a(10) // 等价:test(10)
    
    // 调用test02函数
    test02(10,3.14,test)
    // 因为这里a等价于 test函数,所以也可以直接传入a变量
    test02(10,3.14,a)
    
}
为了简化数据类型定义,Go 支持自定义数据类型
// 基本语法:
// type 自定义数据类型名 数据类型
type myInt int // myInt 等价于 int 来使用
// 等价一个函数类型 func(int,int)int
type mySum func(int,int)int
完整代码:
package main
import "fmt"
// 自定义数据类型(相当于起别名)
type myInt int
// 自定义函数类型
type myFunc func(int)
func test03(testFunc myFunc) {
	fmt.Println("test03函数-测试自定义函数类型")
}
func test2(num int) {
}
func main() {
	// 定义一个myInt类型的变量
	var num myInt = 10
	fmt.Println(num)
	fmt.Printf("%T\n", num) // main.myInt
	var num1 int = 30
	// 虽然是别名,但是在go中编译识别的时候还是以为myInt和int不是一种数据类型
	// 如果想要使用要进行强行转换
	num1 = int(num)
	fmt.Println(num1)
	// 调用函数
	test03(test2)
}
支持对函数返回值命名
func test06(num1 int,num2 int)(sum int,sub int){
	// 求和
	sum = num1 + num2
	// 求差
	sub = num1 - num2
	return
}
五、init函数
init函数:初始化函数,可以用来进行一些初始化操作每个源文件都可以包含一个
init函数,该函数会在main函数之前执行
package main
import "fmt"
// 初始化函数
func init() {
	fmt.Println("init 函数被执行")
}
// 程序入口
func main() {
	fmt.Println("main函数被执行")
}
六、匿名函数
Go支持匿名函数,如果某个函数只希望执行一次,可以考虑使用匿名函数
匿名函数使用方式:
(1)在定义匿名函数时就直接被调用,这种方式匿名函数只能调用一次
(2)将匿名函数赋给一个变量,再通过该变量来调用匿名函数
package main
import "fmt"
func main() {
	// 定义匿名函数
	sum := func(num1 int, num2 int) int {
		return num1 + num2
	}(10, 20)
	fmt.Println(sum)
	// 将匿名变量赋给变量
	sub := func(num1 int, num2 int) int {
		return num1 - num2
	}
	// 调用函数
	result := sub(20, 10)
	fmt.Println(result)
}
七、系统函数
1. 字符串相关函数
len(str):统计字符串长度,按字节统计
package main
import "fmt"
func main() {
	// 统计字符串长度
	str := "Hello,Goalng"
	fmt.Println(len(str)) // 12
	// 在Golang中,汉字是utf-8字符集,一个汉字3个字节
	name := "小明"
	fmt.Println(len(name))  // 6
}
r := []rune(str):对字符串进行遍历
package main
import "fmt"
func main() {
	// 遍历字符串
	str := "Hello,Golang"
	// 使用 []rune(str),把字符串转换成切片
	r := []rune(str)
	// for循环遍历切片并输出
	for i := 0; i < len(r); i++ {
		fmt.Printf("%c\n", r[i])
	}
}
strconv.Atoi("66"):字符串转整数
package main
import (
	"fmt"
	"strconv"
)
func main() {
	// 字符串转整数
	str := "123"
	
	atoi, _ := strconv.Atoi(str)
	
	// 输出结果:atoi的类型为:int,atoi=123
	fmt.Printf("atoi的类型为:%T,atoi=%v", atoi, atoi)
}
strconv.Itoa(88):整数转字符串
package main
import (
	"fmt"
	"strconv"
)
func main() {
	// 整数转字符串
	num1 := 88
	str := strconv.Itoa(num1)
	// 输出结果:str类型为:string,str=88
	fmt.Printf("str类型为:%T,str=%v", str, str)
}
strings.Contains("javago","go"):查找子串是否在指定的字符串中
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 查找子串是否在指定的字符串中
	str := "javaandgolang"
	result := strings.Contains(str, "go")
	
	fmt.Println(result) // true
}
strings.Count("javaandgolang","a"):统计一个字符串中有几个指定子串
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 统计一个字符串中有几个指定子串
	str := "javaandgolang"
	res := strings.Count(str, "a")
	
	fmt.Println(res) // 4
}
strings.EqualFold("go","GO"):不区分大小写进行字符串比较
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 不区分大小写进行字符串比较
	str := "go"
	res := strings.EqualFold(str, "GO")
	fmt.Println(res) // true
}
strings.Index("go","g"):返回子串在字符串第一次出现的索引值,如果没有返回-1
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 返回子串在字符串第一次出现的索引值,如果没有返回-1
	str := "javaandgolang"
	result := strings.Index(str, "a")
	
	fmt.Println(result) // 1
}
strings.Replace("goandjavago","go","golang",n)
n可以指定你希望替换几个,如果n=-1代表全部替换,替换2个就是n=2
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 替换字符串
	str := "goandgojavago"
	// 使用 Replace() 函数替换字符串,把go替换为golang
	str1 := strings.Replace(str, "go", "golang", -1)
	fmt.Println(str1) //golangandgolangjavagolang
}
string.Split("go-python-java","-")
按照指定的某个字符,为分割标识,将一个字符串拆分成字符串数组
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 分割字符串
	str := "java-python-golang"
	// 使用 Split() 函数进行分割,以-为标识
	result := strings.Split(str, "-")
	fmt.Println(result) // [java python golang]
}
string.ToLower("GOLANG"),strings.ToUpper("golang")
将字符串字母进行大小写转换
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 将字符串字母进行大小写转换
	str1 := "golang"
	// 转换为大写
	str1 = strings.ToUpper(str1)
	fmt.Println(str1) // GOLANG
	str2 := "GOLANG"
	// 转换为小写
	str2 = strings.ToLower(str2)
	fmt.Printf(str2) // golang
}
strings.TrimSpace(" golang "):去除字符串两边的空格
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 去除字符串两边空格
	str := " golang "
	fmt.Println(strings.TrimSpace(str)) // golang
}
strings.Trim("~golang~","~"):去除字符串两边指定的字符
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 去除字符串两边指定的字符
	str := "~golang~"
	fmt.Println(strings.Trim(str, "~")) // golang
}
strings.TrimLeft("~golang~","~"):去除字符串左边指定的字符
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 去除字符串左边指定的字符
	str := "~golang~"
	fmt.Println(strings.TrimLeft(str, "~")) // golang~
}
strings.TrimRight("~golang~","~"):去除字符串右边指定的字符
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 去除字符串右边指定的字符
	str := "~golang~"
	fmt.Println(strings.TrimRight(str, "~")) // ~golang
}
strings.HasPrefix("http://a.com","http"):判断字符串是否以指定字符开头
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 判断字符串是否以指定字符开头
	url := "http://www.baidu.com"
	flag := strings.HasPrefix(url, "http://")
	fmt.Println(flag) // true
}
strings.HasSuffix:判断字符串是否以指定字符结尾
package main
import (
	"fmt"
	"strings"
)
func main() {
	// 判断字符串是否以指定字符结尾
	url := "http://www.baidu.com"
	flag := strings.HasSuffix(url, ".com")
	fmt.Println(flag) // true
}
2. 日期和时间相关函数
时间和日期函数,需要导入
time包
获取当前时间:time.Now()
package main
import (
	"fmt"
	"time"
)
func main() {
	// time.Now() 获取当前时间
	currentTime := time.Now()
	// time.Now()返回结果是一个结构体
	fmt.Printf("%T\n", currentTime) // time.Time
	fmt.Println(currentTime)
	
	// 调用结构体中的方法
	fmt.Printf("年:%v \n", currentTime.Year())
	fmt.Printf("月:%v \n", currentTime.Month()) // October
	fmt.Printf("月:%v \n", int(currentTime.Month())) // 10
	fmt.Printf("日:%v \n", currentTime.Day())
	fmt.Printf("时:%v \n", currentTime.Hour())
	fmt.Printf("分:%v \n", currentTime.Minute())
	fmt.Printf("秒:%v \n", currentTime.Second())
}
日期格式化方法1:
package main
import (
	"fmt"
	"time"
)
func main() {
	// time.Now() 获取当前时间
	currentTime := time.Now()
	// Printf 将字符串直接输出
	fmt.Printf("当前年月日:%d-%d-%d,时分秒:%d:%d:%d \n",
		currentTime.Year(), currentTime.Month(), currentTime.Day(),
		currentTime.Hour(), currentTime.Minute(), currentTime.Second())
	// Sprintf 可以得到这个字符串
	dateStr := fmt.Sprintf("当前年月日:%d-%d-%d,时分秒:%d:%d:%d \n",
		currentTime.Year(), currentTime.Month(), currentTime.Day(),
		currentTime.Hour(), currentTime.Minute(), currentTime.Second())
	
	fmt.Println(dateStr)
}
日期格式化方法2:
package main
import (
	"fmt"
	"time"
)
func main() {
	// time.Now() 获取当前时间
	currentTime := time.Now()
	
	// 这个字符串的各个数字是固定的,必须这样写
	dateStr := currentTime.Format("2006/01/02 15:04:05")
	fmt.Println(dateStr)
}
3. 内置函数
内置函数/内建函数是为了编程方便提供了一些函数,不用导包可以直接使用
内置函数存放位置
在
builtin包下,使用内置函数,直接用就行
常见的内置函数
len函数:统计字符串长度,按字节进行统计
new函数:分配内存,主要用来分配值类型(int系列、float系列、bool、string、数组和结构体struct)
make函数:分配内存,主要是用来分配引用类型(指针、slice切片、map、管道chan、interface等)

                
            
        
浙公网安备 33010602011771号