Go 语言基础之常用包【flag、time、strconv、io】(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

相关文章
|
3月前
|
Go 开发者
Go语言包的组织与导入 -《Go语言实战指南》
本章详细介绍了Go语言中的包(Package)概念及其使用方法。包是实现代码模块化、复用性和可维护性的核心单位,内容涵盖包的基本定义、命名规则、组织结构以及导入方式。通过示例说明了如何创建和调用包,并深入讲解了`go.mod`文件对包路径的管理。此外,还提供了多种导入技巧,如别名导入、匿名导入等,帮助开发者优化代码结构与可读性。最后以表格形式总结了关键点,便于快速回顾和应用。
178 61
|
2月前
|
JSON 中间件 Go
Go语言实战指南 —— Go中的反射机制:reflect 包使用
Go语言中的反射机制通过`reflect`包实现,允许程序在运行时动态检查变量类型、获取或设置值、调用方法等。它适用于初中级开发者深入理解Go的动态能力,帮助构建通用工具、中间件和ORM系统等。
222 63
|
1月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
1月前
|
缓存 监控 安全
告别缓存击穿!Go 语言中的防并发神器:singleflight 包深度解析
在高并发场景中,多个请求同时访问同一资源易导致缓存击穿、数据库压力过大。Go 语言提供的 `singleflight` 包可将相同 key 的请求合并,仅执行一次实际操作,其余请求共享结果,有效降低系统负载。本文详解其原理、实现及典型应用场景,并附示例代码,助你掌握高并发优化技巧。
170 0
|
1月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
2月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
2月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
211 0
|
3月前
|
JSON 编解码 API
Go语言网络编程:使用 net/http 构建 RESTful API
本章介绍如何使用 Go 语言的 `net/http` 标准库构建 RESTful API。内容涵盖 RESTful API 的基本概念及规范,包括 GET、POST、PUT 和 DELETE 方法的实现。通过定义用户数据结构和模拟数据库,逐步实现获取用户列表、创建用户、更新用户、删除用户的 HTTP 路由处理函数。同时提供辅助函数用于路径参数解析,并展示如何设置路由器启动服务。最后通过 curl 或 Postman 测试接口功能。章节总结了路由分发、JSON 编解码、方法区分、并发安全管理和路径参数解析等关键点,为更复杂需求推荐第三方框架如 Gin、Echo 和 Chi。
|
4月前
|
分布式计算 Go C++
初探Go语言RPC编程手法
总的来说,Go语言的RPC编程是一种强大的工具,让分布式计算变得简单如同本地计算。如果你还没有试过,不妨挑战一下这个新的编程领域,你可能会发现新的世界。
106 10
|
4月前
|
Go 持续交付 开发者
Go语言包与模块(module)的基本使用-《Go语言实战指南》
本章深入讲解Go语言中的包(Package)和模块(Module)概念。包是代码组织的最小单位,每个`.go`文件属于一个包,通过`import`实现复用;主程序包需命名为`main`。模块是Go 1.11引入的依赖管理机制,支持自动版本管理和私有/远程仓库,无需依赖GOPATH。通过实际示例,如自定义包`mathutil`和第三方模块`gin`的引入,展示其使用方法。常用命令包括`go mod init`、`go mod tidy`等,帮助开发者高效管理项目依赖。最后总结,包负责功能划分,模块实现现代化依赖管理,提升团队协作效率。
216 15