【发布时间】:2017-08-22 23:28:01
【问题描述】:
给定以下输入:
intVal := 2612
strVal := "2612"
将关联的 unicode 值映射为字符串的机制是什么。
例如下面的代码打印“☒”
fmt.Println("\u2612")
但以下不起作用:
fmt.Println("\\u" + strVal)
我研究了符文、strconv 和 unicode/utf8,但找不到合适的转换策略。
【问题讨论】:
给定以下输入:
intVal := 2612
strVal := "2612"
将关联的 unicode 值映射为字符串的机制是什么。
例如下面的代码打印“☒”
fmt.Println("\u2612")
但以下不起作用:
fmt.Println("\\u" + strVal)
我研究了符文、strconv 和 unicode/utf8,但找不到合适的转换策略。
【问题讨论】:
2612不是unicode rune的整数值,\u2612的整数值是9746。字符串"2612"是符文的十六进制值,所以将其解析为十六进制数并转换为rune。
i, err := strconv.ParseInt(strVal, 16, 32)
if err != nil {
log.Fatal(err)
}
r := rune(i)
fmt.Println(string(r))
【讨论】:
strconv.ParseInt() 返回一个类型为 uint64 的值,无论指定哪个位大小,因此在一个不太玩具的示例中,可能需要将结果类型转换为 @987654330 @.
这个有效:
fmt.Println("\u2612")
因为在源代码中指定了interpreted string literal,编译器将取消引用(解释)它。 不是处理此取消引用的 fmt 包。
这不起作用:
fmt.Println("\\u" + strVal)
因为再次使用了一个解释字符串文字,它将被解析为string值\u,然后它将与局部变量strVal的值连接起来,即2612,所以最终string 的值将是 \u2612。但这不是解释的字符串文字,这是“最终”结果。这不会被进一步处理/取消引用。
除了 JimB 的回答之外,您还可以使用 strconv.Unquote() 进行类似于编译器所做的取消引用。
看这个例子:
// The original that works:
s := "\u2612"
fmt.Println(s, []byte(s))
// Using strconv.Unquote():
strVal := "2612"
s2, err := strconv.Unquote(`"\u` + strVal + `"`)
fmt.Println(s2, []byte(s2), err)
fmt.Println(s == s2)
输出(在Go Playground 上试试):
☒ [226 152 146]
☒ [226 152 146] <nil>
true
这里要注意的一点:我们想用strconv.Unquote() 取消引用\u2612 文本,但是Unquote() 要求将要取消引用的字符串放在引号中(“取消引用将 s 解释为单引号、双引号或反引号 Go 字符串字面量..."),这就是为什么我们用引号将其前置和后置。
【讨论】: