文章目录
- 一、函数的基本流程及调用
- 二、包的使用原理
- 三、函数的使用注意事项
- 四、`defer`的使用
- 五、字符串常用系统函数
- 六、时间函数
- 七、常用内置函数
- 八、错误处理机制及自定义错误
一、函数的基本流程及调用
package mainimport ("fmt""strings"
)// 定义简单的函数
func lowercaseWord(word string) string { // 函数名,形参先写变量,再定义对应的参数类型,然后再定义返回值类型word = strings.ToLower(word) // 函数体fmt.Println(word)return word // 函数返回值
}func main() {lowercaseWord("ABC") // 函数调用
}
二、包的使用原理
// 包的本质是创建不同的文件夹来存放 golang 程序。
// 文件第一行package 包名
,包名与所在目录名一致,golang 程序从GOPATH
路径开始查找。
// 包中对外可被引入的变量,函数与方法的名字需要大写。
// 同一个包内,变量和方法名等不能重复。
package mainimport ("code.byted.org/go_learning/utils" // 引入自定义的包,从 GOPATH 路径下开始引入"fmt" // 引入 golang 内部包
)func main() {res := utils.LowercaseWord("ABC") // 使用引入包中的函数fmt.Println(res)
}
重点:如果要编译一个可执行的文件,这个包必须声明为main
:package main
// 语法规范。
三、函数的使用注意事项
- 支持对返回值命名:
func cal(a, b int) (s int) {s = a + b // 函数返回值声明了变量类型后,函数体内不需要再进行类型申明return
}
- go 支持自定义数据类型:
package mainimport ("fmt"
)type MathCal func(int, int) int // 自定义一个函数数据类型func sub(a int, b int) int {return a - b
}func sum(a int, b int) int {return a + b
}func main() {var op MathCalop = subres := op(10, 20)fmt.Printf("%d\n", res)
}
- 使用
_
符号,可以忽略一个返回值:
package mainfunc mathCal(a int, b int) (sum int, sub int) {sum = a + bsub = a - breturn
}func main() {s, _ := mathCal(1, 2)println(s)
}
- 在 go 函数中支持可变参数,可变参数需要放在形参列表最后:
package mainimport "fmt"func sumNum(a int, args...int) int { // 可变参数放在形参最后面sum := afor _, arg := range args {sum += arg}fmt.Println(sum)return sum
}func main() {sumNum(1, 2, 3, 4, 5)
}
init
函数,每个源文件可以有一个init
函数,在main
函数之前被调用:
package mainimport ("code.byted.org/go_learning/utils" // 1.先执行 import 包中全局变量及初始化 init 函数"fmt"
)func init() { // 再执行当前模块下的 init 函数fmt.Printf(utils.Name)fmt.Printf("%v", utils.Age)println("初始化 init 函数执行")
}func main() { // 再执行 main 函数println("主函数执行")
}
golang 匿名函数:
package mainimport "fmt"// golang 匿名函数func main() {res := func(a int, b int) int {return a * b}(1, 2) // 匿名函数,定义后即使用fmt.Printf("res value is:%v\n", res)}
golang 的闭包:
定义:闭包是一个函数值,它引用了其外部作用域中的变量。这个被引用的外部变量将和闭包函数一同存在,即使外部函数已经返回。
// 闭包package mainimport "fmt"func requestHandler(url string) func() {return func() {fmt.Println("Handling request for", url)}
}func main() {handler := requestHandler("https://example.com")// 在某个合适的时候执行闭包handler()
}
四、defer
的使用
函数中的defer
==在函数执行完成之后,及时释放资源。
package mainimport ("fmt""os"
)func main() {fmt.Println("打开一个文件...")file, _ := os.Open("/Users/bytedance/go/src/code.byted.org/go_learning/测试图片.gif")// 当执行到 defer 时,暂时先不会执行 defer 后面的语句,会先将 defer 后面的语句压到 defer 栈中// 函数执行完成后,通过先进后出的方式取出 defer 后的语句再进行执行,一般用于进行资源的关闭defer file.Close()}
五、字符串常用系统函数
package mainimport ("fmt""strconv""strings"
)func main() {// 1. len()计算字符串字节数:6println(len("我的"))// 2. 字符串遍历,同时处理有中文的字符,先转换为切片s := []rune("hello你好")for i := 0; i < len(s); i++ {fmt.Printf("%c\n", s[i])}// 3. 将字符串转换为整数atom, err := strconv.Atoi("12")if err!= nil {return}fmt.Println(atom)// 4. 将整数转化为字符串storm := strconv.Itoa(12)fmt.Println(storm)// 5.字符串转化为 byte 切片 [49 50]byteInfo := []byte(storm)fmt.Printf("%v\n", byteInfo)// 6.将 byte 切片转化为字符串 123strInfo := string([]byte{49, 50, 51})fmt.Println(strInfo)// 7.字符串是否包含字串 trueres := strings.Contains("hello", "he")println(res)// 8.统计字符串有几个字串 1num := strings.Count("hello", "he")println(num)// 9.不区分大小写字符串判断是否相等 trueres = strings.EqualFold("hello", "HeLLO")println(res)// 10.返回字串在字符串第一次/最后一次出现的 index 值,如果不存在则返回 -1num = strings.LastIndex("hellohe", "he")println(num)num = strings.Index("hello", "he")println(num)// 11.将指定的字串替换为另外的字串,可以指定替换数量或者全部替换<得到了一个新串>resString := strings.ReplaceAll("hellohello", "he", "HE")println(resString) // HElloHEllo// 12.字符串分割splitRes := strings.Split("hello world info", " ")fmt.Printf("%v\n", splitRes)// 13.字符串大小写转换upWord := strings.ToUpper("hello world")println(upWord)lowerWord := strings.ToLower("HELLO WORLD")println(lowerWord)// 14.去掉字符串两边的空格resString = strings.TrimSpace("xxx. ")println(resString)// 指定去掉两边的指定字符resString = strings.Trim("1xx1", "1")println(resString)// 去掉右边的指定字符resString = strings.TrimRight("1xx1", "1")println(resString)// 去掉左边的指定字符resString = strings.TrimLeft("1xx1", "1")println(resString)// 15.判断字符串是否以某个字符开头b := strings.HasPrefix("1xx1", "1")println(b)// 16.判断字符串是否以某个字符结尾b = strings.HasSuffix("1xx1", "1")println(b)
}
六、时间函数
// time
包
package mainimport ("fmt""time"
)func main() {// 获取当前时间now := time.Now()fmt.Printf("Res %v\n", now)// 获取当前时间的年月日时分秒fmt.Printf("年: %v\n", now.Year())fmt.Printf("月 %v\n", now.Month())fmt.Printf("月 %v\n", int(now.Month()))fmt.Printf("日 %v\n", now.Day())// 获取当前时间的格式化输出formatTime := now.Format("2006-1-2")fmt.Printf("%v\n", formatTime)// 时间常量fmt.Printf("时间常量秒: %v\n", time.Second)fmt.Printf("时间常量毫秒: %v\n", time.Millisecond)// 时间的 unix 和 unix 纳秒数fmt.Printf("unix 纳秒数:%v\n", now.UnixNano())// 获取两个时间差startTime := time.Now().Unix()endTime := time.Now().Unix()fmt.Printf("duration %v\n", endTime-startTime)
}
七、常用内置函数
https://studygolang.com/pkgdoc
package mainimport "fmt"type Person struct {Name stringAge int
}func updatePerson(p *Person) {fmt.Printf("p = %v\n", &p) // ptr 存储指针地址的内存空间的地址println(p)p.Name = "Updated Name"p.Age = 30
}
func main() {ptr := new(Person)println(ptr) // 指针 ptr 存储的指针地址fmt.Printf("ptr = %v\n", &ptr) // ptr 存储指针地址的内存空间的地址updatePerson(ptr)fmt.Printf("ptr = %v\n", ptr) //fmt.Println(*ptr) // 输出 {Updated Name 30}
}
// new(T)
函数为一个类型为T
的新项分配内存,并返回一个指向该类型零值的指针。
package mainimport "fmt"func main() {// 为类型为 int 分配新的内存,并返回一个该类型初始值的指针// prt 为指针类型,指向的内存空间存储的是:初始化类型存储的值的地址// 修改指针类型 prt 的值的方法:*prt = xxxprt := new(int)fmt.Printf("%v\n", prt) // 0x1400000e088res := cal(prt)fmt.Printf("%d\n", res)fmt.Printf("%v\n", prt)fmt.Printf("%v\n", *prt)
}func cal(a *int) int {fmt.Printf("cal params:%v\n", a) // 0x1400000e088*a = 100return *a
}
make()
为引用类型分配内存。
八、错误处理机制及自定义错误
func queryDatabase() {db, err := sql.Open("driverName", "connectionString")if err!= nil {panic(err)}defer func() {if r := recover(); r!= nil {// 记录错误日志fmt.Println("Recovered from panic:", r)// 关闭数据库连接db.Close()}}()// 执行数据库查询操作rows, err := db.Query("SELECT * FROM table")if err!= nil {panic(err)}defer rows.Close()// 处理查询结果for rows.Next() {//...}
}
package mainimport ("fmt"
)func main() {defer func() {if r := recover(); r!= nil {// 记录错误日志fmt.Println("Recovered from panic:", r)}}()panic("error") // 引发 Panic 的代码}