函数补充&Golang错误处理

字符串中常用的系统函数

统计字符串的长度(按字节len(str)

 package main
 ​
 import "fmt"
 ​
 func main() {
  str := "ttdr"
  fmt.Println("str len = ", len(str))
 ​
 }
 ​
image-20251023151637905

因为这个是按字节统计的长度,所以不能直接用于汉字字符串的长度统计,一个汉字占用三个字节。

字符串的遍历,同时处理有中文的问题r := []rune(str)

 package main
 ​
 import "fmt"
 ​
 func main() {
  str2 := "ttdr通通道人"
  for i := 0; i < len(str2); i++ {
  fmt.Println("字符=", str2[i])
  }
 }

我们先采用一个正常传统的for循环遍历数组来看一下结果

image-20251024160545306

欸怎么都是数字,我们来给他格式化输出一下

 fmt.Printf("字符=%c\n", str2[i])
image-20251024160740953

我们发现,前面的字母还很正常,但是后面的汉字就变成了乱码,因为这样遍历字符串是按照字节遍历的,就会导致汉字被拆解,变成了乱码,这时候我们就需要用标题中的方法。

 package main
 ​
 import "fmt"
 ​
 func main() {
  str2 := "ttdr通通道人"
  str3 := []rune(str2)
  for i := 0; i < len(str3); i++ {
  fmt.Printf("字符=%c\n", str3[i])
  }
 }
image-20251024162612487

就可以正确输出,带汉字的字符串。

字符串转整数: n,err := strconv.Atoi("12")

strconv.Atoi函数的介绍就直接上链接了。

 n, err := strconv.Atoi("123")
 if err != nil {
     fmt.Println("转换错误", err)
 } else {
     fmt.Println("转换的结果为", n)
 }

整数转字符串: str := strconv.Itoa(123465)

 str4 := strconv.Itoa(123465)
 fmt.Printf("str = %v,str = %T",str4,str4 )
image-20251024162620634

字符串转[]byte: var bytes = []byte(“hello ttdr”)

     var bytes = []byte("hello ttdr")
  fmt.Printf("bytes=%v", bytes)
image-20251024162943643

这里打印出来的就是字母对应的ASCII码值

[]byte转字符串: str5 = string([]byte{97,98,99})

     str5 := string([]byte{97, 98, 99})
  fmt.Println(str5)
image-20251024163605665

十进制转2,8,16进制: str = strconv.FormatInt(123,2)

strconv.FormatInt函数介绍这里放个门。

 str6 := strconv.FormatInt(123, 2)
 fmt.Println("123对应的二进制是", str6)
image-20251027093303886

查找子串是否在指定的字符串中: strings.Contains(“seafood”,”foo”)

     b := strings.Contains("seafood", "foo")
  fmt.Println(b)

统计字符串有几个指定的子串:strings.Count(“ceheese”,”e”)

     num := strings.Count("ceheese", "e")
  fmt.Printf("num = %v\n", num)
image-20251029153059872

不区分大小写的字符串比较(==是区分大小写的): fmt.Println(strings.EqualFold(“abc”, “ABc”))

     fmt.Println(strings.EqualFold("abc", "ABc"))
image-20251029153444212

子串在字符串当中第一次出现的index值:strings.Index(”NLT_abc”, “abc”)

     index := strings.Index("NLT_abc", "abc")
  fmt.Printf("index = %v", index)
image-20251029153812735

返回子串在字符串最后一次出现的 index,如没有返回 -1

 strings.LastIndex("go golang", "go")
image-20251029155916334

将指定的子串替换成另一个子串:

 strings.Replace("go go hello", "go", "go语言", n)

n 可以指定你希望替换几个,如果 n = -1 表示全部替换

image-20251029155923795

按照指定的某个字符,作为分割标识,将一个字符串拆分成字符串数组:

 strings.Split("hello,world,ok", ",")
image-20251029155934653

将字符串的字母进行大小写的转换

 strings.ToLower("Go") // go
 strings.ToUpper("Go") // GO
image-20251029155942618

将字符串左右两边的空格去掉:

 strings.TrimSpace("  \t\n a lone gopher \n\t\r ")

将字符串左右两边指定的字符去掉:

 strings.Trim("! hello! ", "! ")

将字符串左边指定的字符去掉:

 trings.TrimLeft("! hello! ", "! ")

将字符串右边指定的字符去掉:

 strings.TrimRight("! hello! ", "! ")
image-20251029155950064

日期时间相关函数

在golang里,时间日期相关函数用的包是time包

我们就先来试试获取当地时间

     //1.获取当前时间
  now := time.Now()
  fmt.Printf("now = %v", now)
image-20251029164532423

但是这么一串都不是我需要的我该怎么处理呢?而且这么一串东西,类型是字符串吗,我可以通过处理字符串一样来处理它吗?

 fmt.Printf("now = %T", now)
image-20251029164900047

我们来打印出来他的类型,我们发现他并不是字符串类型,而是time.Time类型,我们来看看官方文档,我们发现这个实际上是一个结构体,而且我们可以发现下面给了很多,如何获得年月日时分秒的方法。

image-20251029165157542
     // 2. 通过 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())
  fmt.Printf("时=%v\n", now.Hour())
  fmt.Printf("分=%v\n", now.Minute())
  fmt.Printf("秒=%v\n", now.Second())
image-20251029165415973

当然,我们也可以对时间进行格式化输出,变得更符合我们日常看到的

     // 格式化日期时间
 ​
  fmt.Printf("当前年月日 %d-%d-%d %d:%d:%d \n", now.Year(),
  now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
 ​
  dateStr := fmt.Sprintf("当前年月日 %d-%d-%d %d:%d:%d \n", now.Year(),
  now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
 ​
  fmt.Printf("dateStr=%v\n", dateStr)
image-20251029165535670

是不是变得顺眼了很多,但叽里咕噜写了这么一串太麻烦了,那有没有更简单的方法吗,有的有的兄弟

 // (2) 格式化的第二种方式:使用 time.Format() 和标准布局
 ​
 fmt.Printf(now.Format("2006/01/02 15:04:05"))
 fmt.Println()
 ​
 fmt.Printf(now.Format("2006-01-02"))
 fmt.Println()
 ​
 fmt.Printf(now.Format("15:04:05"))
 fmt.Println()
image-20251029170120209

在使用 Go 语言的 time.Format() 方法进行时间格式化时,需要注意以下要点:必须使用特定的布局字符串 "2006/01/02 15:04:05" 作为时间格式化的模板,其中的数字(2006、01、02、15、04、05)代表年、月、日、小时、分钟和秒,这些数字固定的,不能更改。但是可以按照需要自由组合这些字段以创建自定义的时间格式(比如中间是/或者是短线都可以),但要确保遵循这个标准布局。例如,若需展示日期和时间,可使用 "2006-01-02 15:04:05";若仅需时间部分,则可采用 "15:04:05" 格式。

休眠

我们常会用到一些计时功能,或者暂停几秒钟再继续运行,我们就要用到休眠,但是我们怎么规定休眠多久呢,这里就需要用到一些常量去获取指定时间单位的时间,我们先上链接时间常量

然后我们再来实现一下休眠

     fmt.Println("start...")
  time.Sleep(100 * time.Millisecond) // 休眠 100 毫秒
  fmt.Println("ending...")

时间戳

这个东西,最常见的用途就是获取随机的数字了,用Unix还有Unixnano两个方法,返回的是从 1970年1月1日 00:00:00 UTC 到现在经过的秒数(纳秒数)。

     // 获取 Unix 时间戳(秒)
  unixTime := now.Unix()
  fmt.Printf("Unix 时间戳(秒): %d\n", unixTime)
 ​
  // 获取 UnixNano 时间戳(纳秒)
  unixNano := now.UnixNano()
  fmt.Printf("UnixNano 时间戳(纳秒): %d\n", unixNano)
image-20251029171608560

当然我们也可以用时间戳来计算程序的运行时间,比如:

 package main
 import (
  "fmt"
  "strconv"
  "time"
 )
 func test03() {
  str := ""
  for i := 0; i < 100000; i++ {
  str += "hello" + strconv.Itoa(i)
  }
 }
 ​
 func main() {
  start := time.Now().Unix()
  test03()
  end := time.Now().Unix()
  duration := end - start
  fmt.Printf("test03 执行耗时: %d 秒\n", duration)
 }

内置函数

Go 语言为了提升编程效率和代码简洁性,提供了一些内置函数(built-in functions),可以直接使用,无需导入包。

len() —— 获取长度

这个用了不知道多少次了,就不演示了。

new() —— 分配内存并初始化

我们先来个案例尝尝咸淡,我们对比之前学的

 func main() {
  num1 := 100
  fmt.Printf("num1的类型是:%T ,num1的值是:%v ,num1的地址是%v\n", num1, num1, &num1)
  num2 := new(int) //*int类型
  fmt.Printf("num2的类型是:%T ,num2的值是:%v ,num2的地址是%v", num2, num2, &num2)
 }
image-20251029205927451
image-20251029210617887

make用来分配内存

主要用来分配引用类型,我们后面再将

Golang的错误处理机制

如果我们遇到一个报错,我写错了一段代码,可不可以继续向下执行,而不是直接终止运行,还可以在捕获到报错后给管理员一个提示(邮件/短信形式发给我)

Go 语言设计哲学追求简洁和优雅,所以 不支持传统语言中的 try...catch...finally 这种异常处理方式,Go 的替代方案是:defer, panic, recover

Go 用 panic 来“抛异常”,在defer中,通过recover来“捕获异常”,实现了一种轻量级但强大的错误处理机制。

我们来把错误代码尝尝咸淡

 package main
 ​
 import (
  "fmt"
 )
 ​
 func test() {
  num1 := 10
  num2 := 0
  res := num1 / num2
  fmt.Println("res=", res)
 }
 ​
 func main() {
  // 测试
  test()
  fmt.Println("main()下面的代码...")
 }
image-20251029211200075

我们来捕获一下试试。

 package main
 ​
 import (
  "fmt"
 )
 ​
 func test() {
  defer func() {
  err := recover() //内置函数可以捕获到异常
  if err != nil {
  fmt.Println("err", err)
  }
  }()
  num1 := 10
  num2 := 0
  res := num1 / num2
  fmt.Println("res=", res)
 }
 ​
 func main() {
  // 测试
  test()
  fmt.Println("main()下面的代码...")
 }
 ​
image-20251029211438782

进行错误处理后,程序不会轻易的挂掉,如果假如预警代码,可以让程序更加的健壮

自定义错误

在 Go 程序中,除了使用 panicrecover 处理异常外,还可以通过 errors.New()panic 内置函数 来创建和处理自定义错误。

errors.New() 创建自定义错误,会返回一个error类型的值,panic()内置函数,可以接受任何值作为参数, 可以用 recover() 捕获。,如果错误未被捕获,输出错误信息,终止程序,我们直接上例子

 func readConf(name string) (err error) {
  if name == "config.ini" {
  return nil
  } else {
  return errors.New("读取文件错误···")
  }
 }
 func test02() {
  err := readConf("三角洲.ini")
  if err != nil {
  //发生错误,输出错误终止程序
  panic(err)
  }
  fmt.Println("test02.....")
 }
 func main() {
  //测试自定义错误
  test02()
  fmt.Println("下面的代码...")
 }
 ​
image-20251029212545985
暂无评论

发送评论 编辑评论


				
上一篇
下一篇