GO学习之 常用系统函数_字符串相关函数_时间函数_内置函数

一.常用的字符串函数

后面的一些需要导入strings包

//(1)统计字符串的长度,按字节len(str)
package main

import "fmt"

func main() {

    // 统计字符串的长度,按字节
    // 一个英文字母占用一个字节
    // utf8中一个中文编码一个字符三个字节
    str := "hello东"
    fmt.Println("str len=",len(str))  // 8
}

//(2)字符串变量,同时处理有中文的问题 r :[] rune(str)
    str2 := "hello深圳"
    // 有中文的话,需要转rune
    str3 := []rune(str2)
    for i := 0; i < len(str3); i++ {
        fmt.Printf("字符=%c\n",str3[i])
    }
//(3)字符串转整数: n.err = stronv.Atoi(“123”)
    // 字符串转整数:n,err := strconv.Atoi("12")
    n, err := strconv.Atoi("123")
    if err != nil{
        fmt.Println("转换错误",err)
    } else {
        fmt.Println("转成的结果是",n)
    }
//(4)整数转字符串: str = strconv.Itoa(“hello”)
    // 整数转字符串
    str4 := strconv.Itoa(12345)
    fmt.Printf("str=%v, str_type=%T",str4,str4)
//(5)字符串转byte
    // 字符串转byte
    var bytes = []byte("hello go")
    fmt.Printf("bytes=%v\n",bytes)
//(6)byte转字符串
    // byte 转字符串
    str5 := string([]byte{97, 98, 99})
    fmt.Println("str5=", str5)

//(7)10 进制转 2,8,16进制
    // 10 进制转 2,8,16进制  返回对应的字符串
    str6 := strconv.FormatInt(123, 2)
    fmt.Printf("123对应的二进制是=%v\n",str6)
    str7 := strconv.FormatInt(123,8)
    fmt.Printf("123对应的8进制是=%v\n",str7)
    str8 := strconv.FormatInt(123,16)
    fmt.Printf("123对应的16进制是=%v\n",str8)

//(8)查找子串是否在指定的字符串中
需要导入strings
    // 查找子串是否在指定的字符串中
    is_in := strings.Contains("hszllo","llo")
    fmt.Println("是否存在",is_in)

//(9)统计一个字符串中有几个指定的子串
    // 统计一个字符串中有几个指定的子串
    num := strings.Count("hahahahahhahah", "ha")
    fmt.Printf("出现%v次",num)

//(10)不区分大小的字符串比较(==是字母大小写的)
    // 不区分带小写比较
    is_eq := strings.EqualFold("ASD","asd")
    fmt.Println("是否相同",is_eq)

//(11)返回子串在字符串中第一个出现的index值,如果没有返回-1
    // 返回子串Index值
    index := strings.Index("NNN_ABC","ABC")
    fmt.Println("返回index=",index)

//(12)返回子串最后一次出现的index,如果没有返回-1
    // 返回子串最后一次出现的index,如果没有返回-1
    index_02 := strings.LastIndex("go go go goLang","go")
    fmt.Println("最后一次出现index=",index_02)
//(13)字符串的替换
strings.Replace(“hello go go go”,”go”,”go 语言”,n) 
n 可以指定希望替换几个,如果n=-1表示全部替换

    //字符串的替换
    rp_str := strings.Replace("hello go go go","go","go 语言",3) 
    fmt.Println("替换后的结果:",rp_str)

//(14)字符串的分割,才分为字符串数组

    // 字符串的分割,才分为字符串数组
    strArr := strings.Split("hello,world,ok",",")
    fmt.Println("strArr=",strArr)
    // 遍历数组
    for i := 0 ; i <len(strArr); i++ {
        fmt.Println(strArr[i])
    }


//(15)字符串中的带小写转换
    // 字符串中的带小写转换
    // strings.ToLower("GO")
    // strings.ToUpper("go")
    res1 := strings.ToLower("GO")
    fmt.Println("变成小写:",res1)
    res2 := strings.ToUpper("go")
    fmt.Println("变成大写:",res2)
//(16)字符串左右空格去掉

    // 字符串左右空格去掉
    new_str_01 := strings.TrimSpace("  hello go !   ")
    fmt.Println("去掉空格的:",new_str_01)
//(17)字符串去掉左右两边的字符串
    // 去掉左右两边指定的字符串
    new_str_02 := strings.Trim("!!hello go !!","!!")
    fmt.Println("去掉左右两边指定的!:",new_str_02)

//(18)字符串去掉左边指定字符串
     // 去掉左边指定的字符串
    new_str_03 := strings.TrimLeft("!!hello go !   ","!!")
    fmt.Println("去掉左边指定的!:",new_str_03)

//(19)字符串去掉右边指定的字符串
    // 去掉右边指定的字符串
    new_str_04 := strings.TrimRight("!!hello go !!","!!")
    fmt.Println("去掉右边指定的!:",new_str_04)

//(20)判断字符串是否以指定的字符串开头
    // 判断字符串是否以指定的字符串开头
    is_start := strings.HasPrefix("ftp://127.0.0.1","ftp")
    fmt.Println("是否为ftp开头:",is_start)

//(21)判断字符串是否以指定的字符串结尾
    // 判断字符串是否以指定的字符串结尾
    is_end := strings.HasSuffix("www.baidu.com","com")
    fmt.Println("是否为com结尾:",is_end)

  

二.常用的时间与日期函数

时间和日期相关函数,需要导入time包

1.time.Time 时间类型

例:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 日期和时间相关函数与方法的使用
    // 1.获取当前时间
    now := time.Now()
    fmt.Printf("当前时间为:now=%v\n时间类型为:time_type=%T\n",now,now)
    // 打印结果:
    // 当前时间为:now=2020-03-15 17:59:06.3353254 +0800 CST m=+0.002996901
    // 时间类型为:time_type=time.Time

    // 通过now获取到年月日,时分秒
    fmt.Printf("年=%v\n",now.Year())
    fmt.Printf("月=%v  %v\n",now.Month(),int(now.Month())) // 英文的  数字加int强转
    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("周=%v\n",now.Weekday())
}

2.格式化日期和时间

方式一:

例:

port (
    "fmt"
    "time"
)

func main() {
    // 格式化日期时间
    now := time.Now()
    fmt.Printf("当前年月日 时分秒 %02d-%02d-%02d %02d:%02d:%02d\n",
    now.Year(),now.Month(),now.Day(),
    now.Hour(),now.Minute(),now.Second())
    dateStr := fmt.Sprintf("当前年月日 时分秒 %02d-%02d-%02d %02d:%02d:%02d\n",
    now.Year(),now.Month(),now.Day(),
    now.Hour(),now.Minute(),now.Second())
    fmt.Printf("%v %T",dateStr,dateStr)

}

方式二:使用time.Format("2006/01/02 15:04:05")

例:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 格式化日期时间
    now := time.Now()
    // "2006/01/02 15:04:05" 这个字符串的各个数字是固定的,必须是这样写
    // "2006/01/02 15:04:05" 这个字符串各个数字可以自由的组合,这样可以按程序需求来返回时间和日期
    fmt.Println(now.Format("2006/01/02 15:04:05"))
    // 只输出年月日
    fmt.Println(now.Format("2006/01/02"))
    // 只输出时分秒
    fmt.Println(now.Format("15:04:05"))
}

3.时间的常量

const(

Nanosecond Duration = 1 // 纳秒

Microsecond = 1000 * Nanosecond Duration // 微秒

Millisecond = 1000* Microsecond // 毫秒

Second = 1000*Millisecond // 秒

Minute = 60 * Second // 分钟

Hour = 60* Minute // 小时

)

常量的作用:在程序中可用于获取指定时间单位的时间,比如想得到100毫秒 100 * time.Millisecond

休眠:

time.Sleep(1000*time*Millisecond) // 休眠100毫秒

例:

  i := 0
    for {
        i ++
        fmt.Println(i)
        time.Sleep(time.Second)
        if i >= 10 {
            break
        }
    }

4.获取unix时间戳和unixnano时间戳

作用是可以获取随机的数字

从1970年1月1日0时0分0秒 到现在的时间

例子:

package main

import "fmt"
import "time"

func main() {
    now := time.Now()
    // Unix 和 UnixNamo
    fmt.Printf("uinx时间戳=%v \nunixnano时间戳=%v",now.Unix(),now.UnixNano())

}

例:计算程序运行时间

package main

import "fmt"
import "strconv"
import "time"

func test() {
    str := ""
    for i := 0 ; i < 100000; i++ {
        str += "hello" + strconv.Itoa(i)
    }
}

func main() {
    start := time.Now().Unix()
    test()
    end := time.Now().Unix()
    fmt.Printf("执行程序耗费时间为%v秒",end-start)  
}

三.内置函数builtin

Golang设计者为了编程方便,提供了一些函数,这些函数可以直接使用,我们称为GO的内置函数。

文档:https://studygolang.com/pkgdoc -> builtin

1.len

用来求长度,比如:string,array,slice,map,channel

2.new

用来分配内存,主要用来分配值类型,比如int,float32,struct...返回的是指针

举例:

package main

import "fmt"

func main() {
    //
    num1 := 100
    fmt.Printf("num1的类型%T,num1的值=%v,num1的地址%v\n",num1,num1,&num1)

    num2 := new(int)  // num2是指针
    // 指针的值是一个地址
    // num2 的类型%T => *int
    // num2 的值 = 地址 0xc0000540a0
    // num2的地址 = 0xc000080020
    
    // 修改num2 指向的的值
    *num2 = 100
    fmt.Printf("num2的类型%T,num2的值=%v,num2的地址%v 指向的值=%v\n",num2,num2,&num2,*num2)

}

3.make

用来分配内存,主要用来分配引用类型,比如channel、map、slice。

4.错误处理

默认情况下代码逻辑或语法错误,会报错。

如果让报错跳过继续运行就需要使用到错误处理机制。

基本说明:

(1)GO语言追求简洁优雅,所有,GO语言不支持传统的try...catch..finally (java)这种处理

(2)GO中引入的处理方式为:defer,panic,recover

(3)GO中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理。

举例:defer + recover

package main

import "fmt"

func test() {
    // 使用defer + recover 来捕获和处理异常
    defer func() {
        err := recover()  //内置函数recover可以捕获到异常
        if err != nil {  // 说明捕获到异常或错误
            fmt.Println("err=",err)
        }
    }()
    num1 := 10
    num2 := 0
    res := num1 / num2
    fmt.Println("res=",res)
}

func main() {
    // 
    test()
    // 下面的代码正常指向
    fmt.Println("test() 后运行的")
}

错误处理的好处:

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

自定义错误

GO程序中,也支持自定义错误,使用errors.New和panic内置函数。

(1)errors.New(“错误说明”),会返回一个error类型的值,表示一个错误

(2)panic内置函数,接收一个interface{} 类型的值(也就是任何值),作为参数。可以接收error类型的变量,输出错误信息,并退出程序。

举例:自定义错误

package main

import (
    "errors"
    "fmt"
)

// 函数去读取以配置文件init.conf的信息
// 如果文件名传入不正确,我们就返回一个自定义的错误
func readConf(name string) (err error) {
    if name == "config.ini" {
        // 读取
        return nil
    } else {
        // 返回一个自定义错误
        return errors.New("读取文件错误...")
    }
}

func test() {
    err := readConf("config.ini2") // 看传的文件名是否正确,不正确就报错
    if err != nil {
        // 如果读取文件发送错误,就输出这个错误,并终止程序
        panic(err)
    }
    fmt.Println("test继续执行")
}

func main() {
    // 自定义错误的使用
    test()
    fmt.Println("运行main()后面的代码")
}