英文:
Golang convert integer to unicode character
问题
给定以下输入:
intVal := 2612
strVal := "2612"
有什么机制可以将其映射为关联的 Unicode 值作为字符串。
例如,以下代码将打印出 "☒":
fmt.Println("\u2612")
但以下代码无法正常工作:
fmt.Println("\\u" + strVal)
我研究了 runes、strconv
和 unicode/utf8
,但未能找到合适的转换策略。
英文:
Given the following input:
intVal := 2612
strVal := "2612"
What is a mechanism for mapping to the associated unicode value as a string.
For example, the following code prints "☒"
fmt.Println("\u2612")
But the following does not work:
fmt.Println("\\u" + strVal)
I researched runes, strconv
, and unicode/utf8
but was unable to find a suitable conversion strategy.
答案1
得分: 5
2612
不是Unicode符文的整数值,\u2612
的整数值是9746
。字符串"2612"
是符文的十六进制值,因此将其解析为十六进制数并转换为rune
类型。
i, err := strconv.ParseInt(strVal, 16, 32)
if err != nil {
log.Fatal(err)
}
r := rune(i)
fmt.Println(string(r))
链接:https://play.golang.org/p/t_e6AfbKQq
英文:
2612
is not the integer value of the unicode rune, the integer value of \u2612
is 9746
. The string "2612"
is the hex value of the rune, so parse it as a hex number and convert it to a rune
.
i, err := strconv.ParseInt(strVal, 16, 32)
if err != nil {
log.Fatal(err)
}
r := rune(i)
fmt.Println(string(r))
答案2
得分: 3
这个可以工作:
fmt.Println("\u2612")
因为源代码中指定了一个解释的字符串字面量,编译器会对其进行解引用(解释)。这不是fmt
包处理这个解引用。
这个不行:
fmt.Println("\\u" + strVal)
因为再次使用了一个解释的字符串字面量,它将被解析为一个string
值\u
,然后与局部变量strVal
的值2612
连接在一起,所以最终的string
值将是\u2612
。但这不是一个解释的字符串字面量,这是“最终”的结果。这不会被进一步处理/解引用。
除了JimB的答案之外,你还可以使用strconv.Unquote()
,它执行类似于编译器的解引用操作。
看看这个例子:
// 原始的可以工作的代码:
s := "\u2612"
fmt.Println(s, []byte(s))
// 使用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()
要求要解引用的字符串要用引号括起来(“Unquote interprets s as a single-quoted, double-quoted, or backquoted Go string literal...”),这就是为什么我们在前后加上引号的原因。
英文:
This one works:
fmt.Println("\u2612")
Because an interpreted string literal is specified in the source code, and the compiler will unquote (interpret) it. It is not the fmt
package that processes this unquoting.
This doesn't work:
fmt.Println("\\u" + strVal)
Because again an interpreted string literal is used which will be resolved to a string
value \u
, and then it will be concatenated with the value of the local variable strVal
which is 2612
, so the final string
value will be \u2612
. But this is not an interpreted string literal, this is the "final" result. This won't be processed / unquoted further.
Alternatively to JimB's answer, you may also use strconv.Unquote()
which does an unquoting similar to what the compiler does.
See this example:
// 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)
Output (try it on the Go Playground):
☒ [226 152 146]
☒ [226 152 146] <nil>
true
Something to note here: We want to unquote the \u2612
text by strconv.Unquote()
, but Unquote()
requires that the string to be unquoted to be in quotes ("Unquote interprets s as a single-quoted, double-quoted, or backquoted Go string literal..."), that's why we pre- and postpended it with a quotation mark.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论