2013-10-11 4 views
74

Что такое rune в Go?Что такое руна?

Я прибегая к помощи, но Golang говорит только в одной строке: rune является псевдонимом для int32.

Но как же целые числа используются повсюду, как обменные футляры?

Ниже приведена функция swapcase. Что все <= и -?

И почему у switch нет никаких аргументов?

&& должно означать и, но что такое r <= 'z'?

func SwapRune(r rune) rune { 
    switch { 
    case 'a' <= r && r <= 'z': 
     return r - 'a' + 'A' 
    case 'A' <= r && r <= 'Z': 
     return r - 'A' + 'a' 
    default: 
     return r 
    } 
} 

Большинство из них из http://play.golang.org/p/H6wjLZj6lW

func SwapCase(str string) string { 
    return strings.Map(SwapRune, str) 
} 

Я понимаю, что это отображение rune в string так, что он может вернуть выгружена строку. Но я не понимаю, как работает rune или byte.

ответ

62

Рунические литералы представляют собой целочисленное значение (как вы уже писали). Они «сопоставляются» с их кодовым номером unicode. Например, правило буквального «а» в действительности число 97.

Therfore программы довольно много эквивалента:

package main 

import "fmt" 

func SwapRune(r rune) rune { 
    switch { 
    case 97 <= r && r <= 122: 
     return r - 32 
    case 65 <= r && r <= 90: 
     return r + 32 
    default: 
     return r 
    } 
} 

func main() { 
    fmt.Println(SwapRune('a')) 
} 

, который должен быть очевидным, если посмотреть на отображении юникода, которая идентична до ASCII в этом диапазоне. И 32 - это смещение символов верхнего и нижнего регистра. Поэтому, если вы добавите 32 в «A», вы получите «a» и наоборот.

+8

Это очевидно работает только для символов ASCII, а не для расшифрованных символов, таких как «ä», не говоря уже о более сложных случаях, таких как «ı» (U + 0131). Go имеет специальные функции для отображения в нижнем регистре, например, 'unicode.ToLower (r rune) rune'. – topskip

+2

И добавить к правильному ответу @ topskip функцию SwapCase, которая работает для всех кодовых точек, а не просто az: 'func SwapRune (r rune) rune {if unicode.IsUpper (r) {r = unicode.ToLower (r)} else {r = unicode.ToUpper (r)}; return r} ' – ANisus

+13

Руны - это значения int32. Вот и весь ответ. Они не «отображаются» _. – thwd

27

Из примечания к выпуску Go Ланг: http://golang.org/doc/go1#rune

руна имеет тип. Он занимает 32 бита и предназначен для представления UnicodeCodePoint. В качестве аналогии набор английских символов, закодированный в «ASCII», имеет 128 кодовых точек. Таким образом, он может помещаться внутри байта (8 бит). Из этого (ошибочного) допущения C обрабатываются символы как «байты» char и «строки» как «последовательность символов» char*.

Но угадайте, что. Есть много других символов, изобретенных людьми, отличными от символов «abcde ..». И есть так много, что нам нужно 32 бит для их кодирования. В golang затем string является последовательностью runes.

Пакет Unicode http://golang.org/pkg/unicode/ может дать вкус богатства проблемы.

+4

С недавним Unicode 6.3 определено более 110 000 символов. Для этого требуется, по меньшей мере, 21-битное представление каждой кодовой точки, поэтому 'rune' подобен' int32' и имеет много бит. –

+0

Вы говорите: «строка» - это последовательность «руны» - я не думаю, что это правда? [Go blog] (https://blog.golang.org/strings): «строка - это всего лишь куча байтов»; [Go lang spec] (https://golang.org/ref/spec#String_types): «Строковое значение - это (возможно, пустая) последовательность байтов» –

+0

Я все еще запутался, поэтому строка представляет собой массив рун или массив байтов? Являются ли они взаимозаменяемыми? –

13

У меня недостаточно репутации, чтобы оставить комментарий к ответе fabrizioM, поэтому мне придется публиковать его здесь.

Ответ Фабрицио в основном правилен, и он, безусловно, захватил суть проблемы - хотя есть и такое различие.

Строка NOT обязательно последовательность рун. Это оболочка над «кусочком байтов», а срез - оболочкой над массивом Go. Какая разница?

Руна обязательна для 32-битного значения, то есть последовательность рун обязательно будет иметь некоторое количество бит x * 32. Строки, являющиеся последовательностью байтов, вместо этого имеют длину x * 8 бит. Если бы все строки были на самом деле в Юникоде, эта разница не имела бы никакого эффекта. Однако, поскольку строки являются фрагментами байтов, Go может использовать ASCII или любую другую произвольную байтовую кодировку.

Строковые литералы, однако, должны быть записаны в источник, закодированный в UTF-8.

Источник информации: http://blog.golang.org/strings

8

Я пытался сохранить свой язык, просто так, что неспециалист понимает rune.

Руна - символ. Вот и все.

Это персонаж. Это персонаж любого алфавита с любого языка из любой точки мира.

Чтобы получить строку, мы используем

double-quotes "" 

ИЛИ

back-ticks `` 

Строка отличается руна. В рунах мы используем

single-quotes '' 

Теперь руна также является псевдонимом для int32 ... Uh Что?

Причина руна является псевдонимом для int32, потому что мы видим, что с схемами кодирования, такими как ниже enter image description here

каждый символ отображается на некоторое число, и таким образом это число, которое мы храним. Например, a соответствует , и когда мы храним этот номер, это просто номер, и поэтому руна является псевдонимом для int32. Но это не просто номер. Это число с 32 «нулями и единицами» или «4» байтами. (Примечание: UTF-8 представляет собой 4-байтовую схему кодирования)

Как руны относятся к строкам?

Строка представляет собой набор рун. В следующем коде:

package main 

    import (
     "fmt" 
    ) 

    func main() { 
     fmt.Println([]byte("Hello")) 
    } 

Мы пытаемся преобразовать строку в поток байтов. Выходной сигнал:

[72 101 108 108 111] 

Мы можем видеть, что каждый из байтов, составляющих эту строку, представляет собой руну.

3

Все остальные покрывали часть, связанную с рунами, поэтому я не собираюсь говорить об этом.

Однако, есть вопрос, связанный с switch, не имеющий никаких аргументов. Это просто потому, что в Golang switch без выражения является альтернативным способом выражения if/else логики. Например, пишу это:

t := time.Now() 
switch { 
case t.Hour() < 12: 
    fmt.Println("It's before noon") 
default: 
    fmt.Println("It's after noon") 
} 

такой же, как это пишу:

t := time.Now() 
if t.Hour() < 12 { 
    fmt.Println("It's before noon") 
} else { 
    fmt.Println("It's after noon") 
} 

Вы можете прочитать больше here.

 Смежные вопросы

  • Нет связанных вопросов^_^