Golang中fmt.Printf()方法遇到的问题排查
Golang中fmt.Printf()方法遇到的问题排查
var s = 'a'
fmt.Printf("%T type of s\n",s,"mangalarora")
fmt.Println(s)
输出:
int32 type of s
%!(EXTRA string=mangalarora)97
它应该给出错误,而不是打印出这是额外的字符串输出。
感谢您告诉我这一点。我没有阅读文档,只是开始尝试用Go做一些新东西。
而且我认为这应该显示错误,而不是显示额外的字符串。
更多关于Golang中fmt.Printf()方法遇到的问题排查的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用 Visual Studio Code 和 Go 插件时至少会给出警告。我猜这来自 go vet。但它不会对额外的参数提出警告。

编译时错误还是运行时恐慌?
我更倾向于在编译时出现错误,这样有时会让事情变得更容易。但另一方面,编译器需要特别处理fmt.Printf及其相关函数,而那些使用args...包装这些函数的代码(比如日志记录器)仍然需要在运行时处理这些问题。
然而运行时恐慌会很麻烦……特别是对于动态生成的格式化字符串/参数,它可能导致我的程序崩溃,而我却没有机会对此采取任何措施,或者我不得不在每次使用打印功能时都使用延迟的恐慌处理程序……这也不好玩……
func main() {
fmt.Println("hello world")
}
谁说过它应该报错?
它的行为符合文档描述:
fmt package - fmt - Go Packages
格式化错误:
如果为动词提供了无效参数,例如为 %d 提供字符串,生成的字符串将包含问题描述,如下例所示:
错误类型或未知动词:%!verb(type=value) Printf("%d", hi): %!d(string=hi) 参数过多:%!(EXTRA type=value) Printf("hi", "guys"): hi%!(EXTRA string=guys) 参数过少:%!verb(MISSING) Printf("hi%d"): hi%!d(MISSING) 宽度或精度使用非整数值:%!(BADWIDTH) 或 %!(BADPREC) Printf("%*s", 4.5, "hi"): %!(BADWIDTH)hi Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi 参数索引无效或使用不当:%!(BADINDEX) Printf("%*[2]d", 7): %!d(BADINDEX) Printf("%.[2]d", 7): %!d(BADINDEX)
在Go语言中,fmt.Printf 的行为与预期一致,但代码中存在两个问题导致输出不符合预期。以下是详细解释和修正方法:
-
单引号字符类型问题:在Go中,单引号
'a'表示一个 rune 类型(int32 的别名),而不是字符串。因此,var s = 'a'声明s为 rune 类型,%T正确输出int32。 -
fmt.Printf 的格式字符串不匹配:
fmt.Printf的第一个参数是格式字符串,其中%T是一个格式化动词,用于输出变量的类型。在您的代码中,格式字符串"%T type of s\n"只包含一个%T,但您传递了两个额外参数:s和"mangalarora"。fmt.Printf会处理格式字符串中的所有格式化动词,如果额外参数未被使用,它会输出%!(EXTRA ...)错误信息。这里,"mangalarora"是额外参数,因此输出%!(EXTRA string=mangalarora)。 -
fmt.Println 输出 rune 值:
fmt.Println(s)输出 rune'a'的整数值 97(因为 rune 是 int32,'a'的 Unicode 码点是 97)。
如果您期望输出错误,可能是因为误解了 Go 的强类型和 fmt 包的行为。Go 在编译时不会因类型不匹配而报错(除非是语法错误),但 fmt.Printf 在运行时处理格式不匹配时会添加错误信息。
修正后的代码示例:
如果您想输出变量 s 的类型和值,并避免额外参数错误,可以修改如下:
package main
import "fmt"
func main() {
var s = 'a' // s is of type rune (int32)
fmt.Printf("%T type of s\n", s) // 只传递一个参数,匹配格式字符串
fmt.Println(s) // 输出 rune 值 97
// 如果您想输出字符串,应使用双引号
var str = "a"
fmt.Printf("%T type of str\n", str) // 输出: string type of str
fmt.Println(str) // 输出: a
}
输出:
int32 type of s
97
string type of str
a
如果您希望 fmt.Printf 在格式不匹配时 panic 或返回错误,Go 的 fmt 包不提供此行为;它设计为在运行时处理格式错误并输出信息。对于严格的类型检查,应依赖 Go 的编译时类型系统。

