#go #unicode #rune
#Вперед #юникод #руна
Вопрос:
Похоже, что golang не поддерживает все символы Юникода для своих рун
package main
import "fmt"
func main() {
standardSuits := []rune{'♠️', '♣️', '♥️', '♦️'}
fmt.Println(standardSuits)
}
Генерирует следующую ошибку:
./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
Есть ли способ обойти это, или я должен просто смириться с этим ограничением и использовать что-то еще?
Комментарии:
1. Если вы используете
[]rune{'♠', '♣', '♥', '♦'}
, это, похоже, работает. По-видимому, U FE0F является «селектором вариантов», и может случиться так, что вам нужно разделить ваш глиф на кодовые точки, из которых он состоит.2. странно, что есть связанный с ним селектор вариантов, неудивительно, что он выходит из строя
Ответ №1:
Мне кажется, что это проблема синтаксического анализа. Вы можете использовать точки Юникода для создания этих рун, что должно дать тот же результат, что и при использовании символов.
package main
import "fmt"
func main() {
standardSuits := []rune{'u2660', 'u2663', 'u2665', 'u2666', '⌘'}
fmt.Println(standardSuits)
}
Генерирует
[9824 9827 9829 9830 8984]
Ссылка на игровую площадку: https://play.golang.org/p/jTLsbs7DM1
Я добавил дополнительную 5-ю руну, чтобы проверить, дает ли результат из кодовой точки или символа то же самое. Похоже, что это так.
Редактировать:
Не уверен, что не так с вашими символами (не просматривал их в шестнадцатеричном редакторе, их нет), но что-то в них странное.
Я также получил это для запуска, скопировав символы из Википедии:
package main
import "fmt"
func main() {
standardSuits := []rune{'♠', '♣', '♥', '♦'}
fmt.Println(standardSuits)
}
Ответ №2:
Строка юникода, которую вы используете в своем исходном коде, состоит из более чем одного «символа», но символьной константе «…» не разрешается содержать строки длиной больше единицы. Более подробно:
Если я скопирую и вставлю ваш исходный код и напечатаю шестнадцатеричный дамп, я смогу увидеть точные байты в вашем исходном коде:
>>> 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).}.|
Это показывает, например, что ваш '♠️'
кодируется с использованием шестнадцатеричных байтов e2 99 a0 ef b8 8f
. В кодировке utf-8 это соответствует двум (!) символам u2660 uFE0F
. Это не очевидно, если посмотреть на код, поскольку uFE0F
это не печатаемый символ, но Go жалуется, потому что у вас более одного символа в символьной константе. Использование '♠'
или 'u2660'
вместо этого работает, как ожидалось.