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等)

posted @ 2022-10-29 19:00  ZunSir  阅读(55)  评论(0编辑  收藏  举报