字符串中常用的系统函数
统计字符串的长度(按字节len(str))
package main
import "fmt"
func main() {
str := "ttdr"
fmt.Println("str len = ", len(str))
}

因为这个是按字节统计的长度,所以不能直接用于汉字字符串的长度统计,一个汉字占用三个字节。
字符串的遍历,同时处理有中文的问题r := []rune(str)
package main
import "fmt"
func main() {
str2 := "ttdr通通道人"
for i := 0; i < len(str2); i++ {
fmt.Println("字符=", str2[i])
}
}
我们先采用一个正常传统的for循环遍历数组来看一下结果

欸怎么都是数字,我们来给他格式化输出一下
fmt.Printf("字符=%c\n", str2[i])

我们发现,前面的字母还很正常,但是后面的汉字就变成了乱码,因为这样遍历字符串是按照字节遍历的,就会导致汉字被拆解,变成了乱码,这时候我们就需要用标题中的方法。
package main
import "fmt"
func main() {
str2 := "ttdr通通道人"
str3 := []rune(str2)
for i := 0; i < len(str3); i++ {
fmt.Printf("字符=%c\n", str3[i])
}
}

就可以正确输出,带汉字的字符串。
字符串转整数: 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 )

字符串转[]byte: var bytes = []byte(“hello ttdr”)
var bytes = []byte("hello ttdr")
fmt.Printf("bytes=%v", bytes)

这里打印出来的就是字母对应的ASCII码值
[]byte转字符串: str5 = string([]byte{97,98,99})
str5 := string([]byte{97, 98, 99})
fmt.Println(str5)

十进制转2,8,16进制: str = strconv.FormatInt(123,2)
strconv.FormatInt函数介绍这里放个门。
str6 := strconv.FormatInt(123, 2)
fmt.Println("123对应的二进制是", str6)

查找子串是否在指定的字符串中: 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)

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

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

返回子串在字符串最后一次出现的 index,如没有返回 -1
strings.LastIndex("go golang", "go")

将指定的子串替换成另一个子串:
strings.Replace("go go hello", "go", "go语言", n)
n 可以指定你希望替换几个,如果 n = -1 表示全部替换

按照指定的某个字符,作为分割标识,将一个字符串拆分成字符串数组:
strings.Split("hello,world,ok", ",")

将字符串的字母进行大小写的转换
strings.ToLower("Go") // go
strings.ToUpper("Go") // GO

将字符串左右两边的空格去掉:
strings.TrimSpace(" \t\n a lone gopher \n\t\r ")
将字符串左右两边指定的字符去掉:
strings.Trim("! hello! ", "! ")
将字符串左边指定的字符去掉:
trings.TrimLeft("! hello! ", "! ")
将字符串右边指定的字符去掉:
strings.TrimRight("! hello! ", "! ")

日期时间相关函数
在golang里,时间日期相关函数用的包是time包
我们就先来试试获取当地时间
//1.获取当前时间
now := time.Now()
fmt.Printf("now = %v", now)

但是这么一串都不是我需要的我该怎么处理呢?而且这么一串东西,类型是字符串吗,我可以通过处理字符串一样来处理它吗?
fmt.Printf("now = %T", now)

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

// 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())

当然,我们也可以对时间进行格式化输出,变得更符合我们日常看到的
// 格式化日期时间
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)

是不是变得顺眼了很多,但叽里咕噜写了这么一串太麻烦了,那有没有更简单的方法吗,有的有的兄弟
// (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()

在使用 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)

当然我们也可以用时间戳来计算程序的运行时间,比如:
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)
}


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()下面的代码...")
}

我们来捕获一下试试。
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()下面的代码...")
}

进行错误处理后,程序不会轻易的挂掉,如果假如预警代码,可以让程序更加的健壮
自定义错误
在 Go 程序中,除了使用 panic 和 recover 处理异常外,还可以通过 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("下面的代码...")
}










