很多人第一次看到 fmt.Println(string(65)),都会下意识认为输出应该是 65。但这正是这道 Go 面试题容易“坑”人的地方:它考的不是数字转字符串的日常经验,而是 Go 对字符和字符串转换的明确语义。顺着这个例子看下去,你可以分清 string(int)、rune 和数字字符串之间的区别,也能判断什么时候该用 strconv.Itoa 或 fmt.Sprintf。
这段代码到底输出什么
先看题目本身:
package main
import "fmt"
func main() {
fmt.Println(string(65))
}
这段代码的输出不是 65,也不会报编译错误,而是:
A
原因在于,Go 里的 string() 在接收整数值做转换时,并不是把这个整数转成十进制文本,而是把它解释成一个 Unicode 代码点,再生成对应字符的字符串。
数值 65 对应的大写字母 A,因此 string(65) 的结果就是只包含一个字符的字符串 "A"。
为什么会是 A,而不是 65
这背后对应的是 Go 的一条很重要的类型转换规则:string(整数) 表示按字符编码构造字符串,不是按十进制数字形式格式化输出。
换句话说,65 在这里扮演的不是“一个待打印的数字”,而是“一个字符位置编号”。Go 会拿这个值去查对应的 Unicode code point,然后返回那个字符。
由于 65 同时也是 ASCII 中 A 的编码,所以这里最终得到的是 A。这也是为什么不少刚接触 Go 的开发者会误判:他们把“类型转换”和“格式化成数字字符串”混成了一件事,但在 Go 中,这两件事是分开的。
如果想得到字符串 65,正确写法是什么
如果你的目标确实是把整数 65 变成字符串 "65",那就应该使用专门的数字格式化方法,而不是直接写 string(65)。

方式一:使用 strconv.Itoa
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.Itoa(65)) // 输出:"65"
}
这是最直接、也最常见的整数转字符串方式。
方式二:使用 fmt.Sprintf
package main
import "fmt"
func main() {
fmt.Println(fmt.Sprintf("%d", 65)) // 输出:"65"
}
当你已经在使用格式化输出,或者需要拼接更复杂的文本时,fmt.Sprintf 也很合适。

简单区分的话:
string(65):按字符编码取对应字符strconv.Itoa(65):转成十进制数字字符串fmt.Sprintf("%d", 65):按格式化规则生成数字字符串
这种混用为什么容易出 bug
这个问题看起来只是一个小知识点,但在真实代码里很容易埋坑。比如处理用户 ID、订单编号、状态码、业务编码时,如果本来需要的是字符串形式的数字,却误用了 string(),程序依然能编译通过,但结果会悄悄变成一个字符,问题往往要到数据落库、日志排查或接口联调时才暴露出来。
Go 工具链也注意到了这一类误用。用 go vet 检查代码时,如果发现你把整数直接转成字符串,通常会给出类似提示:
conversion from int to string yields a string of one rune,
not a string of digits (did you mean fmt.Sprint(x)?)
这段提示的重点很明确:从 int 到 string,得到的是“一个 rune 对应的字符串”,不是“数字的字符串表示”。如果你的本意是得到数字文本,应该考虑 fmt.Sprint(x)、strconv.Itoa 等方法。
因此,这类问题最值得警惕的地方不在于它会不会报错,而在于它很可能“不报错但结果不对”。
再往里看:rune、字符和字符串是什么关系
要彻底理解这个现象,需要把 Go 里的字符和字符串区分开。
在 Go 中,rune 是 int32 的别名,用来表示一个 Unicode 代码点;而字符串则是字节序列。也就是说,字符本质上是一个数值,字符串则是一段编码后的内容。
例如下面这段代码:
a := 'A'
fmt.Printf("%T, %dn", a, a) // 输出:int32, 65
这里的 'A' 不是字符串,而是字符字面量。它对应的值是 65,类型表现为 int32,也就是 rune 的底层形式。
而 "A" 才是真正的字符串字面量。于是你就能看懂前面的行为了:
'A'代表字符,其数值是65string(65)是把代码点65转成字符串- 结果自然就是
"A"
这也是 Go 在字符处理上保持一致性的地方:整数、rune、字符串各自有明确语义,转换规则并不含糊。
记住这一条就不容易再答错
这道题的关键不在“记住答案是 A”,而在于记住背后的规则:
string(整数)会把整数当作 Unicode 代码点,得到对应字符strconv.Itoa(整数)才是把整数转成十进制字符串- 涉及 ID、编码、数字文本时,要特别留意自己需要的是字符还是数字字符串
所以,string(65) 输出 A,并不是 Go “特殊处理”了这个数字,而是它一直都在遵守统一的转换语义。面试里答对这道题不难,真正重要的是在写业务代码时别把这两类转换混在一起。









