Electric Coffee
Electric Coffee

Reputation: 12144

Can't use unicode character as rune

It appears that golang doesn't support all unicode characters for its runes

package main

import "fmt"

func main() {
  standardSuits := []rune{'♠️', '♣️', '♥️', '♦️'}
  fmt.Println(standardSuits)
}

Generates the following error:

./main.go:6: missing '
./main.go:6: invalid identifier character U+FE0F '️'
./main.go:6: syntax error: unexpected ️, expecting comma or }
./main.go:6: missing '
./main.go:6: invalid identifier character U+FE0F '️'
./main.go:6: missing '
./main.go:6: invalid identifier character U+FE0F '️'
./main.go:6: missing '
./main.go:6: invalid identifier character U+FE0F '️'
./main.go:6: missing '
./main.go:6: too many errors

Is there a way to get around this, or should I just live with this limitation and use something else?

Upvotes: 2

Views: 2914

Answers (2)

jochen
jochen

Reputation: 3940

The unicode string you use in your source code consist of more than one "character", but a character constant '...' is not allowed to contain strings of length greater than one. In more detail:

If I copy&paste your source code and print a hexdump, I can see the exact bytes in your source code:

>>> hexdump -C x.go
00000000  70 61 63 6b 61 67 65 20  6d 61 69 6e 0a 0a 69 6d  |package main..im|
00000010  70 6f 72 74 20 22 66 6d  74 22 0a 0a 66 75 6e 63  |port "fmt"..func|
00000020  20 6d 61 69 6e 28 29 20  7b 0a 20 20 73 74 61 6e  | main() {.  stan|
00000030  64 61 72 64 53 75 69 74  73 20 3a 3d 20 5b 5d 72  |dardSuits := []r|
00000040  75 6e 65 7b 27 e2 99 a0  ef b8 8f 27 2c 20 27 e2  |une{'......', '.|
00000050  99 a3 ef b8 8f 27 2c 20  27 e2 99 a5 ef b8 8f 27  |.....', '......'|
00000060  2c 20 27 e2 99 a6 ef b8  8f 27 7d 0a 20 20 66 6d  |, '......'}.  fm|
00000070  74 2e 50 72 69 6e 74 6c  6e 28 73 74 61 6e 64 61  |t.Println(standa|
00000080  72 64 53 75 69 74 73 29  0a 7d 0a                 |rdSuits).}.|

This shows, for example, that your '♠️' is encoded using the hex bytes e2 99 a0 ef b8 8f. In utf-8 encoding this corresponds to the two(!) characters \u2660 \uFE0F. This is not obvious by looking at the code, since \uFE0F is no printable character, but Go complains, because you have more than one character in a character constant. Using '♠' or '\u2660' instead works as expected.

Upvotes: 2

kratenko
kratenko

Reputation: 7594

It looks to me like a parsing issue. You could use the unicode points to produce that runes, which should give the same result as using the chars.

package main

import "fmt"

func main() {
  standardSuits := []rune{'\u2660', '\u2663', '\u2665', '\u2666', '⌘'}
  fmt.Println(standardSuits)
}

Generates

[9824 9827 9829 9830 8984]

Playground link: https://play.golang.org/p/jTLsbs7DM1

I added the additional 5th rune to check if the result from code point or char gives the same. Looks like it does.

Edit:

Not sure what is wrong with your chars (did not view them in a hex editor, have none around), but something is strange about them.

I also got this to run by copy pasting the chars from Wikipedia:

package main

import "fmt"

func main() {
  standardSuits := []rune{'♠', '♣', '♥', '♦'}
  fmt.Println(standardSuits)
}

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

Upvotes: 5

Related Questions