- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
fmt 标准库是 Go 语言标准库的一部分,提供了格式化字符串、输入输出等基本功能。通过 fmt 库,我们可以进行简单的格式化输出、读取用户输入、错误输出等操作.
fmt 库实现了类似 C 语言 printf 和 scanf 的格式化 I/O,主要分为向外输出内容和获取输入内容两大部分,本文将通过示例来分别测试.
GO 语言的输出是由 Print 系列函数完成的,下面列一下都有哪些输出类型.
Print 函数直接输入内容到终端,是最简单的输出方式.
package main
import (
"fmt"
)
func main() {
fmt.Print("第一段")
fmt.Print("第二段")
fmt.Print("第三段")
}
由输出可见,Print 函数直接输出引号中的内容,不进行任何修饰.
fmt.Printf 是 Go 语言 fmt 包中的一个函数,用于格式化输出字符串.
它的基本语法是 fmt.Printf(format, a, b, c, ...),其中 format 是一个字符串,用于指定输出的格式,a, b, c, ... 是需要输出的参数。fmt.Printf 会按照 format 字符串中的格式说明符,将参数转换为相应的格式输出.
对于 format 中的格式说明,有比较多格式配置,下面总结下.
占位符 | 说明 |
%v | 根据值的默认格式标识仅输出值 |
%+v | 在 v% 的基础上,带上字段名 |
%#v | 按照值的 GO 语法表示输出,类型+值 |
%T | 输出值的类型 |
%% | 输出单个字符:百分号 |
下面通过输出三个类型(常量、字符串、自定义结构)来简单演示下:
package main
import "fmt"
func main() {
pi := 3.1415926
fmt.Printf("%%v-pi :%v \n", pi) // %v 值的类型输出
fmt.Printf("%%+v :%+v \n", pi)
fmt.Printf("%%#v :%#v \n", pi)
fmt.Printf("%%T :%T \n", pi)
str := "chengzi"
fmt.Printf("%%v-str:%v \n", str)
fmt.Printf("%%+v :%+v \n", str)
fmt.Printf("%%#v :%#v \n", str)
fmt.Printf("%%T :%T \n", str)
stu := struct {
name string
address string
}{"橙子", "河南"}
fmt.Printf("%%v-stu:%v \n", stu)
fmt.Printf("%%+v :%+v \n", stu)
fmt.Printf("%%#v :%#v \n", stu)
fmt.Printf("%%T :%T \n", stu)
}
针对布尔类型,有个专用的占位符: %t ,用于直接输出 true/false .
如果要输出的字段不是布尔类型,不会中断程序运行,只会有警告提示.
package main
import "fmt"
func main() {
fmt.Printf("%%t :%t \n", true)
fmt.Printf("%%t :%t \n", false)
fmt.Printf("%%t :%t \n", "chengzi")
}
。
占位符 | 说明 |
%b | 输出值对应的二进制格式值 |
%c | 输出值对应的 Unicode 码值 |
%d | 输出值对应的十进制格式值 |
%o | 输出值对应的八进制格式值 |
%x | 输出值对应的十六进制格式值,小写字母 a~f |
%X | 输出值对应的十六进制格式值,大写字母 A~F |
%U | 输出值对应的 Unicode 格式:U+1234 |
%q | 该值对应的 单引号 括起来的 Go 语法字符字面值,必要时会采用安全的转义表示 |
注:统一码(Unicode),也叫万国码、单一码,由统一码联盟开发,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。其中 3400-4DBF/4E00-9FFF/20000-3FFFF,表示中日韩越统一表意文字(CJKV Unified Ideographs).
如下通过对整数 100 的多类型输出,示例说明一下各个占位符对应的区别:
package main
import "fmt"
func main() {
num := 100
fmt.Printf("%%b :%b\n", num)
fmt.Printf("%%c :%c\n", num)
fmt.Printf("%%d :%d\n", num)
fmt.Printf("%%o :%o\n", num)
fmt.Printf("%%x :%x\n", num)
fmt.Printf("%%X :%X\n", num)
fmt.Printf("%%U :%U\n", num)
fmt.Printf("%%q :%q\n", num)
}
占位符 | 说明 |
%e | 科学计数法,小写字母:-1.234567e+89 |
%E | 科学计数法,大写字母:-1.234567E+89 |
%f | 有小数(六位)、无指数:123.456789 |
%F | 同上 |
%g | 以使用更简洁、准确的格式输出为目的,灵活采用 %e 或 %f 格式,小数保留前十四位 |
%G | 以使用更简洁、准确的格式输出为目的,灵活采用 %E 或 %F 格式 |
package main
import "fmt"
func main() {
f := 123.45600
fmt.Printf("f-%%e :%e\n", f)
fmt.Printf("f-%%E :%E\n", f)
fmt.Printf("f-%%f :%f\n", f)
fmt.Printf("f-%%F :%F\n", f)
fmt.Printf("f-%%g :%g\n", f) // 最多保留十四位小数
fmt.Printf("f-%%G :%G\n", f) // 最多保留十四位小数
ff := 123.4560001001000111001000011001
fmt.Printf("ff-%%e :%e\n", ff)
fmt.Printf("ff-%%E :%E\n", ff)
fmt.Printf("ff-%%f :%f\n", ff)
fmt.Printf("ff-%%F :%F\n", ff)
fmt.Printf("ff-%%g :%g\n", ff) // 最多保留十四位小数,末尾若是 0 默认省去
fmt.Printf("ff-%%G :%G\n", ff) // 最多保留十四位小数
}
占位符 | 说明 |
%s | 直接输出字符串或 []byte |
%q | 该值对应的双引号括起来的 Go 语法字符串字面值,必要时会采用安全的转义表示 |
%x | 每个字节用两字符十六进制数表示,小写 a~f |
%X | 每个字节用两字符十六进制数表示,大写 A~F |
package main
import "fmt"
func main() {
str := "橙子"
fmt.Printf("%%s: %s\n", str)
fmt.Printf("%%q: %q\n", str)
fmt.Printf("%%x: %x\n", str)
fmt.Printf("%%X: %X\n", str)
byte := []byte("橙子")
fmt.Printf("%%v: %v\n", byte)
fmt.Printf("%%s: %s\n", byte)
}
指针也是一个专门的占位符 %p ,表示 ‘十六进制字符串’+‘0x’ .
package main
import "fmt"
func main() {
a := 18
fmt.Printf("%p\n", &a)
fmt.Printf("%#p\n", &a)
}
宽度标识符就是以浮点数占位符中的 %f 为基础,增加宽度配置。%[n].[m]f 其中 n 表示整个数值的宽度,m 表示小数位宽度。如下示例与代表的意义:
占位符 | 说明 |
%f | 默认宽度、默认精度 |
%9f | 宽度 9、默认精度 |
%.2f | 默认宽度、精度 2 |
%9.2f | 宽度 9、精度 2 |
%9.f | 宽度 9、精度 0 |
注意:小数点也占用一个位数.
package main
import "fmt"
func main() {
n := 88.88
fmt.Printf("%%f :%f\n", n) // 默认小数位为六位
fmt.Printf("%%9f :%9f\n", n)
fmt.Printf("%%10f :%10f\n", n)
fmt.Printf("%%.2f :%.2f\n", n)
fmt.Printf("%%9.2f :%9.2f\n", n)
fmt.Printf("%%9.f :%9.f\n", n)
}
。
占位符 | 说明 |
+ | 总是输出数值的正负号;对 %q(%+q)会生成全部是 ASCII 字符的输出(通过转义) |
(一个空格) | 对数值:正数前加空格而负数前加负号 。 对字符串:采用%x或%X时(% x或% X)会给各打印的字节之间加空格 。 |
-(一个横杠) | 在输出右边填充空白,而不是默认的左边(即从默认的右对齐切换为左对齐) |
# | 八进制数前加 0(%#o) 。 十六进制数前加 0x,对于 %x(%#x);0X,对于 %X(%#X) 。 指针去掉前面的 0x,对于 %q(%#q), 。 unicode 值,对 %U(%#U)会输出空格和单引号括起来的 Go 字面值 。 |
0 | 使用 0 而不是空格填充,对于数值类型会把填充的 0 放在正负号后面 |
package main
import "fmt"
func main() {
fmt.Println("-----------------------------")
num := -12.34
num1 := 12.34
fmt.Printf("%f %f\n", num, num1)
fmt.Printf("%+f %+f\n", num, num1)
fmt.Println("-----------------------------")
num2 := -12.34
num3 := 12.34
fmt.Printf("%f %f\n", num2, num3)
fmt.Printf("% f % f\n", num2, num3)
str := "chengzi"
fmt.Printf("%x\n% x\n", str, str)
fmt.Println("-----------------------------")
num4 := 77.77
fmt.Printf("%10f\n", num4)
fmt.Printf("%0-10f\n", num4)
fmt.Println("-----------------------------")
str1 := "chengzi"
fmt.Printf("%s\n", str1)
fmt.Printf("%8s\n", str1) // 默认左侧填充一个空格,右对齐
fmt.Printf("%-8s\n", str1) // 左对齐
fmt.Printf("%08s\n", str1) // 填充 0
fmt.Printf("%-08s\n", str1) // 左对齐并填充 0,可以左对齐,但此时填充无法实现
}
其实 Println 就是在打印输出内容后添加一个换行符‘\n’.
package main
import "fmt"
func main() {
fmt.Print("Println测试")
fmt.Println("-----------------------------")
fmt.Print("Println测试")
}
横线直接跟在了第一行,第二个输出自动进行了换行.
Fprint 系列函数 会将内容输出到一个 io.Writer 接口类型的变量 w 中,我们通常用这个函数 往文件中写入内容 .
func Fprint(w io.Writer, a ...interface{}) (n int, err error) func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 。
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("开始向标准输出写入内容...")
fileObj, err := os.OpenFile("./log.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
// O_CREATE(不存在则创建)O_WRONLY(只写)O_APPEND(追加内容)
if err != nil {
fmt.Println("打开文件出错,err:", err)
return
}
content := "chengzi子"
// 向打开的文件句柄中写入内容
fmt.Fprintf(fileObj, "往文件中写入信息:%s\n", content)
fmt.Fprintln(fileObj, "又一行信息。")
fmt.Fprint(fileObj, "再一行信息。")
fmt.Fprint(fileObj, "最后的信息。")
fmt.Println("写入完成!")
}
终端输出:
func Sprint(a ...interface{}) string func Sprintf(format string, a ...interface{}) string func Sprintln(a ...interface{}) string 。
package main
import (
"fmt"
)
func main() {
s1 := fmt.Sprint("chengzi家")
fmt.Println(s1)
s2 := fmt.Sprintln("chengzi家")
fmt.Println(s2)
name := "chengzi家"
age := 18
s3 := fmt.Sprintf("name:%s,age:%d", name, age)
fmt.Println(s3)
}
Errorf 函数根据 format 参数生成格式化字符并返回一个包含该字符串的错误.
func Errorf(format string, a ...interface{}) error 。
fmt.Errorf 的优点在于其支持格式化字符串,这使得我们可以方便地在原始错误信息中包含一些动态的数据,但是它并不会保留原始错误的堆栈跟踪信息.
Go 1.13 中引入的新特性使 fmt.Errorf 通过 %w 谓词包装错误,这样就可以保留原始错误的信息。如下:
package main
import (
"errors"
"fmt"
)
func main() {
original_err := errors.New("original error")
new_err := fmt.Errorf("an error occurred: %w", original_err)
fmt.Println(new_err)
}
另外, errors.Wrap 和 errors.Wrapf 是包含原始错误的堆栈跟踪信息 。它们是 github.com/pkg/errors 库中的函数,用于创建新的错误。它们接受一个原始错误和一个描述信息,返回一个新的错误,结构如下:
err := errors.Wrap(err, "an error occurred")
err = errors.Wrapf(err, "an error occurred: %s", "additional context")
errors.Wrap 和 errors.Wrapf 的优点在于它们会保留原始错误的堆栈跟踪信息。你可以使用 errors.Cause 函数获取到原始错误,使用 fmt.Printf("%+v", err) 打印完整的错误信息和堆栈跟踪。 。
此外,errors.Wrapf 还支持格式化字符串,这意味着我们可以在错误信息中直接包含动态的数据。如下一个关于 errors.Wrap 和 errors.Wrapf 的示例:
package main
import (
"fmt"
"github.com/pkg/errors"
)
func main() {
original_err := errors.New("original error")
new_err := fmt.Errorf("fmt.Errorf(): %w", original_err)
fmt.Println(new_err)
fmt.Println("------------------------------------------")
fmt.Println("------------------------------------------")
err := errors.Wrap(original_err, "errors.Wrap()")
fmt.Printf("fmt.Wrap():%+v\n", err)
fmt.Println("------------------------------------------")
fmt.Println("------------------------------------------")
err = errors.Wrapf(original_err, "errors.Wrapf(): %s", "additional context")
fmt.Printf("fmt.Wrapf():%+v\n", err)
}
1.6 参考: https://cloud.tencent.com/developer/article/2311646 。
Go 语言 fmt 包下有 fmt.Scan、fmt.Scanf、fmt.Scanln 三个函数,可以在程序运行过程中从标准输入获取用户的输入。下面分别来介绍下.
Scan 从标准输入扫描文本,读取由 空白符分割的值 保存到传递给本函数的参数中, 换行符或空格视为空白符 .
本函数返回成功扫描的数据个数和遇到的任何错误。如果读取的数据个数比提供的参数少,会返回一个错误描述原因.
func Scan(a ...interface{}) (n int, err error) 。
package main
import (
"fmt"
)
func main() {
var (
name string
age int
married bool
)
fmt.Println("请输入字符参数,回车确认输入完成:")
fmt.Scan(&name, &age, &married)
fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}
客户端手动输入多个字符参数时,用空格或换行分隔且可以混用,最后通过回车确认输入完成。如下是几个输入示例:
相较于 fmt.Scan(),fmt.Scanf() 可以定义输入参数的格式,只有按照指定格式输入才会识别,更加标准化.
Scanf 从标准输入扫描文本,根据 format 参数指定的格式去读取由空白符分隔的值保存到传递给本函数的参数中.
本函数返回成功扫描的数据个数和遇到的任何错误.
func Scanf(format string, a ...interface{}) (n int, err error) 。
package main
import "fmt"
func main() {
var (
name string
age int
married bool
)
fmt.Println("请输入字符参数,回车确认输入完成:")
fmt.Scanf("1:%v 2:%v 3:%v", &name, &age, &married)
fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}
相较于 fmt.Scan(),fmt.Scanln 不允许输入多个参数间回车,只能通过空格来分隔多个参数,最后回车确认输入.
Scanln 类似 Scan,它在遇到换行时才停止扫描。最后一个数据后面必须有换行或者到达结束位置.
本函数返回成功扫描的数据个数和遇到的任何错误.
func Scanln(a ...interface{}) (n int, err error) 。
package main
import "fmt"
func main() {
var (
name string
age int
married bool
)
fmt.Println("请输入字符参数,回车确认输入完成:")
fmt.Scanln(&name, &age, &married)
fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}
当想获取完整获取输入的内容,但是输入的内容可能包含空格,这种情况下可以使用 bufio 包来实现.
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin) // 从标准输入生成读对象
fmt.Print("请输入内容:")
text, _ := reader.ReadString('\n') // 读到换行
text = strings.TrimSpace(text)
fmt.Printf("%#v\n", text)
}
这几个函数功能分别类似于 fmt.Scan、fmt.Scanf、fmt.Scanln 三个函数,只不过它们不是从标准输入中读取数据而是从 io.Reader 中读取数据。注意:Fscan 系列都是和 io 阻塞的有关系.
func Fscan(r io.Reader, a ...interface{}) (n int, err error) func Fscanln(r io.Reader, a ...interface{}) (n int, err error) func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 。
package main
import (
"fmt"
"strings"
)
func main() {
var (
name string
age int
married bool
)
reader := strings.NewReader("chengzijia 18 false")
intt, _ := fmt.Fscan(reader, &name, &age, &married)
fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
fmt.Printf("intt:%v\n", intt)
}
。
这几个函数功能分别类似于 fmt.Scan、fmt.Scanf、fmt.Scanln 三个函数,只不过它们不是从标准输入中读取数据而是从指定字符串中读取数据.
func Sscan(str string, a ...interface{}) (n int, err error) func Sscanln(str string, a ...interface{}) (n int, err error) func Sscanf(str string, format string, a ...interface{}) (n int, err error) 。
package main
import "fmt"
func main() {
{ // Sscan
var name string
var alphabet_count int
n, err := fmt.Sscan("GFG 3", &name, &alphabet_count) // 根据空格取值
if err != nil {
panic(err)
}
fmt.Printf("%d:%s, %d\n", n, name, alphabet_count)
}
{ // Sscanln
var name string
var alphabet_count int
n, err := fmt.Sscanln("GFG 3", &name, &alphabet_count) // 根据空格取值
if err != nil {
panic(err)
}
fmt.Printf("n:%d, name:%s, alphabet_count:%d\n",
n, name, alphabet_count)
}
{ // Sscanf
var name string
var alphabet_count int
n, err := fmt.Sscanf("GFG is having 3 alphabets.", // 根据模板取值
"%s is having %d alphabets.", &name, &alphabet_count)
if err != nil {
panic(err)
}
fmt.Printf("%d:%s, %d\n", n, name, alphabet_count)
}
}
参考: http://www.topgoer.com/%E5%B8%B8%E7%94%A8%E6%A0%87%E5%87%86%E5%BA%93/fmt.html 。
最后此篇关于fmt库简介和示例【GO基础】的文章就讲到这里了,如果你想了解更多关于fmt库简介和示例【GO基础】的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
vue3 快速入门系列 - 基础 前面我们已经用 vue2 和 react 做过开发了。 从 vue2 升级到 vue3 成本较大,特别是较大的项目。所以许多公司对旧项目继续使用vue2,新项目则
C# 基础 C#项目创建 这里注意win10虚拟机需要更新下补丁,不然直接下载visual studio 2022会显示版本不支持 HelloWorld C#的类文件都是以.cs结尾,入口方法为sta
关于 iPhone 内存管理的非常基本的问题: 假设我有一个 viewController,其中有几个 subview 也由 viewController 控制。当我删除顶部 viewControll
我仍在努力适应指针。不是概念——我理解内存位置、匹配可变长度的指针增量等——这是语法。这是一个我认为是我感到困惑/无法直观把握的原因之一: int a = 42; 在一个int大小的内存空间中分配并放
1. 简介 Kafka(Apache Kafka) 是一种分布式流数据平台,最初由LinkedIn开发,并于后来捐赠给Apache软件基金会,成为了一个Apache顶级项目。它被设计用于处理大规
1.想要在命令提示符下操作mysql服务器,添加系统变量。(计算机-系统属性——环境变量——path) 2.查询数据表中的数据; select selection_lis
MySQL表的增删改查(基础) 1. CRUD 注释:在SQL中可以使用“–空格+描述”来表示注释说明 CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Dele
我有一个网页,可以在加载时打开显示模式,在这个模式中,我有一个可以打开第二个模式的链接。当第二个模式关闭时(通过单击关闭按钮或单击模式外部),我想重新打开第一个模式。 对于关闭按钮,我可以通过向具有
使用 Core Data Fetched Properties,我如何执行这个简单的请求: 我希望获取的属性 ( myFetchProp ) 存储 StoreA ,它应该这样做: [myFetchPr
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 8年前关闭。 Improve this
最近,我得到了一个现有的Drupal项目,并被要求改进前端(HTML,JavaScript,CSS)。我在Django,PHP,Ruby等方面具有大量的前端和后端开发经验,但是我没有任何Drupal经
我试图让我的用户通过使用扫描仪类来决定要做什么,但我有一个问题,代码一旦运行就不会激活,并且它不会让我跳过任何行。我的代码如下所示: Scanner input = new Scanner(S
对模糊的标题表示歉意,因为我想不出这个名字是什么。 基本上创建一个计算学生财务付款的小程序。当我运行它时,它计算对象限额没有问题。然而,无论我尝试什么,对象“助学金”似乎除了 0 之外什么也没有提出。
这是我的代码 - main() { double x; double y = pow(((1/3 + sin(x/2))(pow(x, 3) + 3)), 1/3); prin
如果我的术语在这个问题上有误,我们深表歉意。 采取以下功能: i = 1; v = i * 2; for (j = 0; j < 4; j++ ) { console.log(v);
我的应用程序中有不同的类文件。我有 5 个类,其中 2 个是 Activity ,1 个是运行的服务。其他 2 个只是类。这两个类中变量的生命周期是多少。我知道一个 Activity 可以被操作系统杀
例如,一个方法返回一个 List 类型的对象。 public List bojangles () ... 一些代码调用方法FooBar.bojangles.iterator(); 我是 Java 的新
我遇到了一个奇怪的问题,网格的大小不适合我的屏幕。当我使用 12 列大时,它只占据屏幕的 1/3 的中间,请参见图像。我不确定是什么导致了这个问题。我没有任何会导致这种情况发生的奇怪 CSS。我不会在
我尝试使用头文件和源文件,但遇到了问题。因此,我对我正在尝试做的事情做了一个简化版本,我在 CodeBlocks 中遇到了同样的错误(undefined reference to add(double
我正在为我的网格系统使用基础,但这在任何网格系统中都可能是一个问题。我基本上用一个容器包裹了 3 个单元格,但其中一个单元格应该长到页面边框(留在我的 Sampe-Image 中)但这也可能在右侧)。
我是一名优秀的程序员,十分优秀!