Go 语言基础之常用包【flag、time、strconv、io】(1)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Go 语言基础之常用包【flag、time、strconv、io】

1、命令行参数包 flag

flag 包就是一个用来解析命令行参数的工具。

1.1、os.Args

import (
  "fmt"
  "os"
)
 
func main() {
  if len(os.Args) > 0 {
    for index, arg := range os.Args {
      fmt.Printf("args[%d]=%v\n", index, arg)
    }
  }
}

运行结果:

       osArgs 的本质是一个字符串切片,它的第一个索引 0 存储的是可执行文件的名称,之后的参数才是用户输入的参数。

1.2、flag 包的基本使用

flag 支持的的命令行参数主要有:数值类型、字符串和时间间隔(time.Duration)等。

  • 对于 duration 类型,合法的单位有"ns"、“us” 、“µs”、“ms”、“s”、“m”、“h”。用的时候需要带上单位,比如 1h30m。

1.2.1、命令行参数的定义

       命令行参数的定义有两种方式:一种是不带初始值的(flag.Type),一种是带初始值的(flag.TypeVar)。

flag.Type(flag名, 默认值, 帮助信息)
    name := flag.String("name", "张三", "姓名")
  age := flag.Int("age", 18, "年龄")
  married := flag.Bool("married", false, "婚否")
  delay := flag.Duration("delay", 0, "时间间隔")

通过查看源码我们可以发现,使用这种方式返回的是一个指针,而不是值:

所以在读取的时候需要使用 * 来取出指针的值。

flag.TypeVar(Type指针, flag名, 默认值, 帮助信息)
var name string
var age int
var married bool
var delay time.Duration
flag.StringVar(&name, "name", "张三", "姓名")
flag.IntVar(&age, "age", 18, "年龄")
flag.BoolVar(&married, "married", false, "婚否")
flag.DurationVar(&delay, "d", 0, "时间间隔")

1.2.2、解析命令行参数 flag.Parse()

定义好命令行参数之后,需要显式调用解析命令行参数方法(flag.Parse())才能生效,不然读取不到参数。

flag 支持的命令行参数格式有以下几种:

  • -flag xxx (使用空格,一个-符号)
  • --flag xxx (使用空格,两个-符号)
  • -flag=xxx (使用等号,一个-符号)
  • --flag=xxx (使用等号,两个-符号)

对于布尔类型的参数一般用等号来传递,不然解析不到布尔值之后的参数,并且会把布尔值及其之后的参数当做其它参数。

使用 go run ./flag.go 执行或者 go build 编译 go 文件再执行:

go build ./flag.go

1.2.3、其它参数

       除了我们定义的参数之外,还可以有其它参数,但是必须跟在我们定义的最后一个参数后面,此外 flag 提供了一些方法来获取其它参数的属性:

  //返回命令行参数后的其他参数
  fmt.Println(flag.Args())
  //返回命令行参数后的其他参数个数
  fmt.Println(flag.NArg())
  //返回使用的命令行参数个数
  fmt.Println(flag.NFlag())

1.3、测试

package main
 
import (
  "flag"
  "fmt"
  "time"
)
 
func main() {
  var age int
  var married bool
  var delay time.Duration
  name := flag.String("name", "张三", "姓名")
  flag.IntVar(&age, "age", 18, "年龄")
  flag.BoolVar(&married, "married", false, "婚否")
  flag.DurationVar(&delay, "delay", 0, "延迟的时间间隔")
 
  //解析命令行参数
  flag.Parse()
  
  fmt.Println(*name, age, married, delay)
  
  //返回命令行参数后的其他参数
  fmt.Println(flag.Args())
  //返回命令行参数后的其他参数个数
  fmt.Println(flag.NArg())
  //返回使用的命令行参数个数
  fmt.Println(flag.NFlag())
}

测试1(自定义参数 + 其它参数):

测试2(全为其它参数):

2、时间包 time

Go 语言中使用time.Time类型表示时间。我们可以通过time.Now函数获取当前的时间对象,然后从时间对象中可以获取到年、月、日、时、分、秒等信息。

func main() {
  now := time.Now()
  // 2024-05-06 19:44:56.6410767 +0800 CST m=+0.004404001
  fmt.Println(now)
  // 现在是2024年5月6日19时46分38秒
  fmt.Printf("现在是%d年%d月%d日%d时%d分%d秒", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
}

2.1、Location和time zone

这个还是比较实用的,因为 time.LoadLocation 依赖系统的时区数据库,在不太确定程序运行环境的情况下建议先自定义时区偏移量(比如北京时间就是东八区时间,需要在UTC基础上+8个小时)然后使用time.FixedZone的方式指定时区。

    // 时差(单位:s)
  diffSeconds := int((8 * time.Hour).Seconds()) // float 转 int
  // 北京时间
  beijing := time.FixedZone("Beijing Time", diffSeconds) // 返回 *Location

2.2、Unix Time

       Unix Time是自1970年1月1日 00:00:00 UTC 至当前时间经过的总秒数,我们可以通过 time 提供的方法获得当前的 Unix 秒/毫秒数(微秒、纳秒用不上):

func main() {
  now := time.Now()
    // 都是返回 int64 类型的整数
  timestamp := now.Unix()
  millisecond := now.UnixMilli() 
  // 1714996867s,1714996867336ms
  fmt.Printf("%ds,%dms", timestamp, millisecond) 
}

我们也可以把秒/毫秒数(int64)转为时间:

func main() {
  now := time.Now()
    // 都是返回 int64 类型的整数
  second := now.Unix()
    // 第2个参数为不足1秒的纳秒数
  timeValue := time.Unix(int64(second), 22)
  fmt.Println(timeValue) // 2024-05-06 20:01:07.000000022 +0800 CST
}

2.3、时间间隔

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

const (
    Nanosecond  Duration = 1
    Microsecond          = 1000 * Nanosecond
    Millisecond          = 1000 * Microsecond
    Second               = 1000 * Millisecond
    Minute               = 60 * Second
    Hour                 = 60 * Minute
)

用的时候直接用常量 * 单位即可,下面是 time.Duration 常用的一些方法:

 
func main() {
  now := time.Now()
  // 这里 Add 方法的参数为 time.Duration 类型
  later := now.Add(3 * time.Hour)
  // 三个小时以后是: 2024-05-06 23:07:28.3043137 +0800 CST m=+10800.004676401
  fmt.Println("三个小时以后是: ", later)
  // Sub 方法的返回值为 time.Duration 类型
  fmt.Println(now.Sub(later)) // -3h0m0s
  // now 是否在 later 之前
  fmt.Println(now.Before(later)) // true
  // now 是否在 later 之后
  fmt.Println(now.After(later)) // false
 
  // 加载东京所在的时区
  tokyo, _ := time.LoadLocation("Asia/Tokyo")
  // 加载上海所在的时区
  shanghai, _ := time.LoadLocation("Asia/Shanghai")
  tk := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond(), tokyo)
  sh := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond(), shanghai)
  // 判断两个时间是否相同,会考虑时区的影响
  fmt.Println(now.Equal(tk)) // false
  fmt.Println(now.Equal(sh)) // true
}

2.4、时间格式化

注意:Go 语言诞生于2006 年 1 月 2 日下午15 点 4 分 5 秒,它的时间格式化模板用的也正是这个时间!

func main() {
  now := time.Now()
  // 格式化模板:2006-01-02 15:04:05.000
  fmt.Println(now.Format("2006-01-02 15:04:05")) // 2024-05-06 20:24:57
}

2.5、解析时间字符串

func main() {
  now := time.Now()
  // 格式化模板:2006-01-02 15:04:05.000
  // 两个参数的长度必须对应上
  t1, _ := time.Parse("2006-01-02 15:04:05", now.String()[0:19])
  fmt.Println(t1) // 2024-05-06 20:34:59 +0000 UTC
}

在解析时,可额外指定时区信息:

func main() {
  now := time.Now()
  sh, _ := time.LoadLocation("Asia/Shanghai")
  // 格式化模板:2006-01-02 15:04:05.000
  // 按照指定时区和指定格式解析字符串时间
  t1, _ := time.ParseInLocation("2006-01-02 15:04:05", now.String()[0:19], sh)
  fmt.Println(t1) // 2024-05-06 20:40:24 +0800 CST
}

Go 语言基础之常用包【flag、time、strconv、io】(2)https://developer.aliyun.com/article/1534277

相关文章
|
2天前
|
存储 Go 索引
go语言使用for循环遍历
go语言使用for循环遍历
16 7
|
5天前
|
存储 Go
go语言 遍历映射(map)
go语言 遍历映射(map)
18 2
|
6天前
|
Go 调度 开发者
Go语言中的并发编程:深入理解goroutines和channels####
本文旨在探讨Go语言中并发编程的核心概念——goroutines和channels。通过分析它们的工作原理、使用场景以及最佳实践,帮助开发者更好地理解和运用这两种强大的工具来构建高效、可扩展的应用程序。文章还将涵盖一些常见的陷阱和解决方案,以确保在实际应用中能够避免潜在的问题。 ####
|
6天前
|
测试技术 Go 索引
go语言使用 range 关键字遍历
go语言使用 range 关键字遍历
14 3
|
6天前
|
测试技术 Go 索引
go语言通过 for 循环遍历
go语言通过 for 循环遍历
16 3
|
8天前
|
安全 Go 数据处理
Go语言中的并发编程:掌握goroutine和channel的艺术####
本文深入探讨了Go语言在并发编程领域的核心概念——goroutine与channel。不同于传统的单线程执行模式,Go通过轻量级的goroutine实现了高效的并发处理,而channel作为goroutines之间通信的桥梁,确保了数据传递的安全性与高效性。文章首先简述了goroutine的基本特性及其创建方法,随后详细解析了channel的类型、操作以及它们如何协同工作以构建健壮的并发应用。此外,还介绍了select语句在多路复用中的应用,以及如何利用WaitGroup等待一组goroutine完成。最后,通过一个实际案例展示了如何在Go中设计并实现一个简单的并发程序,旨在帮助读者理解并掌
|
7天前
|
Go 索引
go语言按字符(Rune)遍历
go语言按字符(Rune)遍历
21 3
|
11天前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
35 4
|
11天前
|
缓存 监控 前端开发
Go 语言中如何集成 WebSocket 与 Socket.IO,实现高效、灵活的实时通信
本文探讨了在 Go 语言中如何集成 WebSocket 与 Socket.IO,实现高效、灵活的实时通信。首先介绍了 WebSocket 和 Socket.IO 的基本概念及其优势,接着详细讲解了 Go 语言中 WebSocket 的实现方法,以及二者集成的重要意义和具体步骤。文章还讨论了集成过程中需要注意的问题,如协议兼容性、消息格式、并发处理等,并提供了实时聊天、数据监控和在线协作工具等应用案例,最后提出了性能优化策略,包括数据压缩、缓存策略和连接管理优化。旨在帮助开发者更好地理解并应用这些技术。
25 3
|
11天前
|
缓存 监控 前端开发
在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统
本文深入探讨了在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统。
45 1