Go语言学习(常用包)

Go语言中包的本质:文件夹,不同的文件夹可以存放不同的功能代码。

Go语言中的源码复用就是建立在包机制上的

main包

  • main函数所在的包,必须是main包。代表着程序的入口;

  • main包引入其它包,import "fmt";

  • main包是程序的入口,其它包不能使用,尽量使用网址作为包名;

package 包名

src:保存项目的源码路径,所有代码都用包的形式放在src文件夹下

package 声明包在哪里,不需要和文件夹名一样,但尽量使用文件夹的名字

  • 一个目录下的所有的go文件的package必须同名;

  • package可以和文件夹不同名,但不建议;

  • 同一个包下的所有go文件的函数,都可以直接调用;

  • import 导入包的时候,要从src开始

package pojo

// 导入其他包,需要从goworks 下面的src 目录开始导,最标准写法
// import "xuego/lesson10/service"
// 相对路径的导包,十分不建议
// import "../service"
  • 对于外包中的函数,需要使用包名.函数名来使用

package service

import (
   "fmt"

   "xuego/lesson/pojo/user"
)

func userInfo() {
   user.UpdateUserInfo()

   fmt.Println()
}

导包方式:

  • 可以批量导入包

import (
    // 系统
    ""

    // 自己建的包
    ""

    // 网上下载的包
    ""
)
  • 相对路径导入包 ../上一级

import "../xxx" // 不建议这样用
  • 如果包名冲突

import (
    // R "math/rand"  // 可以给包起别名
    // . "math/rand"  // 简便模式:可以直接调用该包下的函数,不需要通过包名
    _ "math/rand" // 匿名导入,只会执行这个包下的init方法
)

init函数(重点)

必须要匿名导入,才会执行这个包下的init函数。

Go语言函数中,除了main函数入口之外,还有一个十分特别的init函数。

init:初始化,在main方法执行之前执行。

init函数可以有多个,在init函数中可以设置一些包,初始化一些全局变量,建立第三方(数据库)连接、注册、检查、修复程序状态等

init函数的执行顺序问题
package main

import (
    "fmt"
    // 匿名导入包,会执行包下所有go文件的init函数,单个init被多个地方导入,只会执行一次
    // 1、先执行导入包的init函数,单个go文件中是顺序执行的,所有go中的init函数执行完毕后,才会到main包
    // 2、如果导入了多个匿名包,按照main中导入包的顺序来执行
    // 3、在同一个包下的go文件如果有多个init的情况下,按照文件排放顺序来执行对应的init函数
    _ "xuego/lesson05/test"  // b.go   -- init()
    _ "xuego/lesson05/test2" // a.go  c.go  -- init()
)

func init() {
    fmt.Println("main--init")
}
func main() {
    // init函数不需要传入参数,也没有返回值,任何地方不能调用 init()
    // init()
}

strings包

strings包:字符串常用操作包。

package stringsdemo

import (
    "fmt"
    "strings"
)

// strings 字符串常用操作包
func Test() {
    // 1、字符是不能修改的
    str := "hello,world"
    fmt.Println(len(str))

    // strings下的常用方法
    // 1、判断某个字符是否包含了指定的内容
    // func Contains(s, substr string) bool
    fmt.Println(strings.Contains(str, "h")) // true

    // 2、判断某个字符串是否包含了多个字符串中的某一个
    fmt.Println(strings.ContainsAny(str, "zd")) // true

    // 3、统计这个字符在指定字符串中出现的数量
    // func Count(s, substr string) int
    fmt.Println(strings.Count(str, "l")) // 3

    fileName := "20230223.mp4"
    // 4、判断字符串以什么开头
    // func HasPrefix(s, prefix string) bool
    if strings.HasPrefix(fileName, "2023") {
        fmt.Println("找到以2023开头的文件:", fileName)
    }
    // 5、判断字符串以什么结尾
    // func HasSuffix(s, suffix string) bool
    if strings.HasSuffix(fileName, ".mp4") {
        fmt.Println("找到以mp4结尾的文件:", fileName)
    }
    // 6、寻找这个字符串第一次出现的位置
    fmt.Println(strings.Index(str, "l")) // 2
    // 7、寻找这个字符串最后一次出现的位置
    fmt.Println(strings.LastIndex(str, "or")) // 7

    // 8、拼接字符串,数组或切片
    // Join(elems []string, sep string) string
    str2 := []string{"a", "b", "c", "d", "e"}
    fmt.Println(strings.Join(str2, ",")) // a,b,c,d,e

    // 9、通过某个格式,拆分字符串(用的最多)
    // Split(s, sep string) []string
    str3 := strings.Join(str2, "-")
    fmt.Println(strings.Split(str3, "-")) // [a b c d e]

    // 大小写
    fmt.Println(strings.ToUpper(str)) // HELLO,WORLD
    fmt.Println(strings.ToLower(str)) // hello,world
    // 替换,n为-1表示修改所有的,n为1表示修改一个,以此类推
    fmt.Println(strings.Replace(str, "l", "的", -1)) // he的的o,wor的d
    // 截取字符串
    str4 := str[0:5]
    fmt.Println(str4) // hello
}
package main

import "xuego/lesson05/stringsdemo"

func main() {
    stringsdemo.Test()
}

strconv

顾名思义:string convert 字符串转换包

在后端接收前端请求时,需要使用字符串转换包进行字符串转换处理。

package main

import (
    "fmt"
    "strconv"
)

// string convert = strconv
func main() {
    s1 := "true"
    // 字符串转化为bool(解析:parse)
    // func ParseBool(str string) (bool, error)
    b1, err := strconv.ParseBool(s1)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("%T, %t\n", b1, b1) // bool, true
    // bool转化为字符串(格式化 format)
    s2 := strconv.FormatBool(b1)
    fmt.Printf("%T, %s\n", s2, s2) // string, true

    // 字符串转化为整数 parse
    s3 := "100"
    // 字符串、进制、大小
    // func ParseInt(s string, base int, bitSize int) (i int64, err error)
    i, _ := strconv.ParseInt(s3, 10, 64)
    fmt.Printf("%T, %d\n", i, i) // int64, 100
    // 整数转化为字符串 format
    s4 := strconv.FormatInt(i, 10)
    fmt.Printf("%T, %s\n", s4, s4) // string, 100

    // 十进制数相互转换字符串的简便方法  atoi itoa
    a, _ := strconv.Atoi("10")
    fmt.Printf("%T, %d\n", a, a) // int, 10
    s := strconv.Itoa(20)
    fmt.Printf("%T, %s\n", s, s) // string, 20
}

time

所有代码都是为了处理生活中出现的业务,其中时间的处理很重要。

  • 获取当前时间

  • 格式化时间

  • 定时

package main

import (
    "fmt"
    "time"
)

// time
func main() {
    // time1()
    // time2()
    // time3()
    // time4()
}

// 获取当前时间 now
func time1() {
    // 返回值为Time结构体
    // func Now() Time
    now := time.Now()
    // 常量信息:年月日时分秒等
    year := now.Year()
    month := now.Month()
    day := now.Day()
    hour := now.Hour()
    minute := now.Minute()
    second := now.Second()
    // 2023-06-28 23:10:52
    // Printf  整数补位操作 02d 如果不足两位,左侧用0补齐
    fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)
}

// 格式化时间
func time2() {
    // 打印当前时间
    now := time.Now()
    // 2023-06-28 23:22:23.6808764 +0800 CST m=+0.023741701
    fmt.Println(now)
    // 格式化时间 格式化模板:yyyy-MM-dd HH:mm:ss
    // Go语言诞生的时间作为格式化模板:2006年1月2号下午3点4分
    // 固定的格式化时间模板:2006-01-02 15:04:05 (助记 6 12345)
    // 24小时制
    fmt.Println(now.Format("2006-01-02 15:04:05")) // 2023-06-28 23:22:23
    // 12小时制
    fmt.Println(now.Format("2006-01-02 03:04:05 PM")) // 2023-06-28 11:22:23 PM
    fmt.Println(now.Format("2006/01/02 15:04"))       // 2023-06-28 11:22:23 PM
    fmt.Println(now.Format("15:04 2006/01/02"))       // 23:22 2023/06/28
    fmt.Println(now.Format("2006/01/02"))             // 2023/06/28
}

// 将字符串转换为时间
func time3() {
    // 获取时区,Asia/Shanghai 首字母必须大写
    loc, err := time.LoadLocation("Asia/Shanghai")
    if err != nil {
        fmt.Println(err)
        return
    }
    // 将字符串解析为时间
    timeStr := "2023-06-28 23:22:23"
    timeObj, _ := time.ParseInLocation("2006-01-02 15:04:05", timeStr, loc)
    // 2023-06-28 23:22:23 +0800 CST
    fmt.Println(timeObj)
    // time.Time
    fmt.Printf("%T\n", timeObj)
}

// 时间戳:更多会与随机数结合
func time4() {
    // 时间戳 Unix 格林威治时间自1970年1月1日(00:00:00 GMT)至当前的总秒数
    // 时间戳永远不会重复的
    now := time.Now()
    timeStamp1 := now.Unix()     // 时间戳
    timeStamp2 := now.UnixNano() // 纳秒时间戳
    fmt.Println(timeStamp1)      // 1687967128
    fmt.Println(timeStamp2)      // 1687967128542682700

    // 通过Unix时间戳转换为Time对象
    timeObj := time.Unix(timeStamp1, 0)
    year := timeObj.Year()
    month := timeObj.Month()
    day := timeObj.Day()
    hour := timeObj.Hour()
    minute := timeObj.Minute()
    second := timeObj.Second()
    // 2023-06-28 23:45:28
    // Printf  整数补位操作 02d 如果不足两位,左侧用0补齐
    fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)
}

随机数

package main

import (
    "fmt"
    "math/rand"
    "time"
)

// random随机数 - math/rand
func main() {
    // 获取一个随机数
    num1 := rand.Int()
    fmt.Println("num1: ", num1) // num1:  5577006791947779410
    // n表示0-n的范围
    num2 := rand.Intn(10)
    fmt.Println("num2: ", num2) // 7

    // 需要一个随时变化的量作为随机数种子 - 时间戳
    // 如果随机数的种子一样,那么随机数一样
    timeStamp := time.Now().Unix()
    // 使用时间戳设置随机数种子
    rand.Seed(timeStamp)
    for i := 0; i < 5; i++ {
        num := rand.Intn(10)
        fmt.Println(num)
    }
}

定时器

时间间隔常量 Duration

time.Duration是time包定义的一个类型,它代表两个时间点经过的时间

以纳秒为单位,可表示的最长时间段大约290年。

time包中定义的时间间隔类型的常量如下:

const (
    Nanosecond  Duration = 1
    Microsecond          = 1000 * Nanosecond
    Millisecond          = 1000 * Microsecond
    Second               = 1000 * Millisecond
    Minute               = 60 * Second
    Hour                 = 60 * Minute
) 
定时器-本身是一个通道chan
func d1() {
    // 定时器,每个1秒都会被触发执行一次
    ticker := time.Tick(time.Second)
    for i := range ticker {
        fmt.Println(i) // 2023-02-26 14:29:40.6272883 +0800 CST m=+1.024658801
    }
}
时间判断
package main

import (
    "fmt"
    "time"
)

func main() {
    // 加  减  比较 (在...之前 在...之后)
    now := time.Now()
    // func (t Time) Add(d Duration) Time
    later := now.Add(time.Hour)
    fmt.Println(later) // 2023-02-26 15:37:03.8765174 +0800 CST m=+3600.008474201

    // 两个时间的差值
    // func (t Time) Sub(u Time) Duration
    subTime := later.Sub(now)
    fmt.Println(subTime) // 1h0m0s

    // 比较时间,可以用在init()方法中用来校验当地时间和网络时间是否一致
    fmt.Println(now.Equal(later))  // false
    fmt.Println(now.Before(later)) // true
    fmt.Println(now.After(later))  // false
}

小案例:

package main

import (
    "syscall"
    "time"
    "unsafe"
)

func main() {
    ticker := time.Tick(time.Second) // 每一秒都会触发。
    for i := range ticker {
        msgBox(i.Format("2006-01-02 15:04:05"))
    }
}
func msgBox(timeStr string) {
    user32 := syscall.NewLazyDLL("user32.dll")
    messageBox := user32.NewProc("MessageBoxW")
    hwnd := 0 // 0表示将弹窗放在桌面的中心位置
    title := "Hello"
    text := timeStr
    flags := 0x00000000 | 0x00000040 // 0x00000000表示弹出消息框并且默认按钮为OK,0x00000040表示消息框的图标为信息图标
    messageBox.Call(uintptr(hwnd), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))), uintptr(flags))
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值