fmt包
在Go语言中,fmt
包是一个非常重要且广泛使用的标准库包,它提供了格式化I/O(输入/输出)功能,类似于C语言中的 printf
和 scanf
。通过这个包,你可以读取输入并将数据格式化输出到标准输出或其他写入器(writers)。
主要功能
-
打印:
Print
,Printf
,Println
: 这些函数用于向标准输出打印文本。其中,Printf
允许使用格式化字符串。
-
格式化:
- 格式化功能允许你控制数字、字符串等的显示方式。例如
%d
用于整数、%f
用于浮点数、%s
用于字符串等。
- 格式化功能允许你控制数字、字符串等的显示方式。例如
-
读取:
Scan
,Scanf
,Scanln
: 这些函数从标准输入读取,并根据需要解析输入的数据。
-
字符串处理:
Sprint
,Sprintf
,Sprintln
: 这些函数不会向标准输出打印,而是返回一个格式化后的字符串。- 类似地,还有对应的错误处理版本如:Fprint系列可以将内容打印到任何实现了io.Writer接口的对象。
使用示例
打印和格式化
package main
import "fmt"
func main() {
print("内置输出")
println("换行输出")
fmt.Println("--------------------")
fmt.Print("fmt输出")
fmt.Println("换行输出")
fmt.Printf("这是占位符【%s】\n", "ok")
fmt.Printf("这是占位符【%d】\n", 123)
fmt.Printf("这是占位符【%f】\n", 123.456)
fmt.Printf("这是占位符【%.2f】\n", 123.456) // 保留两位,四舍五入
// 格式化输出
name := "小明"
age := 30
height := 1.8
fmt.Printf("名字: %s, 年龄: %d, 身高: %.2f米\n", name, age, height)
}
输入读取
package main
import "fmt"
func main() {
var name string
var age int
fmt.Print("请输入你的名字和年龄(空格或者换行隔开): ")
fmt.Scan(&name, &age)
fmt.Printf("Name: 【%s】, Age: 【%d】\n", name, age)
var a string
var b int
var c float64
fmt.Println("请输入字符串、整数、小数,用空格隔开:")
fmt.Scanf("%s %d %f", &a, &b, &c) // 可以理解为输入的值会先放在第一个参数的位置,再解析出a\b\c三个值
fmt.Printf("a: 【%s】, b: 【%d】, c: 【%f】\n", a, b, c)
}
注意:
fmt.Scanf
:Scanf
函数使用格式字符串来解析输入,它需要一个格式字符串参数,后面跟着要填充的变量的地址。- 它从标准输入(通常是键盘)读取输入,直到遇到换行符或文件末尾。
Scanf
会根据格式字符串中的格式说明符来匹配和解析输入的值,并将它们赋给相应的变量。
fmt.Scan
:Scan
函数不需要格式字符串,它直接读取输入并将其赋值给提供的变量。- 它同样从标准输入读取,但它不会尝试根据格式字符串解析输入,而是简单地读取空白字符分隔的值。
Scan
在处理输入时不如Scanf
那样灵活,因为它不会根据格式说明符来解析输入。
- scan相关的方法使用,goland会提醒Unhandled error,这是因为我们代码没有做好异常的控制处理,后期再详细学习异常(错误)处理相关的知识
常见格式说明符
%v
: 默认方式表示变量值。%+v
: 当输出结构体时,默认添加字段名。%#v
: 输出值的Go语法表示方式。%T
: 输出值类型。%d
: 整型格式显示。%s
: 字符串显示。%f
: 浮点数显示。
数据类型
Go语言提供了一系列的基本数据类型,这些类型可以分为几个主要类别:基本类型、复合类型、引用类型和接口类型。这里先展开基本类型
基本类型
- 布尔型:
bool
:表示真或假,值为true
或false
。
- 数字型:
- 整数:
- 有符号整型:
int8
,int16
,int32
,int64
- 无符号整型:
uint8
,uint16
,uint32
,uint64
- 特定长度整数:例如,
byte
(等同于uint8
),rune
(等同于int32
) - 通用大小整数(根据操作系统决定大小):
int
,uint
- 指针整数(指针后面再详细展开):
uintptr
- 有符号整型:
- 浮点数:
- 单精度浮点数:
float32
- 双精度浮点数:
float64
- 单精度浮点数:
- 复数(少用):
- 小复数:
complex64
(实部和虚部都是 float32) - 大复数:
complex128
(实部和虚部都是 float64)
- 小复数:
- 整数:
- 字符串:
- 字符串由字节序列组成,使用 UTF-8 编码表示 Unicode 文本。
注意:
int
类型的长度取决于你的计算机系统架构:
- 在 32位 系统上,
int
通常是 32位 。 - 在 64位 系统上,
int
通常是 64位 。
查看我的int是多少位:
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Printf("我的系统中int是 %d 位\n", strconv.IntSize)
}
示例
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Printf("我的系统中int是 %d 位\n", strconv.IntSize)
// 布尔型
var isActive bool = false
// 整形
var int1 int = 123 // 32 位系统中:-2147483648 到 2147483647,64 位系统中:-9223372036854775808 到 9223372036854775807
var int2 int8 = -128 // -128 到 127
var int3 int16 = 32767 // -32768 到 32767
var int4 int32 = 2147483647 // -2147483648 到 2147483647
var int5 int64 = 9223372036854775807 // -9223372036854775808 到 9223372036854775807
var int6 uint = 18446744073709551615 // 32 位系统中 :0 到 4294967295 ,64 位系统中:0 到 18446744073709551615
// 浮点型
var float float64 = 3.5
// 字符串
var str1 string = "\n啊啊啊"
var str2 string = `\n啊啊啊`
fmt.Println(isActive)
fmt.Println(int1, int2, int3, int4, int5, int6)
fmt.Println(float)
fmt.Println(str1)
fmt.Println(str2)
}
字符串的定义
字符串可以用双引号 ("
) 或反引号 (`
) 来定义。它们之间有一些重要的区别:
使用双引号 ("
)
- 双引号用于定义常规的字符串。
- 支持转义序列。例如,
\n
代表换行符,\t
代表制表符等。 - 必须在同一行结束。
使用反引号 (`
)
- 反引号用于定义原生的字符串字面量(raw string literals),其中所有的字符都是直接按照字面意思解释,不进行转义。
- 可以跨多行书写而不需要特殊的换行符。
- 常用于编写多行文本、嵌入JSON、HTML或正则表达式等场景。
如果你需要在字符串中包含特殊字符或转义序列,并且希望它们被解释和处理,则应该使用双引号。如果你希望保留原始格式,并且不想处理任何转义逻辑,则使用反引号会更合适。
示例
package main
import "fmt"
func main() {
str1 := "字符串1\n字符串1"
str2 := `字符串2\n字符串2
字符串2`
fmt.Println(str1)
fmt.Println(str2)
}
特别
如果我用 `
定义的字符串中,要使用 `
这个符号怎么办,会遇到一个问题,因为反引号内部不能直接包含反引号。
方法1: 使用双引号和转义
如果你需要在文本中包含反引号字符,可以考虑将整个字符串或字符串的那一部分改用双引号,并使用转义序列。例如:
s1 := "输出`反引号"
fmt.Println(s1)
方法2: 拼接字符串
另一种方法是将原生字符串分成几部分,并用加号 (+
) 将它们连接起来,在需要插入反引号的地方切换到双引号定义的字符串:
s2 := `输出` + "`" + `反引号`
fmt.Println(s2)