【问题标题】:Why is "int" convertible to "string"?为什么“int”可以转换为“string”?
【发布时间】:2021-04-26 20:11:42
【问题描述】:

这个例子展示了 int 类型可以转换为 string 类型。但我的问题是为什么?

package main

import (
    "fmt"
    "reflect"
)

func main() {
    it := reflect.TypeOf(42)
    st := reflect.TypeOf("hello")

    fmt.Printf("%q is convertible to %q: %v\n",
        it, st, it.ConvertibleTo(st))
        // OUTPUT: "int" is convertible to "string": true

    fmt.Printf("%q is convertible to %q: %v\n",
        st, it, st.ConvertibleTo(it))
        // OUTPUT: "string" is convertible to "int": false
}

如果我错了,请纠正我。但是这不应该是false吗?

reflect.TypeOf(int(0)).ConvertibleTo(reflect.TypeOf("string"))

【问题讨论】:

  • 正如@Hymns 所指出的,intstring 的转换是一种原始转换——可能不是你所期望的。如果您想要特定 intstring 表示 - 使用 strconv.Itoa(x)fmt.Sprint(x)
  • 作为记录,有一个 active proposal 不允许这样做,因为此转换的潜在奇怪/令人困惑的行为

标签: go reflect


【解决方案1】:

为什么“int”可以转换为“string”?

因为语言规范1是这么说的:

将有符号或无符号整数值转换为字符串类型会生成一个包含整数的 UTF-8 表示形式的字符串。

1:Conversions, section "Conversions to and from a string type"

【讨论】:

    【解决方案2】:

    intstring 转换的含义是创建一个具有一个 unicode 字符的字符串:由该 int 的数字标识的字符。

    看这个例子:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        fmt.Println(string(int(1234)))
    }
    

    On playground

    输出:

    Ӓ
    

    这是因为 Unicode 字符 1234(或更标准的表示形式中的 U+04D2)是:

    西里尔大写字母 A 带分音符


    您还会注意到,在 Go 操场上,您会看到来自 go vet 的红色输出,它是查找 Go 程序中常见问题的工具。输出警告:

    ./prog.go:8:14:从 int 到 string 的转换产生一个由一个符文组成的字符串,而不是一串数字(你是说 fmt.Sprint(x) 吗?)

    这是因为这种转换比较奇怪,不常用,所以go vet基本默认认为是潜在的错误。

    【讨论】:

    • 感谢您的解释。我对此进行了实验。我在一个函数中使用它,我只在值可转换的情况下进行转换,例如 float 到 int,int 到 float 等。将 int 转换为字符串对我来说是违反直觉的,int 到 rune 是可以的,尽管 rune 是一个别名整数32。如果我想从 int 或 int 从 string 中提取字符串,则有来自 strconv 包的函数。无论如何,我认为这是一个语言决定。
    • strconv 中的转换功能与string(someint) 中的转换功能不同。
    猜你喜欢
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多