Ir a aprender un idioma de tipo 5

3. Ir a tipos de datos de idioma

En el artículo anterior, presentamos el tipo de matriz del idioma Go, y este artículo presentará el tipo de segmento del idioma Go.

3.3 Cortar

El corte en rodajas puede verse como una forma de empaquetado para matrices. La matriz envuelta por una rebanada se denomina matriz subyacente de la rebanada. Un segmento es un descriptor de un segmento continuo en su matriz subyacente.

3.3.1 Notación de tipo

Para un tipo de segmento cuyo tipo de elemento es T, su literal de tipo es:

[]T

Se puede ver que la longitud no es parte del tipo de sector (es decir, no aparece en el literal de tipo que representa el tipo de sector). Además, la longitud del corte es variable. Los valores de corte del mismo tipo pueden tener diferentes longitudes.

El tipo de elemento en la declaración de tipo de segmento también puede ser cualquier tipo de datos de idioma Go válido. P.ej:

[]rune

Lo anterior se usa para indicar el tipo de rebanada cuyo tipo de elemento es runa.

También puede utilizar un tipo de estructura anónimo como tipo de elemento del tipo de sector. P.ej:

[] struct {name, department string}

3.3.2 Notación de valor

Similar a una matriz, también es un tipo de literal compuesto, por ejemplo:

[]string{"Go", "Python", "Java", "C", "C++", "PHP"}

No hay ninguna estipulación sobre la longitud en el tipo al que pertenece el valor del segmento. Las siguientes porciones son legales:

[]string{8: "Go", 2: "Swift", "Java", "C", "C++", "PHP"}

Lo anterior es equivalente al siguiente literal compuesto:

[]string{0: "", 1: "", 2: "Swift", 3: "Java", 4: "C", 5: "C++", 6: "PHP", 7: "", 8: "Go"}

3.3.3 Propiedades y operaciones básicas

El valor cero del tipo de sector es nulo. Antes de la inicialización, el valor de una variable de tipo de sector es nulo .

Aunque no hay ninguna declaración sobre la longitud en el tipo de sector, el valor tiene una longitud, que se refleja en el número real de valores de elementos que contienen. Puede utilizar la función incorporada len para obtener la longitud del valor del segmento. P.ej:

len([]string{8: "Go", 2: "Swift", "Java", "C", "C++", "PHP"})

El resultado del cálculo anterior es 9. Este valor de segmento en realidad contiene 6 valores de tipo de cadena especificados explícitamente y 3 valores cero de tipo de cadena completa "".

Nota : La aplicación de la función incorporada len al valor cero (es decir, nulo ) del tipo de sector dará como resultado 0.

La implementación subyacente del valor del segmento:
Un valor de sector siempre tiene una referencia a un valor de matriz. Una vez que se inicializa un valor de sector, se asociará con un valor de matriz que contiene los valores del elemento. Este valor de matriz se denomina matriz subyacente que hace referencia a su valor de sector.

Varios valores de sector pueden compartir la misma matriz subyacente. Por ejemplo, si un valor de sector se copia en varios, o si se corta un nuevo valor de sector para un determinado segmento continuo, todos estos valores de sector se referirán a la misma matriz subyacente. La modificación del valor del elemento en el valor del sector es esencialmente la modificación del elemento correspondiente en la matriz subyacente. Hablando a la inversa, los cambios en el valor del elemento en el valor de la matriz como elemento subyacente también se reflejarán en todos los valores de sector que se refieren a la matriz subyacente y contienen el valor del elemento.

Además de la longitud, el valor del segmento tiene una capacidad de atributo muy importante. La capacidad del valor del segmento está relacionada con la longitud de la matriz subyacente que contiene. Se puede obtener a través del tapón de función incorporado. P.ej:

cap([]string{8: "Go", 2: "Swift", "Java", "C", "C++", "PHP"})

La capacidad del valor de corte es 9, que es igual a su longitud. Este es un caso especial, pero en muchos casos no es el caso, escuchemos con calma.

La estructura de datos subyacente del valor del sector:
La estructura de datos subyacente de un valor de segmento contiene un valor de tipo de puntero que apunta a la matriz subyacente, un valor de tipo int que representa la longitud del segmento y un valor de tipo int que representa la capacidad del segmento.
Escriba la descripción de la imagen aquí

Puede utilizar una expresión de sector para "cortar" un segmento continuo de un valor de matriz o un valor de sector y generar un nuevo valor de sector. P.ej:

array1 := [...]string{8: "Go", 2: "Swift", "Java", "C", "C++", "PHP"}
slice1 := array1[:4]

La matriz subyacente del valor de la variable slice1 es en realidad el valor de la variable array1, como se muestra a continuación:

Escriba la descripción de la imagen aquí

Después de la descripción anterior, puede pensar que la capacidad de un segmento puede ser la longitud de su matriz subyacente. Pero este no es el caso, aquí creamos otro valor de corte. P.ej:

slice2 := array1[3:]

La matriz subyacente del valor de la variable slice2 también es el valor de la variable array1, como se muestra a continuación:

Escriba la descripción de la imagen aquí

Como se muestra arriba, la capacidad del valor de slice2 no es igual a la longitud del valor de array1. De hecho, la capacidad de un valor de sector es el valor de recuento desde el valor del elemento al que apunta el puntero hasta el último valor del elemento de la matriz subyacente . El significado de la capacidad del valor de segmento es el número máximo de valores de elemento en la matriz subyacente actual a la que puede acceder.

El valor del sector se puede expandir para ver más elementos de matriz subyacentes. Sin embargo, la ventana no se puede expandir directamente volviendo a cortar. Por ejemplo, realice las siguientes operaciones en el valor original del segmento1 anterior:

slice1[4]

Esto provocará un pánico en tiempo de ejecución, porque el valor del índice excede la longitud actual del valor del segmento, lo cual no está permitido. La forma correcta de expandir es la siguiente:

slice1 = slice1[:cap(slice1)]

Al volver a cortar slice1 al máximo, puede ver la mayoría de los valores de los elementos de la matriz de nivel inferior. En este momento, la longitud del valor de slice1 es igual a su capacidad.

Nota: La capacidad de un valor de corte es fija. En otras palabras, el número máximo de elementos de matriz subyacentes que se pueden ver es fijo.

El valor de la porción no se puede expandir más allá de su capacidad, por ejemplo:

slice1 = slice1[:cap(slice1)+1]//超出slice1容量的范围,这样会引起一个运行时恐慌

Un valor de sector solo puede expandirse en la dirección de aumentar el índice. P.ej:

slice2 = slice2[-2:] //这会引起一个运行时恐慌。另外,切片值不允许由负整数字面量代表。

Use la función de agregar para extender el valor de slice1 al principio:

slice1 = append(slice1, "Ruby", "Erlang")

Después de ejecutar esta declaración, el valor de la variable de tipo de sector slice1 y el estado de su matriz subyacente (el valor de la variable de matriz array1) son los siguientes:

Escriba la descripción de la imagen aquí

Se puede ver que la longitud del valor de slice1 ha aumentado de 4 a 6 original, que es lo mismo que su capacidad. Pero dado que la longitud de este valor no ha superado su capacidad, no es necesario crear una nueva matriz subyacente.

El valor de slice1 original es:

[]string{"Go", "Python", "Java", "C"}

El valor actual de slice1 es:

[]string{"Go", "Python", "Java", "C", "Ruby", "Erlang"}

El valor original de array1 es:

[6]string{"Go", "Python", "Java", "C", "C++", "PHP"}

El valor actual de array1 es:

[6]string{"Go", "Python", "Java", "C", "Ruby", "Erlang"}

Extienda el segmento actual1 de la siguiente manera:

slice1 = append(slice1, "Lisp")

Después de ejecutar esta instrucción, la longitud del valor de la variable slice1 excede su capacidad. En este momento, se creará e inicializará un nuevo valor de matriz. Este nuevo valor de matriz se utilizará como la matriz inferior del valor de segmento recién creado en la función de adición, y contendrá todos los valores de elemento en el valor de segmento original y todos los valores de elemento como contenido extendido. El puntero en el nuevo valor de segmento apuntará al valor del primer elemento de su matriz subyacente, y su longitud y capacidad son las mismas que la longitud de su matriz subyacente. Finalmente, este nuevo valor de segmento se asignará a la variable segmento1.

Puede utilizar la función de adición para conectar dos valores de sector con el mismo tipo de elemento. P.ej:

slice1 = append(slice1, slice...)

Por supuesto, también puede pasar el valor de la matriz como segundo parámetro a la función de adición.

Incluso si el valor de la variable de tipo de sector es cero cero, se considerará como un valor de sector con una longitud de 0. P.ej:

slice2 = nil
slice2 = append(slice2, slice1...)

O como sigue:

var slice4 []string
slice4 = append(slice4, slice...)

La primera declaración anterior se usa para declarar (no incluir la inicialización) una variable. Comience con la palabra clave var , seguida del nombre y tipo de la variable. El valor de la variable de corte no inicializada es nulo .

3.3.4 Uso complejo de rodajas

Agregue un tercer índice a la expresión de corte ----- índice de límite superior de capacidad. Si se especifica, la capacidad del valor de segmento del resultado de la evaluación de la expresión de segmento ya no es la diferencia entre la capacidad del objeto de operación de la expresión de segmento y el índice de límite inferior del elemento en la expresión, sino la capacidad La diferencia entre el índice de límite y el índice de límite inferior del elemento.

El propósito de especificar el índice de límite superior de la capacidad es reducir la capacidad del nuevo valor de segmento, lo que permite una estrategia de aislamiento de datos más flexible.

var array2 [10]int = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
slice5 := array2[2:6]

Como arriba, podemos acceder directamente y modificar el valor del elemento en array2 cuyo valor de índice está dentro del rango de [2,6).

slice5 = slice5[:cap(slice5)]

Después de cortar como arriba, puede acceder y modificar el valor del elemento cuyo valor de índice está en el rango de [2,10) en el valor de matriz2.

Si el valor de slice5 se pasa a otro programa como portador de datos, este programa puede cambiar el valor de algunos elementos en el valor de array2 a voluntad. Esto equivale a exponer parte de los detalles de implementación en el programa y revelar un método que puede modificar indirectamente el estado interno del programa, que a menudo no es lo que queremos.

Si slice5 se declara así:

slice5 := array2[2:6:8]

De esta forma, el titular de slice5 solo puede acceder y modificar el valor del elemento cuyo valor de índice se encuentra dentro del rango de [2,8) en el valor de array2.

slice5 = slice5[:cap(slice5)]

Incluso si slice5 se expande al máximo, no se puede acceder a través de él a aquellos elementos cuyo valor de índice correspondiente sea mayor o igual a 8 en el valor de array2. En este momento, la capacidad del valor del segmento5 es 6 (la diferencia entre el índice de límite superior de la capacidad y el índice de límite inferior del elemento). Para las operaciones de corte, la capacidad del objeto operado es un límite insuperable. El valor de slice5 restringe los "derechos de acceso" de su matriz subyacente (valor de matriz2).

Si la expansión por encima del valor de slice5 excede su capacidad:

slice5 = append(slice5, []int{10, 11, 12, 13, 14, 15}…)

Entonces se reemplazará su matriz subyacente original. También corta completamente la forma de acceder y modificar los valores del elemento en la matriz subyacente original a través de slice5.

Limitación de los 3 índices en la expresión de sector: cuando el índice de límite superior de capacidad se especifica en la expresión de sector, el índice de límite superior del elemento no se puede omitir. Sin embargo, en este caso, se puede omitir el índice de límite inferior del elemento. P.ej:

slice5[:3:5]//合法的切片表达式
slice5[0::5]//非法的切片表达式,会造成一个编译错误

Copie por lotes los elementos en el valor del sector

sliceA := []string{"Notepad", "UltraEdit", "Eclipse"}
sliceB := []string{"Vim", "Emacs", "LiteIDE", "IDEA"}

Utilice la copia de función incorporada del lenguaje Go para copiar los elementos en el valor de la variable sliceB al valor de sliceA. P.ej:

n1 := copy(sliceA,sliceB)

La función de la función incorporada copiar es copiar el valor del elemento en el valor del segmento de origen (el segundo valor del parámetro) al valor del segmento de destino (el primer valor del parámetro) y devolver el número de valores del elemento copiados. Los tipos de elementos de los dos parámetros de la función de copia deben ser los mismos, y el número de valores de elementos que realmente copia será igual a la longitud del valor de corte más corto.

El valor de la variable n1 es 3 y el valor de la variable sliceA se modifica a:

[]string{"Vim", "Emacs", "LiteIDE"}

Supongo que te gusta

Origin blog.csdn.net/u012855229/article/details/115367385
Recomendado
Clasificación