string(int)、string(int32) 和 string([]int32) 都有效,但 string([]int) 无效——这里的原理是什么?
string(int), string(int32) and string([]int32) are all valid but string([]int) is invalid - what's the rationale here?
(我使用的是 Go 1.14.6。)
以下语句都会输出字符 a
Println(string(int(97) ) )
Println(string(int32(97) ) )
Println(string([]int32{97} ) )
但是
Println(string([]int{97} ) )
会导致编译错误
cannot convert []int literal (type []int) to type string
这种行为让我感到困惑。如果它处理 string(int)
与 string(int32)
相同,为什么它处理 string([]int)
不同于 string([]int32)
?
rune
表示一个unicode代码点,是int32
的别名。因此 string([]int32{})
与 string([]rune{})
相同,后者将一段符文(类似于 string
的字符)转换为 string
。这很有用。
int
不是 int32
也不是 rune
,所以把 []int
转换成 string
应该是不合逻辑的,它是模棱两可的,所以它不是语言规范允许。
将整数转换为 string
会生成具有单个 rune
的字符串值。 Spec: Conversions:
Conversions to and from a string type
- Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer. Values outside the range of valid Unicode code points are converted to
"\uFFFD"
.
这让很多人感到困惑,因为许多人希望转换结果是字符串的(十进制)表示形式。 Go 的作者已经认识到这一点,并已采取措施在未来将其从语言中移除。在 Go 1.15 中,go vet
已经警告此类转换。 Go 1.15 release notes: Vet:
New warning for string(x)
The vet tool now warns about conversions of the form string(x)
where x
has an integer type other than rune
or byte
. Experience with Go has shown that many conversions of this form erroneously assume that string(x)
evaluates to the string representation of the integer x. It actually evaluates to a string containing the UTF-8 encoding of the value of x
. For example, string(9786)
does not evaluate to the string "9786"
; it evaluates to the string "\xe2\x98\xba"
, or "☺"
.
Code that is using string(x)
correctly can be rewritten to string(rune(x))
. Or, in some cases, calling utf8.EncodeRune(buf, x)
with a suitable byte slice buf
may be the right solution. Other code should most likely use strconv.Itoa
or fmt.Sprint
.
This new vet check is enabled by default when using go test
.
We are considering prohibiting the conversion in a future release of Go. That is, the language would change to only permit string(x)
for integer x
when the type of x
is rune
or byte
. Such a language change would not be backward compatible. We are using this vet check as a first trial step toward changing the language.
(我使用的是 Go 1.14.6。)
以下语句都会输出字符 a
Println(string(int(97) ) )
Println(string(int32(97) ) )
Println(string([]int32{97} ) )
但是
Println(string([]int{97} ) )
会导致编译错误
cannot convert []int literal (type []int) to type string
这种行为让我感到困惑。如果它处理 string(int)
与 string(int32)
相同,为什么它处理 string([]int)
不同于 string([]int32)
?
rune
表示一个unicode代码点,是int32
的别名。因此 string([]int32{})
与 string([]rune{})
相同,后者将一段符文(类似于 string
的字符)转换为 string
。这很有用。
int
不是 int32
也不是 rune
,所以把 []int
转换成 string
应该是不合逻辑的,它是模棱两可的,所以它不是语言规范允许。
将整数转换为 string
会生成具有单个 rune
的字符串值。 Spec: Conversions:
Conversions to and from a string type
- Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer. Values outside the range of valid Unicode code points are converted to
"\uFFFD"
.
这让很多人感到困惑,因为许多人希望转换结果是字符串的(十进制)表示形式。 Go 的作者已经认识到这一点,并已采取措施在未来将其从语言中移除。在 Go 1.15 中,go vet
已经警告此类转换。 Go 1.15 release notes: Vet:
New warning for string(x)
The vet tool now warns about conversions of the form
string(x)
wherex
has an integer type other thanrune
orbyte
. Experience with Go has shown that many conversions of this form erroneously assume thatstring(x)
evaluates to the string representation of the integer x. It actually evaluates to a string containing the UTF-8 encoding of the value ofx
. For example,string(9786)
does not evaluate to the string"9786"
; it evaluates to the string"\xe2\x98\xba"
, or"☺"
.Code that is using
string(x)
correctly can be rewritten tostring(rune(x))
. Or, in some cases, callingutf8.EncodeRune(buf, x)
with a suitable byte slicebuf
may be the right solution. Other code should most likely usestrconv.Itoa
orfmt.Sprint
.This new vet check is enabled by default when using
go test
.We are considering prohibiting the conversion in a future release of Go. That is, the language would change to only permit
string(x)
for integerx
when the type ofx
isrune
orbyte
. Such a language change would not be backward compatible. We are using this vet check as a first trial step toward changing the language.