Que es un rune en Go?
He estado buscando en Google pero Golang solo dice en una línea: runees 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 switchtiene 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 runepara stringque pueda devolver la cadena intercambiada. Pero no entiendo cómo exactamente runeo bytefunciona aquí.

[]runese 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
32a'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' .
charchar*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
stringes 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
runees comoint32y tiene muchos bits.stringes una secuencia derunes". ¿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
int32es 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 runesEsto 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
stringy[]runemuy claramente, por lo que trataría de agregar otra respuesta con un ejemplo).Como
@Strangeworkdecía la respuesta,stringy[]runeson silenciosamente diferentes.Diferencias -
string&[]rune:string valuees un segmento de byte de solo lectura. Y, un literal de cadena está codificado en utf-8. Cada char enstringrealidad toma 1 ~ 3 bytes, mientras que cadarunetoma 4 bytesstring, amboslen()y el índice se basan en bytes.[]rune, amboslen()y el índice se basan en runas (o int32).Relaciones -
stringy[]rune:stringa[]rune, cada carácter utf-8 en esa cadena se convierte en arune.[]runeastring, cada uno seruneconvierte en un carácter utf-8 en elstring.Consejos:
stringy[]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 = 11len()cadena se basa en bytes, la primera línea impresalen: 11uint8(ya quebytees un tipo de aliasuint8, in go).Al convertir el
stringa[]rune, encontró 7 caracteres utf8, por lo tanto, 7 runas.len()en[]runese basa en la runa, por lo tanto, la última línea impresalen: 7.[]runetravé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[]runebasada 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 comohutf-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
switchno tener ningún argumento. Esto es simplemente porque en Golang,switchsin 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