Golang将整数转换为Unicode字符

huangapple go评论168阅读模式
英文:

Golang convert integer to unicode character

问题

给定以下输入:

intVal := 2612
strVal := "2612"

有什么机制可以将其映射为关联的 Unicode 值作为字符串。

例如,以下代码将打印出 "☒":

fmt.Println("\u2612")

但以下代码无法正常工作:

fmt.Println("\\u" + strVal)

我研究了 runes、strconvunicode/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))

https://play.golang.org/p/t_e6AfbKQq

答案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(&quot;\u2612&quot;)

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(&quot;\\u&quot; + 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 := &quot;\u2612&quot;
fmt.Println(s, []byte(s))

// Using strconv.Unquote():
strVal := &quot;2612&quot;
s2, err := strconv.Unquote(`&quot;\u` + strVal + `&quot;`)
fmt.Println(s2, []byte(s2), err)
fmt.Println(s == s2)

Output (try it on the Go Playground):

☒ [226 152 146]
☒ [226 152 146] &lt;nil&gt;
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.

huangapple
  • 本文由 发表于 2017年3月29日 20:54:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/43094132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定