go语言标准库学习, fmt标准输出,Time 时间,Flag,Log日志,Strconv

向外输出

fmt包实现了类似C语言printf和scanf的格式化I/O。主要分为向外输出内容和获取输入内容两大部分。

内置输出

不需要引入标准库,方便

c 复制代码
package main

func main() {
	print("我是控制台打印,我不换行 可以自己控制换行 \n我是另一行")
	println("Hello World")

}

fmt标准输出

Print

Print系列函数会将内容输出到系统的标准输出,

区别在于Print函数直接输出内容,

Printf函数支持格式化输出字符串,

Println函数会在输出内容的结尾添加一个换行符。

go 复制代码
package main

import "fmt"

type User struct {
	Name string
	Age  int
}

fmt.Print("在终端打印该信息。")
name := "枯藤"
fmt.Printf("我是:%s\n", name)
user := User{"张三", 20}
fmt.Printf("我是一个字符串 %v", user)
fmt.Printf("我是一个字符串 %+v", user)
fmt.Println("在终端打印单独一行显示")

Fprint

Fprint系列函数会将内容输出到一个io.Writer接口类型的变量w中,我们通常用这个函数往文件中写入内容。

go 复制代码
// 默认输出到控制台
	fmt.Fprintf(os.Stdout, "hello world \n")

	// 输出到标准错误
	fmt.Fprintf(os.Stderr, "这是错误信息 \n")

	//文件输出
	file, _ := os.Create("output.txt")
	fmt.Fprintf(file, "写入文件的内容111") // 输出到文件
	file.Close()

	// 输出到内存缓冲区
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "写入缓冲的内容")

	// 输出到网络连接
	conn, _ := net.Dial("tcp", "example.com:80")
	fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")

	//Fprintf简写,默认输出到控制台
	fmt.Print("我是文本内容")

Sprint

Sprint系列函数会把传入的数据生成并返回一个字符串。

该放大的接口定义

go 复制代码
func Sprint(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string
func Sprintln(a ...interface{}) string
go 复制代码
s1 := fmt.Sprint("三体即将到来")
name := "三体"
age := 18
s2 := fmt.Sprintf("name:%s,age:%d", name, age)
s3 := fmt.Sprintln("三体")
fmt.Println(s1, s2, s3)

Errorf

Errorf函数根据format参数生成格式化字符串并返回一个包含该字符串的错误。

go 复制代码
func Errorf(format string, a ...interface{}) error

通常使用这种方式来自定义错误类型,例如:

go 复制代码
	err := fmt.Errorf("这是一个错误")
	fmt.Println(err)
打印:
这是一个错误

格式化占位符

go 复制代码
	fmt.Printf("%v\n", 100)
	fmt.Printf("%v\n", false)
	o := struct {
		name string
		age  int
	}{"枯藤", 18}
	fmt.Printf("%v\n", o)
	fmt.Printf("%+v\n", o)
	fmt.Printf("%#v\n", o)
	fmt.Printf("%T\n", o)
	fmt.Printf("100%%\n")
go 复制代码
isFlag := false
n := 65
fmt.Printf("%b\n", n)
fmt.Printf("%c\n", n)
fmt.Printf("%d\n", n)
fmt.Printf("%o\n", n)
fmt.Printf("%x\n", n)
fmt.Printf("%X\n", n)




go 复制代码
func main() {
	s := "枯藤"
	fmt.Printf("%s\n", s)
	fmt.Printf("%q\n", s)
	fmt.Printf("%x\n", s)
	fmt.Printf("%X\n", s)
}
go 复制代码
a := 18
fmt.Printf("%p\n", &a)
fmt.Printf("%#p\n", &a)
go 复制代码
	n := 88.99
	fmt.Printf("%f\n", n)
	fmt.Printf("%10f\n", n)
	fmt.Printf("%.2f\n", n)
	fmt.Printf("%10.2f\n", n)
	fmt.Printf("%10.f\n", n)

获取输入

Go语言fmt包下有f

mt.Scan、

fmt.Scanf、

fmt.Scanln

三个函数,可以在程序运行过程中从标准输入获取用户的输入。

go 复制代码
func main() {
	var (
		name    string
		age     int
		married bool
	)
	fmt.Scan(&name, &age, &married)
	fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}

Time 时间

时间和日期是我们编程中经常会用到的,本文主要介绍了Go语言内置的time包的基本用法。

时间类型

go 复制代码
    now := time.Now() //获取当前时间
	fmt.Printf("current time:%v\n", now)
	year := now.Year()     //年
	month := now.Month()   //月
	day := now.Day()       //日
	hour := now.Hour()     //小时
	minute := now.Minute() //分钟
	second := now.Second() //秒
	fmt.Printf("年:%d\n", year)
	fmt.Printf("月:%d\n", month)
	fmt.Printf("日:%d\n", day)
	fmt.Printf("时:%d\n", hour)
	fmt.Printf("分:%d\n", minute)
	fmt.Printf("秒:%d\n", second)
	fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)

时间戳

时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数。它也被称为Unix时间戳(UnixTimestamp)。

在Go语言中,时间戳的单位关系如下:

标准时间戳(Unix时间戳)是以秒为单位的整数

1秒 = 1000毫秒

1秒 = 1,000,000,000纳秒(10亿纳秒)

go 复制代码
	now := time.Now()        //获取当前时间
	timestamp1 := now.Unix() //时间戳
	timestamp2 := now.UnixMilli()
	timestamp3 := now.UnixMicro()
	timestamp4 := now.UnixNano() //纳秒时间戳
	fmt.Printf("   时间戳:%v\n", timestamp1)
	fmt.Printf("毫秒时间戳:%v\n", timestamp2)
	fmt.Printf("微秒时间戳:%v\n", timestamp3)
	fmt.Printf("纳秒时间戳:%v\n", timestamp4)

时间操作

Add求时间间隔

我们在日常的编码过程中可能会遇到要求时间+时间间隔的需求,Go语言的时间对象有提供Add方法如下:

go 复制代码
now := time.Now()
	fmt.Println(now)
	//later := now.Add(time.Hour) // 当前时间加1小时后的时间

	//一秒后
	second := now.Add(time.Second)

	//一分钟后
	minute := now.Add(time.Minute)

	//一小时后
	hour := now.Add(time.Hour)

	//一天后
	day := now.Add(24 * time.Hour)

	//一周后
	week := now.Add(7 * 24 * time.Hour)
	//一个月后
	month := now.Add(30 * 24 * time.Hour)
	//一年后
	year := now.Add(365 * 24 * time.Hour)

	//一秒钟前
	preSecond := now.Add(-time.Second)
	//一分钟前
	preMinute := now.Add(-time.Minute)
	//一小时前
	preHour := now.Add(-time.Hour)
	//一天前
	preDay := now.Add(-24 * time.Hour)
	//一周前
	preWeek := now.Add(-7 * 24 * time.Hour)
	//一个月前
	preMonth := now.Add(-30 * 24 * time.Hour)
	//一年前
	preYear := now.Add(-365 * 24 * time.Hour)

	fmt.Printf("一秒后 %v\n", second)
	fmt.Printf("一分钟后 %v\n", minute)
	fmt.Printf("一小时后 %v\n", hour)
	fmt.Printf("一天后 %v\n", day)
	fmt.Printf("一周后 %v\n", week)
	fmt.Printf("一个月后 %v\n", month)
	fmt.Printf("一年后 %v\n", year)
	fmt.Println("=======================")

	fmt.Printf("一秒钟前 %v\n", preSecond)
	fmt.Printf("一分钟前 %v\n", preMinute)
	fmt.Printf("一小时前 %v\n", preHour)
	fmt.Printf("一天前 %v\n", preDay)
	fmt.Printf("一周前 %v\n", preWeek)
	fmt.Printf("一个月前 %v\n", preMonth)
	fmt.Printf("一年前 %v\n", preYear)

Sub 求两个时间之间的差值

go 复制代码
	now := time.Now()
	fmt.Println("开始时间:", now)

	// 正确用法:需要一个另一个时间对象来调用Sub
	later := time.Now()
	fmt.Println("时间差:", later.Sub(now).Seconds(), "s")
	fmt.Println("毫秒差:", later.Sub(now).Milliseconds(), "ms")
	fmt.Println("微秒差:", later.Sub(now).Microseconds(), "us")
	fmt.Println("纳秒差:", later.Sub(now).Nanoseconds(), "ns")

	fmt.Println("结束时间:", later)
go 复制代码
开始时间: 2025-08-06 16:10:08.6476536 +0800 CST m=+0.002114101
时间差: 0.0113969 s
毫秒差: 11 ms
微秒差: 11396 us
纳秒差: 11396900 ns
结束时间: 2025-08-06 16:10:08.6590505 +0800 CST m=+0.013511001

Equal 两个时间是否相等

go 复制代码
	now := time.Now()
	fmt.Println("开始时间:", now)

	//Equal 两个时间是否相等
	now1 := time.Now()
	now2 := time.Now()
	fmt.Println("now1 == now2:", now1.Equal(now2))
	//Add 增加时间
	now3 := now.Add(time.Second)
	fmt.Println("now1 == now3:", now1.Equal(now3))
	fmt.Println(now3)

Before

如果t代表的时间点在u之前,返回真;否则返回假。

go 复制代码
    func (t Time) Before(u Time) bool
go 复制代码
func main() {
	now := time.Now()
	future := now.Add(5 * time.Second) // 当前时间加5秒
	past := now.Add(-5 * time.Second)  // 当前时间减5秒

	// 比较时间先后
	fmt.Println("now在future之前?", now.Before(future)) // true
	fmt.Println("now在past之前?", now.Before(past))     // false
	fmt.Println("future在now之前?", future.Before(now)) // false
}
go 复制代码
now在future之前? true
now在past之前? false
future在now之前? false

注意事项

  1. 比较时会考虑时区信息
  2. 对于相同的时间点,Before() 会返回 false
  3. 通常与 After() 和 Equal() 方法配合使用
  4. 你的原始代码中 now.Before(now.Add(1 * time.Second)) 总是返回 true,因为 now.Add(1 * time.Second) 确实是比 now 晚1秒的时间。

After

与Before相反 如果t代表的时间点在u之后,返回真;否则返回假。

go 复制代码
 func (t Time) After(u Time) bool
go 复制代码
now := time.Now()
future := now.Add(5 * time.Second) // 当前时间加5秒
past := now.Add(-5 * time.Second)  // 当前时间减5秒

// 比较时间先后
fmt.Println("now在future之后?", now.After(future)) // false
fmt.Println("now在past之后?", now.After(past))     // true
fmt.Println("future在now之后?", future.After(now)) // true
go 复制代码
now在future之后? false
now在past之后? true
future在now之后? true

实际场景的应用

  1. 检查任务是否超时
go 复制代码
	deadline := time.Now().Add(2 * time.Second)
	time.Sleep(3 * time.Second)
	// ... 执行一些耗时操作 ...
	if time.Now().After(deadline) {
		fmt.Println("任务已超时")
		return
	}
	fmt.Println("任务已完成")
go 复制代码
任务已超时
  1. 验证证书有效期
go 复制代码
expiryDate := time.Date(2023, 12, 31, 0, 0, 0, 0, time.UTC)
if time.Now().After(expiryDate) {
    fmt.Println("证书已过期")
} else {
    fmt.Println("证书仍在有效期内")
}
go 复制代码
证书已过期
  1. 定时器检查
go 复制代码
在这里插入代码片
go 复制代码
func main() {
	lastCheck := time.Now()
	nextCheck := lastCheck.Add(3 * time.Second)
	time.Sleep(4 * time.Second)
	if time.Now().After(nextCheck) {
		fmt.Println("需要执行定期检查了")
		// 执行检查逻辑...
	}
}
go 复制代码
需要执行定期检查了
  1. 与Before配合使用
go 复制代码
	startTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
	endTime := time.Date(2025, 9, 2, 0, 0, 0, 0, time.UTC)

	current := time.Now()
	if current.After(startTime) && current.Before(endTime) {
		fmt.Println("当前在时间范围内")
	}
go 复制代码
当前在时间范围内

定时器

使用time.Tick(时间间隔)来设置定时器,定时器的本质上是一个通道(channel)。

go 复制代码
ticker := time.Tick(time.Second) //定义一个1秒间隔的定时器
	for i := range ticker {
		fmt.Println(i) //每秒都会执行的任务
	}
go 复制代码
2025-08-06 16:36:18.7846155 +0800 CST m=+1.001458901
2025-08-06 16:36:19.7977679 +0800 CST m=+2.014611301
2025-08-06 16:36:20.7935061 +0800 CST m=+3.010349501
2025-08-06 16:36:21.7993051 +0800 CST m=+4.016148501
2025-08-06 16:36:22.7938337 +0800 CST m=+5.010677101
2025-08-06 16:36:23.7972015 +0800 CST m=+6.014044901
2025-08-06 16:36:24.7889924 +0800 CST m=+7.005835801

时间格式化

  1. 时间类型有一个自带的方法Format进行格式化
  2. Go的诞生时间2006年1月2号15点04分(记忆口诀为2006 1 2 3 4)
go 复制代码
	now := time.Now()
	// 格式化的模板为Go的出生时间2006年1月2号15点04分 Mon Jan
	// 24小时制
	fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
	// 12小时制
	fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
	fmt.Println(now.Format("2006/01/02 15:04"))
	fmt.Println(now.Format("15:04 2006/01/02"))
	fmt.Println(now.Format("2006/01/02"))
go 复制代码
2025-08-06 16:39:19.865 Wed Aug
2025-08-06 04:39:19.865 PM Wed Aug
2025/08/06 16:39
16:39 2025/08/06
2025/08/06

解析字符串格式的时间

go 复制代码
now := time.Now()
fmt.Println(now)
// 加载时区
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
    fmt.Println(err)
    return
}
// 按照指定时区和指定格式解析字符串时间
timeObj, err := time.ParseInLocation("2006/01/02 15:04:05", "2019/08/04 14:15:20", loc)
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println(timeObj)
fmt.Println(timeObj.Sub(now))
go 复制代码
2025-08-06 16:42:04.4364547 +0800 CST m=+0.001074101
2019-08-04 14:15:20 +0800 CST
-52658h26m44.4364547s

Flag命令行

Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单。

flag包基本使用

导入包

go 复制代码
import flag

flag参数类型

实例1
go 复制代码
	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, "时间间隔")

	// 添加这行代码来解析命令行参数
	flag.Parse()

	// 打印解析后的参数值
	fmt.Printf("姓名: %s\n年龄: %d\n婚否: %t\n时间间隔: %v\n", name, age, married, delay)
go 复制代码
PS E:\work\code\go\demo> go run main.go -name 李四 -age 25 -married=true -d 1h30m
姓名: 李四
年龄: 25
婚否: true
时间间隔: 1h30m0s

PS E:\work\code\go\demo> go run main.go                                          
姓名: 张三
年龄: 18
婚否: false
时间间隔: 0s
实例2
go 复制代码
package main

import (
	"flag"
	"fmt"
	"time"
)

type User struct {
	Name string
	Age  int
}

func main() {
	//定义命令行参数方式1
	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, "延迟的时间间隔")

	//解析命令行参数
	flag.Parse()
	fmt.Println(name, age, married, delay)
	//返回命令行参数后的其他参数 []数组,如果你写了没有定义的参数,就会出现这里
	fmt.Println(flag.Args()) 
	//返回命令行参数后的其他参数个数,如果你写了没有定义的参数,就会统计个数在这里
	fmt.Println(flag.NArg())
	//返回使用的命令行参数个数
	fmt.Println(flag.NFlag())
}

命令1,借助help来查看该命令需要什么参数

go 复制代码
 go run main.go  --help 

命令2,使用默认参数

go 复制代码
go run main.go

命令2,填写所需要的参数

错误写法

go 复制代码
 go run main.go -age 800 -d 22m  -married true  -name 李白
复制代码
**返回命令行参数后的其他参数 []数组,如果你写了没有定义的参数,就会出现这里**
fmt.Println(flag.Args()) 
**返回命令行参数后的其他参数个数,如果你写了没有定义的参数,就会统计个数在这里**
fmt.Println(flag.NArg())

问题原因

  1. 当你使用 -married true 时:

    flag包期望布尔标志后面不跟参数值

    true被当作一个独立参数处理

    -name和"李白"也被当作独立参数

  2. 当前解析结果:

    -age、-d 被正确解析

    -married 被解析为true,但后面的true被当作额外参数

    -name 李白 整个被当作额外参数,没有被正确解析

-married后面不能跟true ,如果想填写李白已婚则

go 复制代码
 go run main.go -age 800 -d 22m  -married  -name 李白

李白未婚则 直接取掉-married

go 复制代码
 go run main.go -age 800 -d 22m    -name 李白

OS

更详细的OS 请看链接
添加链接描述

  1. Getwd 获取当前工作目录
c 复制代码
package main

import (
	"os"
)

func main() {
	dir, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	println(dir)

}
c 复制代码
E:\work\code\go\demo
  1. 创建文件
c 复制代码
package main

import "os"

func main() {
	// 创建文件
	create, err := os.Create("readme.md")
	if err != nil {
		panic(err)
	}
	defer create.Close()
}

底层源码,其实是调用了一个OpenFile方法,并且默认的权限是0666

Log日志

常规使用

Go语言内置的log包实现了简单的日志服务。本文介绍了标准库log的基本使用。

log包定义了Logger类型,该类型提供了一些格式化输出的方法。

本包也提供了一个预定义的"标准"logger,

可以通过调用函数
Print系列(Print|Printf|Println)、 Fatal系列(Fatal|Fatalf|Fatalln)、 Panic系列(Panic|Panicf|Panicln)

来使用,比自行创建一个logger对象更容易使用。

使用Logger

go 复制代码
	log.Println("这是一条很普通的日志。")
	v := "很普通的"
	log.Printf("这是一条%s日志。\n", v)
	log.Fatalln("这是一条会触发fatal的日志。")
	log.Panicln("这是一条会触发panic的日志。")

配置logger

1 flag选项

go 复制代码
const (
    // 控制输出日志信息的细节,不能控制输出的顺序和格式。
    // 输出的日志在每一项后会有一个冒号分隔:例如2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
    Ldate         = 1 << iota     // 日期:2009/01/23
    Ltime                         // 时间:01:23:23
    Lmicroseconds                 // 微秒级别的时间:01:23:23.123123(用于增强Ltime位)
    Llongfile                     // 文件全路径名+行号: /a/b/c/d.go:23
    Lshortfile                    // 文件名+行号:d.go:23(会覆盖掉Llongfile)
    LUTC                          // 使用UTC时间
    LstdFlags     = Ldate | Ltime // 标准logger的初始值
)

使用

go 复制代码
log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
log.Println("这是一条很普通的日志。")

配置日志前缀

go 复制代码
 	log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
    log.Println("这是一条很普通的日志。")
    log.SetPrefix("[pprof]")
    log.Println("这是一条很普通的日志。")

配置日志输出位置

go 复制代码
 logFile, err := os.OpenFile("./xx.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
    if err != nil {
        fmt.Println("open log file failed, err:", err)
        return
    }
    log.SetOutput(logFile)
    log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
    log.Println("这是一条很普通的日志。")
    log.SetPrefix("[小王子]")
    log.Println("这是一条很普通的日志。")

自定义日志

log标准库中还提供了一个创建新logger对象的构造函数--New,支持我们创建自己的logger示例。New函数的签名如下:

func New(out io.Writer, prefix string, flag int) *Logger

New创建一个Logger对象。其中,参数out设置日志信息写入的目的地。参数prefix会添加到生成的每一条日志前面。参数flag定义日志的属性(时间、文件等等)。

举个例子:

go 复制代码
func main() {
    logger := log.New(os.Stdout, "<New>", log.Lshortfile|log.Ldate|log.Ltime)
    logger.Println("这是自定义的logger记录的日志。")
}

将上面的代码编译执行之后,得到结果如下:

go 复制代码
<New>2025/08/06 17:43:45 main.go:15: 这是自定义的logger记录的日志。

总结 : Go内置的log库功能有限,例如无法满足记录不同级别日志的情况,我们在实际的项目中根据自己的需要选择使用第三方的日志库,如logrus、zap等。

Strconv

strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数:

Atoi()、

Itia()、

parse系列、

format系列、

append系列、

Atoi() string转int类型

go 复制代码
func main() {
	atoi, err := strconv.Atoi("ddd")
	if err != nil {
		if numErr, ok := err.(*strconv.NumError); ok {
			fmt.Printf("解析错误: 输入值 '%s' 不是有效的整数\n", numErr.Num)
			fmt.Printf("错误类型: %v\n", numErr.Err)
		} else {
			fmt.Printf("未知错误: %v\n", err)
		}
	} else {
		fmt.Println("解析结果:", atoi)
	}
}
go 复制代码
func main() {
	atoi, err := strconv.Atoi("1000")
	if err != nil {
		if numErr, ok := err.(*strconv.NumError); ok {
			fmt.Printf("解析错误: 输入值 '%s' 不是有效的整数\n", numErr.Num)
			fmt.Printf("错误类型: %v\n", numErr.Err)
		} else {
			fmt.Printf("未知错误: %v\n", err)
		}
	} else {
		fmt.Println("解析结果:", atoi)
	}
}

Itoa() 将int类型转(string)字符串

go 复制代码
i2 := 200
s2 := strconv.Itoa(i2)
fmt.Printf("type:%T value:%#v\n", s2, s2)
//type:string value:"200"

字符串转其他类型

strconv.ParseInt 详细解析

go 复制代码
func main() {
	// ... 您现有的代码保持不变 ...

	// 示例1: 十进制解析
	num1, err := strconv.ParseInt("42", 10, 64)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("十进制42解析结果:", num1)
	}

	// 示例2: 二进制解析
	num2, err := strconv.ParseInt("1010", 2, 64)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("二进制1010解析结果:", num2) // 输出10
	}

	// 示例3: 十六进制解析
	num3, err := strconv.ParseInt("FF", 16, 64)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("十六进制FF解析结果:", num3) // 输出255
	}

	// 示例4: 自动判断进制
	num4, err := strconv.ParseInt("0xFF", 0, 64)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("0xFF自动判断进制解析结果:", num4) // 输出255
	}

	// 示例5: 错误处理
	_, err = strconv.ParseInt("12x3", 10, 64)
	if err != nil {
		if numErr, ok := err.(*strconv.NumError); ok {
			fmt.Printf("解析错误: 输入值 '%s' 不是有效的整数\n", numErr.Num)
			fmt.Printf("错误类型: %v\n", numErr.Err)
		}
	}
}

strconv.ParseBool

返回字符串表示的bool值。它接受1、0、t、f、T、F、true、false、True、False、TRUE、FALSE;否则返回错误。

go 复制代码
func main() {

	// 示例1: 真值(true)的各种表示形式
	trueValues := []string{"1", "t", "T", "true", "TRUE", "True"}
	for _, val := range trueValues {
		b, err := strconv.ParseBool(val)
		if err != nil {
			fmt.Printf("'%s' 解析错误: %v\n", val, err)
		} else {
			fmt.Printf("'%s' → %t\n", val, b)
		}
	}

	// 示例2: 假值(false)的各种表示形式
	falseValues := []string{"0", "f", "F", "false", "FALSE", "False"}
	for _, val := range falseValues {
		b, err := strconv.ParseBool(val)
		if err != nil {
			fmt.Printf("'%s' 解析错误: %v\n", val, err)
		} else {
			fmt.Printf("'%s' → %t\n", val, b)
		}
	}

	// 示例3: 无效输入
	invalidValues := []string{"2", "yes", "no", "ture", "abc"}
	for _, val := range invalidValues {
		_, err := strconv.ParseBool(val)
		if err != nil {
			fmt.Printf("'%s' 是无效的布尔值: %v\n", val, err)
		}
	}
}
go 复制代码
'1' → true
't' → true
'T' → true
'true' → true
'TRUE' → true
'True' → true
'0' → false
'f' → false
'F' → false
'false' → false
'FALSE' → false
'False' → false
'2' 是无效的布尔值: strconv.ParseBool: parsing "2": invalid syntax
'yes' 是无效的布尔值: strconv.ParseBool: parsing "yes": invalid syntax
'no' 是无效的布尔值: strconv.ParseBool: parsing "no": invalid syntax
'ture' 是无效的布尔值: strconv.ParseBool: parsing "ture": invalid syntax
'abc' 是无效的布尔值: strconv.ParseBool: parsing "abc": invalid syntax

ParseUnit()

ParseUint类似ParseInt但不接受正负号,用于无符号整型。

go 复制代码
func main() {
	// 示例1: 十进制无符号整数解析
	num1, err := strconv.ParseUint("123", 10, 64)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("十进制123解析结果:", num1)
	}

	// 示例2: 十六进制无符号整数解析
	num2, err := strconv.ParseUint("FF", 16, 64)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("十六进制FF解析结果:", num2) // 输出255
	}

	// 示例3: 二进制无符号整数解析
	num3, err := strconv.ParseUint("1010", 2, 64)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("二进制1010解析结果:", num3) // 输出10
	}

	// 示例4: 自动判断进制
	num4, err := strconv.ParseUint("0xFF", 0, 64)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("0xFF自动判断进制解析结果:", num4) // 输出255
	}

	// 示例5: 错误处理 - 负数会报错
	_, err = strconv.ParseUint("-123", 10, 64)
	if err != nil {
		fmt.Println("负数解析错误:", err) // 输出: strconv.ParseUint: parsing "-123": invalid syntax
	}

	// 示例6: 超出范围错误
	_, err = strconv.ParseUint("99999999999999999999", 10, 32)
	if err != nil {
		fmt.Println("超出范围错误:", err) // 输出: strconv.ParseUint: parsing "99999999999999999999": value out of range
	}
}
go 复制代码
十进制123解析结果: 123
十六进制FF解析结果: 255
二进制1010解析结果: 10
0xFF自动判断进制解析结果: 255
负数解析错误: strconv.ParseUint: parsing "-123": invalid syntax
超出范围错误: strconv.ParseUint: parsing "99999999999999999999": value out of range

ParseFloat()

如果s合乎语法规则,函数会返回最为接近s表示值的一个浮点数(使用IEEE754规范舍入)。

bitSize指定了期望的接收类型,32是float32(返回值可以不改变精确值的赋值给float32),64是float64;

返回值err是*NumErr类型的,语法有误的,err.Error=ErrSyntax;结果超出表示范围的,返回值f为±Inf,err.Error= ErrRange。

go 复制代码
func main() {

	// 示例1: 基本浮点数解析
	f1, err := strconv.ParseFloat("3.1415926", 64)
	if err != nil {
		fmt.Println("解析错误:", err.Error())
	} else {
		fmt.Println("浮点数3.1415926解析结果:", f1)
	}

	// 示例2: 科学计数法解析
	f2, err := strconv.ParseFloat("1.23e5", 64)
	if err != nil {
		fmt.Println("解析错误:", err.Error())
	} else {
		fmt.Println("科学计数法1.23e5解析结果:", f2) // 输出123000
	}

	// 示例3: 负浮点数解析
	f3, err := strconv.ParseFloat("-123.456", 64)
	if err != nil {
		fmt.Println("解析错误:", err.Error())
	} else {
		fmt.Println("负浮点数-123.456解析结果:", f3)
	}

	// 示例4: 32位浮点数解析
	f4, err := strconv.ParseFloat("0.123456789", 32)
	if err != nil {
		fmt.Println("解析错误:", err.Error())
	} else {
		fmt.Println("32位浮点数0.123456789解析结果:", f4) // 注意精度损失
	}

	// 示例5: 错误处理 - 无效格式
	_, err = strconv.ParseFloat("12x.34", 64)
	if err != nil {
		fmt.Println("无效格式错误:", err.Error()) // 输出: strconv.ParseFloat: parsing "12x.34": invalid syntax
	}

	// 示例6: 错误处理 - 超出范围
	_, err = strconv.ParseFloat("1e309", 64)
	if err != nil {
		fmt.Println("超出范围错误:", err) // 输出: strconv.ParseFloat: parsing "1e309": value out of range
	}

}

Format 其他类型转字符串

FormatBool()

go 复制代码
func FormatBool(b bool) string
go 复制代码
func main() {
	// ... 您现有的其他代码保持不变 ...

	// 示例1: 基本转换
	b1 := true
	s1 := strconv.FormatBool(b1)
	fmt.Println("true 转换为:", s1) // 输出: true

	// 示例2: false转换
	b2 := false
	s2 := strconv.FormatBool(b2)
	fmt.Println("false 转换为:", s2) // 输出: false

	// 示例3: 条件表达式结果转换
	age := 20
	isAdult := age >= 18
	s3 := strconv.FormatBool(isAdult)
	fmt.Printf("年龄%d岁是否成年: %s\n", age, s3) // 输出: 年龄20岁是否成年: true

	// 示例4: 与ParseBool配合使用
	input := "TRUE"
	b, _ := strconv.ParseBool(input)
	output := strconv.FormatBool(b)
	fmt.Printf("输入:%s → 解析后:%t → 重新格式化:%s\n", input, b, output)
	// 输出: 输入:TRUE → 解析后:true → 重新格式化:true
}

FormatInt()

go 复制代码
func main() {

	// 示例1: 十进制转换
	num1 := int64(42)
	println(num1)
	s1 := strconv.FormatInt(num1, 10)
	fmt.Println("十进制42转换为:", s1) // 输出: 42

	// 示例2: 二进制转换
	num2 := int64(10)
	s2 := strconv.FormatInt(num2, 2)
	fmt.Println("十进制10转换为二进制:", s2) // 输出: 1010

	// 示例3: 十六进制转换
	num3 := int64(255)
	s3 := strconv.FormatInt(num3, 16)
	fmt.Println("十进制255转换为十六进制:", s3) // 输出: ff

	// 示例4: 八进制转换
	num4 := int64(8)
	s4 := strconv.FormatInt(num4, 8)
	fmt.Println("十进制8转换为八进制:", s4) // 输出: 10

	// 示例5: 负数转换
	num5 := int64(-42)
	s5 := strconv.FormatInt(num5, 10)
	fmt.Println("负数-42转换为:", s5) // 输出: -42

	// 示例6: 大数转换
	num6 := int64(1<<63 - 1) // 最大int64值
	s6 := strconv.FormatInt(num6, 10)
	fmt.Println("最大int64值转换为:", s6) // 输出: 9223372036854775807
}
go 复制代码
42
十进制42转换为: 42
十进制10转换为二进制: 1010
十进制255转换为十六进制: ff
十进制8转换为八进制: 10
负数-42转换为: -42
最大int64值转换为: 9223372036854775807

FormatUint()

go 复制代码
func main() {
	// 示例1: 十进制转换
	num1 := uint64(42)
	s1 := strconv.FormatUint(num1, 10)
	fmt.Println("十进制42转换为:", s1) // 输出: 42

	// 示例2: 二进制转换
	num2 := uint64(10)
	s2 := strconv.FormatUint(num2, 2)
	fmt.Println("十进制10转换为二进制:", s2) // 输出: 1010

	// 示例3: 十六进制转换
	num3 := uint64(255)
	s3 := strconv.FormatUint(num3, 16)
	fmt.Println("十进制255转换为十六进制:", s3) // 输出: ff

	// 示例4: 八进制转换
	num4 := uint64(8)
	s4 := strconv.FormatUint(num4, 8)
	fmt.Println("十进制8转换为八进制:", s4) // 输出: 10

	// 示例5: 大数转换
	num5 := uint64(1<<64 - 1) // 最大uint64值
	s5 := strconv.FormatUint(num5, 10)
	fmt.Println("最大uint64值转换为:", s5) // 输出: 18446744073709551615

	// 示例6: 自定义进制转换
	num6 := uint64(35)
	s6 := strconv.FormatUint(num6, 36) // 36进制
	fmt.Println("十进制35转换为36进制:", s6)   // 输出: z (36进制中z表示35)
}
go 复制代码
十进制42转换为: 42
十进制10转换为二进制: 1010
十进制255转换为十六进制: ff
十进制8转换为八进制: 10
最大uint64值转换为: 18446744073709551615
十进制35转换为36进制: z

FormatFloat()

go 复制代码
func main() {
	// 示例1: 普通小数格式
	f1 := 123.456789
	s1 := strconv.FormatFloat(f1, 'f', 2, 64)
	fmt.Println("保留2位小数:", s1) // 输出: 123.46

	// 示例2: 科学计数法
	f2 := 123456.789
	s2 := strconv.FormatFloat(f2, 'e', 3, 64)
	fmt.Println("科学计数法:", s2) // 输出: 1.235e+05

	// 示例3: 自动选择格式
	f3 := 123456.789
	s3 := strconv.FormatFloat(f3, 'g', 6, 64)
	fmt.Println("自动格式:", s3) // 输出: 123456.789

	// 示例4: 32位浮点数
	f4 := float32(123.456789)
	s4 := strconv.FormatFloat(float64(f4), 'f', 4, 32)
	fmt.Println("32位浮点数:", s4) // 输出: 123.4568

	// 示例5: 大数处理
	f5 := 1.23456789e20
	s5 := strconv.FormatFloat(f5, 'G', 8, 64)
	fmt.Println("大数处理:", s5) // 输出: 1.2345679e+20

}
go 复制代码
保留2位小数: 123.46
科学计数法: 1.235e+05
自动格式: 123457
32位浮点数: 123.4568
大数处理: 1.2345679E+20

其他

isPrint()

返回一个字符是否是可打印的,和unicode.IsPrint一样,r必须是:字母(广义)、数字、标点、符号、ASCII空格。

go 复制代码
func main() {
	// 示例1: 可打印字符
	fmt.Println("字母A:", strconv.IsPrint('A'))  // true
	fmt.Println("数字1:", strconv.IsPrint('1'))  // true
	fmt.Println("空格:", strconv.IsPrint(' '))   // true
	fmt.Println("中文:", strconv.IsPrint('中'))   // true
	fmt.Println("标点:", strconv.IsPrint('!'))   // true
	fmt.Println("换行符:", strconv.IsPrint('\n')) // true

	// 示例2: 不可打印字符
	fmt.Println("控制字符:", strconv.IsPrint('\x00')) // false
	fmt.Println("退格:", strconv.IsPrint('\b'))     // false
	fmt.Println("铃响:", strconv.IsPrint('\a'))     // false
	fmt.Println("删除:", strconv.IsPrint('\x7f'))   // false

	// 示例3: 字符串中字符检查
	str := "Hello\t世界!\n"
	for i, r := range str {
		if !strconv.IsPrint(r) {
			fmt.Printf("位置 %d 的字符 %U 不可打印\n", i, r)
		}
	}
}
go 复制代码
字母A: true
数字1: true
空格: true
中文: true
标点: true
换行符: false
控制字符: false
退格: false
铃响: false
删除: false
位置 5 的字符 U+0009 不可打印
位置 13 的字符 U+000A 不可打印

Http

Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现。

get请求

go 复制代码
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	// 示例1: 基本GET请求
	resp, err := http.Get("https://www.baidu.com")
	if err != nil {
		fmt.Println("请求错误:", err)
		return
	}
	defer resp.Body.Close()

	// 打印响应状态
	fmt.Println("状态码:", resp.Status)
	fmt.Println("响应头:", resp.Header)

	for key, values := range resp.Header {
		fmt.Println(key, ":", values)
	}

	// 示例2: 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取响应体错误:", err)
		return
	}
	fmt.Println("响应体长度:", len(body))
	fmt.Println("响应体内容:", string(body))

	// 示例3: 将响应保存到文件
	file, err := os.Create("baidu.html")
	if err != nil {
		fmt.Println("创建文件错误:", err)
		return
	}
	defer file.Close()

	_, err = file.Write(body)
	if err != nil {
		fmt.Println("写入文件错误:", err)
		return
	}
	fmt.Println("网页已保存到 baidu.html")
}
带参数的GET请求示例
go 复制代码
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

func main() {
	apiUrl := "http://127.0.0.1:9090/get"
	// URL param
	data := url.Values{}
	data.Set("name", "枯藤")
	data.Set("age", "18")
	u, err := url.ParseRequestURI(apiUrl)
	fmt.Println("uuuu==111==>", u.String())
	if err != nil {
		fmt.Printf("parse url requestUrl failed,err:%v\n", err)
	}
	u.RawQuery = data.Encode() // URL encode
	fmt.Println("uuuu==222==>", u.String())
	resp, err := http.Get(u.String())
	if err != nil {
		fmt.Println("post failed, err:%v\n", err.Error())
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("get resp failed,err:%v\n", err)
		return
	}
	fmt.Println(string(b))
}

Post请求示例

上面演示了使用net/http包发送GET请求的示例,发送POST请求的示例代码如下:

go 复制代码
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
)

// net/http post demo

func main() {
	url := "http://tp.demos.xp/post"
	// 表单数据
	//contentType := "application/x-www-form-urlencoded"
	//data := "name=枯藤&age=18"
	// json
	contentType := "application/json"
	data := `{"name":"nicolas","age":18}`
	resp, err := http.Post(url, contentType, strings.NewReader(data))
	if err != nil {
		fmt.Println("post failed, err:%v\n", err)
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("get resp failed,err:%v\n", err)
		return
	}
	fmt.Println(string(b))
}
}

数据格式

json

go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)

// net/http post demo
type Person struct {
	Name  string
	Hobby string
}

func main() {
	p := Person{"baidu.com", "女"}
	// 编码json
	b, err := json.Marshal(p)
	if err != nil {
		fmt.Println("json err ", err)
	}
	fmt.Println(string(b))

	// 格式化输出
	b, err = json.MarshalIndent(p, "", "     ")
	if err != nil {
		fmt.Println("json err ", err)
	}
	fmt.Println(string(b))
}
go 复制代码
{"Name":"5lmh.com","Hobby":"女"}
{
     "Name": "5lmh.com",
     "Hobby": "女"
}

xml

go 复制代码
package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
)

// 抽取单个server对象
type Server struct {
	ServerName string `xml:"serverName"`
	ServerIP   string `xml:"serverIP"`
}

type Servers struct {
	Name    xml.Name `xml:"servers"`
	Version int      `xml:"version"`
	Servers []Server `xml:"server"`
}

func main() {
	data, err := ioutil.ReadFile("my.xml")
	if err != nil {
		fmt.Println(err)
		return
	}
	var servers Servers
	err = xml.Unmarshal(data, &servers)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("xml: %#v\n", servers)
}
go 复制代码
xml: main.Servers{Name:xml.Name{Space:"", Local:""}, Version:1, Servers:[]main.Server{main.Server{ServerName:"Server1", ServerIP:"192.168.1.1"}, main.Server{ServerName:"Server2", ServerIP:"192.168.1.2"}}}
相关推荐
Aousdu23 分钟前
算法_python_学习记录_01
python·学习·算法
一只 Lemon24 分钟前
PHP-单引号和双引号(通俗易懂讲解版)
开发语言·php
雪球不会消失了36 分钟前
Kafka学习记录
分布式·学习·kafka
忧郁的蛋~1 小时前
C#中LINQ to DataSet操作及DataTable与LINQ相互转换
开发语言·c#·linq
呼哧呼哧.1 小时前
Java 8特性(一)
java·开发语言
Runing_WoNiu1 小时前
Golang 与Java 单例模式、工厂模式比较
java·单例模式·golang
xingkongvv123 小时前
C# 异步编程
java·服务器·开发语言·前端·javascript
wjs20243 小时前
HTML DOM 访问
开发语言
●VON4 小时前
重生之我在暑假学习微服务第十一天《配置篇》+网关篇错误订正
java·学习·微服务·云原生·暑假