O que é uma rune
in Go?
Eu tenho pesquisado no Google, mas Golang apenas diz em uma linha: rune
é um apelido paraint32
.
Mas como os números inteiros são usados ao redor, como trocar casos?
A seguir, uma caixa de troca de funções. O que é tudo <=
e -
?
E por que não switch
tem argumentos?
&&
deve significar e mas o que é 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
}
}
A maioria deles é de http://play.golang.org/p/H6wjLZj6lW
func SwapCase(str string) string {
return strings.Map(SwapRune, str)
}
Eu entendo que isso está mapeando rune
para string
que ele possa retornar a string trocada. Mas eu não entendo como exatamente rune
ou byte
funciona aqui.
[]rune
pode ser definido como um tipo booleano, numérico ou de sequência. Consulte stackoverflow.com/a/62739051/12817546 .Respostas:
Literais de runa são apenas valores inteiros de 32 bits ( no entanto, são constantes não tipadas, para que seu tipo possa ser alterado ). Eles representam pontos de código unicode. Por exemplo, o literal da runa
'a'
é realmente o número97
.Portanto, seu programa é praticamente equivalente a:
Deveria ser óbvio, se você observar o mapeamento Unicode, que é idêntico ao ASCII nesse intervalo. Além disso, 32 é de fato o deslocamento entre o ponto de código em maiúsculas e minúsculas do caractere. Então, adicionando
32
a'A'
, você obtém'a'
e vice-versa.fonte
unicode.ToLower(r rune) rune
.func SwapRune(r rune) rune { if unicode.IsUpper(r) { r = unicode.ToLower(r) } else { r = unicode.ToUpper(r) }; return r }
Nas notas de versão do Go lang: http://golang.org/doc/go1#rune
Rune é um tipo. Ocupa 32 bits e deve representar um CodePoint Unicode . Como analogia, o conjunto de caracteres em inglês codificado em 'ASCII' possui 128 pontos de código. Assim, é capaz de caber dentro de um byte (8 bits). A partir dessa suposição (incorreta), C tratava caracteres como 'bytes' e 'strings' como 'sequência de caracteres' .
char
char*
Mas adivinhem. Existem muitos outros símbolos inventados por humanos além dos símbolos 'abcde ...'. E há tantos que precisamos de 32 bits para codificá-los.
Em golang, então a
string
é uma sequência debytes
. No entanto, como vários bytes podem representar um ponto de código da runa, um valor de sequência também pode conter runas. Portanto, pode ser convertido em a[]rune
ou vice-versa.O pacote unicode http://golang.org/pkg/unicode/ pode dar uma amostra da riqueza do desafio.
fonte
rune
é comoint32
e possui muitos bits.string
é uma sequência derune
s" - não acho que seja verdade? Vá ao blog : "uma string é apenas um monte de bytes"; Go lang especificação : "O valor de uma string é uma sequência (possivelmente vazio) de bytes"not bytes
. Então, você pode dizer: "As seqüências de caracteres são compostas de runas e runas de bytes". Algo assim. Então novamente. não é completamente verdade.Tentei manter minha linguagem simples para que um leigo entendesse
rune
.Uma runa é um personagem. É isso aí.
É um único personagem. É um personagem de qualquer alfabeto, de qualquer idioma, de qualquer lugar do mundo.
Para obter uma string, usamos
OU
Uma string é diferente de uma runa. Nas runas usamos
Agora uma runa também é um pseudônimo para
int32
... O quê?A razão pela qual rune é um alias
int32
é porque vemos que, com esquemas de codificação como abaixocada personagem é mapeado para algum número e, portanto, é o número que estamos armazenando. Por exemplo, um mapeia para 97 e quando armazenamos esse número, é apenas o número e, assim, runa é um alias para int32. Mas não é apenas qualquer número. É um número com 32 'zeros e uns' ou '4' bytes. (Nota: UTF-8 é um esquema de codificação de 4 bytes)
Como as runas se relacionam com as strings?
Uma string é uma coleção de runas. No código a seguir:
Tentamos converter uma string em um fluxo de bytes. A saída é:
Podemos ver que cada um dos bytes que compõem essa string é uma runa.
fonte
A string is not a collection of runes
isso não está correto estritamente falando. Em vez disso, string é uma fatia de bytes, codificada com utf8. Cada caractere na string leva de 1 a 3 bytes, enquanto cada runa ocupa 4 bytes. Você pode converter entre string e [] runa, mas elas são diferentes.Eu não tenho reputação suficiente para postar um comentário na resposta de fabrizioM , então terei que postá-lo aqui.
A resposta de Fabrizio está amplamente correta e ele certamente capturou a essência do problema - embora haja uma distinção que deve ser feita.
Uma string NÃO é necessariamente uma sequência de runas. É um invólucro sobre uma 'fatia de bytes', uma fatia sendo um wrapper sobre uma matriz Go. Que diferença isso faz?
Um tipo de runa é necessariamente um valor de 32 bits, o que significa que uma sequência de valores de tipos de runas necessariamente terá algum número de bits x * 32. As strings, sendo uma sequência de bytes, têm um comprimento de x * 8 bits. Se todas as strings estivessem realmente em Unicode, essa diferença não teria impacto. Como as seqüências de caracteres são fatias de bytes , o Go pode usar ASCII ou qualquer outra codificação de bytes arbitrária.
Literais de string, no entanto, precisam ser gravados na fonte codificada em UTF-8.
Fonte de informação: http://blog.golang.org/strings
fonte
(Tenho a sensação de que as respostas acima ainda não indicam as diferenças e as relações entre
string
e[]rune
muito claramente, por isso, tentaria adicionar outra resposta com exemplo.)Como
@Strangework
a resposta disse,string
e[]rune
são silenciosos diferentes.Diferenças -
string
&[]rune
:string value
é uma fatia de bytes somente leitura. E, uma string literal é codificada em utf-8. Cada char nastring
verdade leva de 1 a 3 bytes, enquanto cada umrune
leva 4 bytesstring
, bothlen()
e index são baseados em bytes.[]rune
, bothlen()
e index são baseados em runa (ou int32).Relacionamentos -
string
&[]rune
:string
para[]rune
, cada caractere utf-8 nessa sequência se torna arune
.[]rune
parastring
, cadarune
um se torna um caracter utf-8 nostring
.Dicas:
string
e[]rune
, mas eles ainda são diferentes, tanto no tipo quanto no tamanho geral.(Eu adicionaria um exemplo para mostrar isso mais claramente.)
Código
string_rune_compare.go:
Executar:
Resultado:
Explicação:
A cadeia
hello你好
tem comprimento 11, porque os primeiros 5 caracteres cada um levam apenas 1 byte, enquanto os últimos 2 caracteres chineses levam 3 bytes.total bytes = 5 * 1 + 2 * 3 = 11
len()
a string é baseada em bytes, a primeira linha impressalen: 11
uint8
(já quebyte
é um tipo de alias deuint8
, em movimento).Ao converter
string
para[]rune
, ele encontrou 7 utf8 chars, assim 7 runas.len()
on[]rune
é baseado em runa, a última linha é impressalen: 7
.[]rune
via índice, ele acessará a base na runa.Como cada runa é de um utf8 char na string original, também é possível dizer que a
len()
operação de ambos e o índice[]rune
são baseadas em utf8 chars.fonte
fmt.Println("hello你好"[0])
isso, retorna o ponto de código UTF-8 real em vez de bytes.s[0]
, ele imprimes[0]: 104, type: uint8
, o tipo éuint8
, significa que é um byte. Para caracteres ASCII comoh
utf-8, use também um byte único para representá-lo; portanto, o ponto de código é o mesmo que o byte único; mas para caracteres chineses como你
, use 3 bytes.Todo mundo já cobriu a parte relacionada às runas, então não vou falar sobre isso.
No entanto, há também uma pergunta relacionada a
switch
não ter argumentos. Isso ocorre simplesmente porque em Golang,switch
sem uma expressão, é uma maneira alternativa de expressar a lógica if / else. Por exemplo, escrevendo isso:é o mesmo que escrever isso:
Você pode ler mais aqui .
fonte
Uma runa é um valor int32 e, portanto, é um tipo de Go usado para representar um ponto de código Unicode. Um ponto de código Unicode ou uma posição de código é um valor numérico geralmente usado para representar caracteres Unicode únicos;
fonte