Que es un rune
en Go?
He estado buscando en Google pero Golang solo dice en una línea: rune
es un alias paraint32
.
Pero, ¿cómo es que los enteros se usan por todas partes como casos de intercambio?
El siguiente es un intercambio de funciones. ¿Qué es todo el <=
y-
?
¿Y por qué no switch
tiene ningún argumento?
&&
debería significar y ¿pero qué es 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
}
}
La mayoría de ellos son de http://play.golang.org/p/H6wjLZj6lW
func SwapCase(str string) string {
return strings.Map(SwapRune, str)
}
Entiendo que esto es mapeo rune
para string
que pueda devolver la cadena intercambiada. Pero no entiendo cómo exactamente rune
o byte
funciona aquí.
[]rune
se puede establecer en un tipo booleano, numérico o de cadena. Ver stackoverflow.com/a/62739051/12817546 .Respuestas:
Los literales de runas son solo valores enteros de 32 bits ( sin embargo, son constantes sin tipo, por lo que su tipo puede cambiar ). Representan puntos de código unicode. Por ejemplo, el literal de la runa
'a'
es en realidad el número97
.Por lo tanto, su programa es más o menos equivalente a:
Debería ser obvio, si tuviera que mirar la asignación Unicode, que es idéntica a ASCII en ese rango. Además, 32 es de hecho el desplazamiento entre el punto de código en mayúsculas y minúsculas del carácter. Entonces, agregando
32
a'A'
, obtienes'a'
y viceversa.fuente
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 }
De las notas de la versión de Go Lang: http://golang.org/doc/go1#rune
La runa es un tipo. Ocupa 32 bits y está destinado a representar un CodePoint Unicode . Como analogía, el conjunto de caracteres en inglés codificado en 'ASCII' tiene 128 puntos de código. Por lo tanto, puede caber dentro de un byte (8 bits). De esta suposición (errónea) C trató los caracteres como 'bytes' y 'cadenas' como una 'secuencia de caracteres' .
char
char*
Pero adivina que. Hay muchos otros símbolos inventados por los humanos además de los símbolos 'abcde ...'. Y hay tantos que necesitamos 32 bits para codificarlos.
En golang, a
string
es una secuencia debytes
. Sin embargo, dado que varios bytes pueden representar un punto de código de runas, un valor de cadena también puede contener runas. Por lo tanto, se puede convertir a a[]rune
, o viceversa.El paquete unicode http://golang.org/pkg/unicode/ puede dar una idea de la riqueza del desafío.
fuente
rune
es comoint32
y tiene muchos bits.string
es una secuencia derune
s". ¿No creo que sea cierto? Ir al blog : "una cadena es solo un montón de bytes"; Ir a la especificación lang : "Un valor de cadena es una secuencia (posiblemente vacía) de bytes"not bytes
. Entonces, podría decir: "Las cadenas están formadas por runas y las runas formadas por bytes" Algo así. Entonces otra vez. No es del todo cierto.He tratado de mantener mi lenguaje simple para que un laico entienda
rune
.Una runa es un personaje. Eso es.
Es un solo personaje. Es un personaje de cualquier alfabeto de cualquier idioma desde cualquier parte del mundo.
Para obtener una cadena usamos
O
Una cadena es diferente a una runa. En runas usamos
Ahora una runa es también un alias para
int32
... ¿Qué?La razón por la que las runas son un alias
int32
es porque vemos que con esquemas de codificación como los siguientescada personaje se asigna a algún número y, por lo tanto, es el número que estamos almacenando. Por ejemplo, un mapeo a 97 y cuando almacenamos ese número es solo el número y así es como la runa es un alias para int32. Pero no es un número cualquiera. Es un número con 32 'ceros y unos' o '4' bytes. (Nota: UTF-8 es un esquema de codificación de 4 bytes)
¿Cómo se relacionan las runas con las cuerdas?
Una cadena es una colección de runas. En el siguiente código:
Intentamos convertir una cadena en una secuencia de bytes. El resultado es:
Podemos ver que cada uno de los bytes que conforman esa cadena es una runa.
fuente
A string is not a collection of runes
Esto no es correcto estrictamente hablando. En cambio, la cadena es un segmento de bytes, codificado con utf8. Cada char en cadena realmente toma 1 ~ 3 bytes, mientras que cada runa toma 4 bytes. Puede convertir entre string y [] rune, pero son diferentes.No tengo suficiente reputación para publicar un comentario a la respuesta de fabrizioM , por lo que tendré que publicarlo aquí.
La respuesta de Fabrizio es en gran medida correcta, y ciertamente captó la esencia del problema, aunque hay que hacer una distinción.
Una cadena NO es necesariamente una secuencia de runas. Es un contenedor sobre un 'segmento de bytes', un segmento es un contenedor sobre una matriz Go. ¿Qué diferencia hace esto?
Un tipo de runas es necesariamente un valor de 32 bits, lo que significa que una secuencia de valores de tipos de runas necesariamente tendría algún número de bits x * 32. Las cadenas, que son una secuencia de bytes, tienen una longitud de x * 8 bits. Si todas las cadenas estuvieran realmente en Unicode, esta diferencia no tendría ningún impacto. Sin embargo, dado que las cadenas son segmentos de bytes , Go puede usar ASCII o cualquier otra codificación de bytes arbitraria.
Sin embargo, los literales de cadena deben escribirse en la fuente codificada en UTF-8.
Fuente de información: http://blog.golang.org/strings
fuente
(Tenía la sensación de que las respuestas anteriores todavía no indicaban las diferencias y las relaciones entre ellas
string
y[]rune
muy claramente, por lo que trataría de agregar otra respuesta con un ejemplo).Como
@Strangework
decía la respuesta,string
y[]rune
son silenciosamente diferentes.Diferencias -
string
&[]rune
:string value
es un segmento de byte de solo lectura. Y, un literal de cadena está codificado en utf-8. Cada char enstring
realidad toma 1 ~ 3 bytes, mientras que cadarune
toma 4 bytesstring
, amboslen()
y el índice se basan en bytes.[]rune
, amboslen()
y el índice se basan en runas (o int32).Relaciones -
string
y[]rune
:string
a[]rune
, cada carácter utf-8 en esa cadena se convierte en arune
.[]rune
astring
, cada uno serune
convierte en un carácter utf-8 en elstring
.Consejos:
string
y[]rune
, pero aún así son diferentes, tanto en tipo como en tamaño general.(Añadiría un ejemplo para mostrarlo más claramente).
Código
string_rune_compare.go:
Ejecutar:
Salida:
Explicación:
La cadena
hello你好
tiene una longitud de 11, porque los primeros 5 caracteres toman cada uno solo 1 byte, mientras que los últimos 2 caracteres chinos toman 3 bytes cada uno.total bytes = 5 * 1 + 2 * 3 = 11
len()
cadena se basa en bytes, la primera línea impresalen: 11
uint8
(ya quebyte
es un tipo de aliasuint8
, in go).Al convertir el
string
a[]rune
, encontró 7 caracteres utf8, por lo tanto, 7 runas.len()
en[]rune
se basa en la runa, por lo tanto, la última línea impresalen: 7
.[]rune
través del índice, accederá a la base en runas.Dado que cada runa es de un carácter utf8 en la cadena original, también puede decir que tanto la
len()
operación de índice como la[]rune
basada se basan en caracteres utf8.fuente
fmt.Println("hello你好"[0])
, devuelve el punto de código UTF-8 real en lugar de bytes.s[0]
se imprimes[0]: 104, type: uint8
, el tipo esuint8
, significa que es un byte. Para caracteres ASCII comoh
utf-8 también use un solo byte para representarlo, por lo que el punto de código es el mismo que el byte único; pero para caracteres chinos como你
, usa 3 bytes.Todos los demás han cubierto la parte relacionada con las runas, así que no voy a hablar de eso.
Sin embargo, también hay una pregunta relacionada con
switch
no tener ningún argumento. Esto es simplemente porque en Golang,switch
sin una expresión es una forma alternativa de expresar lógica if / else. Por ejemplo, escribiendo esto:es lo mismo que escribir esto:
Puedes leer más aquí .
fuente
Una runa es un valor int32 y, por lo tanto, es un tipo Go que se usa para representar un punto de código Unicode. Un punto de código Unicode o posición de código es un valor numérico que generalmente se usa para representar caracteres Unicode individuales;
fuente