Что такое руна?
что это rune
в Go?
я гуглил, но Голанг говорит только в одной строке: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
to string
, так что он может вернуть местами строки. Но я не понимаю, как именно!--2--> или byte
здесь работает.
7 ответов
Руна литералы-это просто целочисленное значение (как вы написали). Они "сопоставляются" с их кодовой точкой Unicode. Например, рунный литерал 'a'
на самом деле число 97
.
поэтому ваша программа в значительной степени эквивалентна:
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'))
}
это должно быть очевидно, если вы посмотрите на отображение Unicode, который идентичен ASCII в этом диапазоне. Кроме того, 32 фактически является смещением между прописными буквами и нижний регистр кода символа. Добавить 32
to 'A'
вы получаете 'a'
и наоборот.
С ходу Лэнг выпуске: http://golang.org/doc/go1#rune
руна-это тип. Он занимает 32bit и предназначен для представления Unicode кода.
В качестве аналогии набор английских символов, закодированный в "ASCII", имеет 128 кодовых точек. Таким образом может поместиться в байте (8бит). Из этого (ошибочного) предположения C рассматривал символы как "байты"char
и "строки" как "последовательность символов"char*
.
но угадай, что. Есть много других символов, изобретенных людьми, кроме abcde..' атрибутика. И их так много, что нам нужно 32 бит для их кодирования.
в golang потом string
- это последовательность bytes
. Однако, поскольку несколько байтов могут представлять кодовую точку руны, строковое значение также может содержать руны. Таким образом, он может быть преобразован в []rune
, или наоборот.
пакет unicode http://golang.org/pkg/unicode/ смогите дать вкус богатства вызова.
У меня недостаточно репутации, чтобы опубликовать комментарий к ответу фабрициома, поэтому мне придется опубликовать его здесь.
строка не обязательно последовательность рун. Это обертка над "ломтиком байтов", ломтик, являющийся оберткой над массивом Go. Какая разница?
A руна обязательно является 32-разрядным значением, то есть последовательность рун обязательно будет иметь некоторое количество бит x*32. Строки, будучи последовательностью байтов, вместо этого имеют длину x * 8 бит. Если бы все строки были на самом деле в Unicode, это различие не имело бы никакого влияния. Поскольку строки являются срезами байтов, Go может использовать ASCII или любую другую произвольную байтовую кодировку.
строковые литералы, однако, должны быть записаны в источник, закодированный в UTF-8.
источник информация: http://blog.golang.org/strings
Я старался держать свой язык простым, чтобы непрофессионал понимал rune
.
руна-это символ. Вот и все.
это один персонаж. Это символ из любого алфавита из любого языка из любой точки мира.
получить строку, мы используем
double-quotes ""
или
back-ticks ``
строка отличается от руны. В рунах мы используем
single-quotes ''
теперь руна также является псевдонимом для int32
...Что?
причиной руна-это псевдоним int32
потому что мы видим, что со схемами кодирования, такими как ниже
каждый символ сопоставляется некоторое число, и это число, которое мы храним. Например, a карты 97 и когда мы храним это число, это просто число, и поэтому руна-это псевдоним для int32. но это не просто любое число. Это число с 32 ' нулями и те' или '4' байт. (Примечание: UTF-8-это 4-байтовая схема кодирования)
как руны относятся к строкам?
строка-это набор рун. В следующем коде:
package main
import (
"fmt"
)
func main() {
fmt.Println([]byte("Hello"))
}
мы пытаемся преобразовать строку в поток байтов. Вывод:
[72 101 108 108 111]
мы видим, что каждый из байтов, составляющих эту строку, является руной.
все остальные рассмотрели часть, связанную с рунами, поэтому я не собираюсь говорить об этом.
однако, есть также вопрос, связанный с 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")
}
вы можете подробнее здесь.
(появилось ощущение, что выше ответы все еще не указали различия и отношения между string
и []rune
очень ясно, поэтому я бы попытался добавить еще один ответ с примером.)
As @Strangework
Вместо ответа спросил:string
и []rune
отличаются.
различия string
& []rune
:
-
string value
- это байтовый срез только для чтения. И строковый литерал кодируется в utf-8. Каждая буква вstring
на самом деле принимает 1 ~ 3 байт, в то время как каждыйrune
принимает 4 байт - на
string
, иlen()
и индекс основаны на байтах. - на
[]rune
, иlen()
и индекс основаны на руне (или int32).
отношения string
& []rune
:
- при конвертации из
string
to[]rune
, каждый символ utf-8 в этой строке становитсяrune
. - аналогично, в обратном преобразовании, когда конвертировать из
[]rune
tostring
, каждыйrune
становится символом utf-8 вstring
.
советы:
- можно конвертировать между
string
и[]rune
, но все же они разные, как по типу , так и по общему размеру.
(я бы добавил пример, чтобы показать, что больше очевидно.)
код
string_rune_compare.go:
// string & rune compare,
package main
import "fmt"
// string & rune compare,
func stringAndRuneCompare() {
// string,
s := "hello你好"
fmt.Printf("%s, type: %T, len: %d\n", s, s, len(s))
fmt.Printf("s[%d]: %v, type: %T\n", 0, s[0], s[0])
li := len(s) - 1 // last index,
fmt.Printf("s[%d]: %v, type: %T\n\n", li, s[li], s[li])
// []rune
rs := []rune(s)
fmt.Printf("%v, type: %T, len: %d\n", rs, rs, len(rs))
}
func main() {
stringAndRuneCompare()
}
выполнить:
запустите string_rune_compare.go
выход:
hello你好, type: string, len: 11
s[0]: 104, type: uint8
s[10]: 189, type: uint8
[104 101 108 108 111 20320 22909], type: []int32, len: 7
объяснение:
-
строка
hello你好
имеет длину 11, потому что первые 5 символов каждый принимает только 1 байт, в то время как последние 2 китайских символа каждый занимает 3 байта.- таким образом,
total bytes = 5 * 1 + 2 * 3 = 11
- с
len()
on строка основана на байтах, таким образом, первая строка напечатанаlen: 11
- поскольку индекс на строке также основан на байтах, то следующие 2 строки печатают значения типа
uint8
(посколькуbyte
является псевдонимом типаuint8
, в go).
- таким образом,
-
при преобразовании
string
to[]rune
, он нашел 7 символов utf8, таким образом, 7 руна.- с
len()
on[]rune
основан на руне, таким образом, последняя строка напечатанаlen: 7
. - если вы используете
[]rune
через индекс, он получит доступ к базе на руне.
Поскольку каждая руна из символа utf8 в исходной строке, таким образом, вы также можете сказать обаlen()
и индекс операции на[]rune
основаны на символах utf8.
- с
руна-это значение int32, и поэтому это тип Go, который используется для представления кодовой точки Unicode. Кодовая точка Юникода или кодовая позиция-это числовое значение, которое обычно используется для представления отдельных символов Юникода;