Compartir tecnología

[Ir a serie] matriz, corte y mapa

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Conecta el anterior y el siguiente.

Introdujimos si y para en nuestro artículo anterior. Esto no debe practicarse. Practiquemos cómo usarlo.continue Declaración para calcular la suma de números pares hasta 100. Mientras escribimos código,continueLa declaración nos ayudará a omitir ciertas iteraciones que no son necesarias; por ejemplo, en este ejemplo, omitiremos todos los números impares.

  1. sum := 0
  2. for i := 1; i < 100; i++{
  3. if i & 1 == 0 {
  4. continue
  5. }
  6. sum += i
  7. }
  8. fmt.Println("the sum is",sum)

Comienza a aprender

En programación, a menudo necesitamos tratar con un conjunto de elementos del mismo tipo, y estos conjuntos de elementos están representados por estructuras de datos específicas en el lenguaje Go. Hoy les presentaré en detalle varios tipos de colecciones en Go: matriz, sector y mapa.

formación

Primero, comencemos con las matrices. La matriz es la estructura de datos más básica en Go. Es una secuencia de longitud fija de elementos del mismo tipo. Una vez declarada una matriz, su longitud no se puede cambiar. La declaración e inicialización de matrices es muy simple,

declarar matriz

Al declarar una matriz, debe especificar el tipo y la longitud de la matriz. Así es como se declara una matriz:

var arrayName [arrayLength]elementType

Por ejemplo, declare una matriz de enteros de longitud 5:

var numbers [5]int
inicializar matriz

Puede inicializar una matriz de varias maneras:

  • Utilice inicialización literal:
var numbers = [5]int{1, 2, 3, 4, 5}
  • usar:=Breve declaración:
numbers := [5]int{1, 2, 3, 4, 5}
  • Inferir automáticamente la longitud de la matriz:
numbers := [...]int{1, 2, 3, 4, 5}
  • Especifique la inicialización del índice:
numbers := [5]int{0: 1, 4: 5}

Características de las matrices.

  • Longitud fija: La longitud de la matriz se determina cuando se declara y no se puede cambiar más adelante.
  • elementos del mismo tipo: Las matrices solo pueden contener elementos del mismo tipo.
  • asignación de memoria de forma contigua: Los elementos de la matriz se asignan de forma contigua en la memoria, lo que hace que el acceso a los elementos de la matriz sea muy eficiente.

Acceder a elementos de la matriz

Puede acceder a los elementos de una matriz por índice, comenzando desde 0:

value := numbers[2] // 获取索引为 2 的元素

matriz transversal

puedes usarforRecorre todos los elementos de una matriz:

  1. for i, value := range numbers {
  2. fmt.Printf("Index: %d, Value: %dn", i, value)
  3. }

longitud de la matriz

Puedes usar el incorporadolenFunción para obtener la longitud de una matriz:

length := len(numbers)

valor cero de la matriz

Si una matriz no se inicializa explícitamente, sus elementos se establecen automáticamente en el valor cero de su tipo. Por ejemplo, el valor cero de una matriz de números enteros es 0:

var numbers [5]int // 所有元素都是 0

Matrices multidimensionales

El lenguaje Go también admite matrices multidimensionales. El siguiente es un ejemplo de declaración e inicialización de una matriz de enteros de 2x3:

  1. var matrix [2][3]int
  2. matrix = [2][3]int{{1, 2, 3}, {4, 5, 6}}

Limitaciones de las matrices

Dado que la longitud de la matriz es fija, esto puede no ser muy flexible en algunos casos. Si necesita una colección de longitud variable, puede utilizar sectores.

rebanada

El siguiente es el segmento, que es un tipo integrado más flexible que puede considerarse como una matriz dinámica. La longitud del segmento es variable y se crea en función de una matriz, lo que proporciona mayor comodidad. A continuación se explica cómo declarar e inicializar un segmento:

  1. s := make([]int, 3) // 创建一个长度为3的整型切片
  2. s[0] = 1 // 切片元素赋值
  3. s[1] = 2
  4. s[2] = 3
  5. s = append(s, 4) // 向切片追加元素

En el lenguaje Go, aunque tanto las matrices como los sectores se utilizan para almacenar una serie de elementos del mismo tipo, tienen diferencias significativas en la asignación de memoria, la variabilidad del tamaño y el uso. Estas son las principales diferencias entre matrices y sectores:

variabilidad de tamaño

  • formación : El tamaño de una matriz se determina cuando se declara y no se puede cambiar más adelante.El tamaño de una matriz es parte de su tipo, por lo que[3]inty[4]intson diferentes tipos.
  • rebanada : Los sectores son dinámicos y pueden crecer o reducirse en tiempo de ejecución.El tamaño de una porción no forma parte de su tipo, por lo que[]intEs el tipo común para todos los sectores de números enteros.

asignación de memoria

  • formación : Las matrices son tipos de valores y cuando se pasa una matriz como parámetro de función, se pasa una copia de su valor. Esto significa que las modificaciones a la matriz dentro de la función no afectan la matriz original.
  • rebanada : El segmento es un tipo de referencia que contiene un puntero a la matriz subyacente, la longitud y la capacidad del segmento. Cuando se pasa un segmento como parámetro de función, se pasa una copia del puntero, por lo que las modificaciones al segmento dentro de la función afectarán al segmento original.

inicialización

  • formación: Al inicializar una matriz, se debe especificar su tamaño y los valores de los elementos se pueden asignar inmediatamente.
  • rebanada: Los sectores se pueden pasar a través de literales,makeFunción o corte de una matriz para inicializar, sin tamaño especificado.

Código de muestra

A continuación se muestran ejemplos de inicialización para matrices y sectores:

  1. // 数组
  2. var arr [3]int = [3]int{1, 2, 3}
  3. // 切片
  4. var slice []int = []int{1, 2, 3}
  5. // 或者使用 make 函数
  6. slice := make([]int, 3)

Diferencias funcionales

  • formación: Dado que el tamaño es fijo, el tamaño de la matriz se conoce en el momento de la compilación, lo que hace posible asignar memoria para la matriz en la pila, y la complejidad temporal para acceder a los elementos de la matriz es O (1).
  • rebanada: Cortar proporciona más flexibilidad alappend La función agrega elementos u obtiene subporciones mediante operaciones de corte.La matriz subyacente del segmento se puede asignar en el montón, y la complejidad temporal para acceder a los elementos del segmento también es O (1), peroappendPuede dar lugar a una reasignación de la matriz subyacente, que suele ser una operación O(n).

cartografía

Finalmente, veamos el mapeo. Un mapa es una matriz asociativa en Go que asigna claves a valores. Las claves del mapa pueden ser de cualquier tipo admitido por el operador de igualdad, como números enteros, números de punto flotante, cadenas, punteros, interfaces (siempre que los valores contenidos dentro de la interfaz sean comparables), estructuras y matrices. El valor asignado puede ser de cualquier tipo.

Declaración e inicialización

declarar mapa

La sintaxis para declarar un mapa es la siguiente:

var mapName map[keyType]valueType

Por ejemplo, declare un mapa con claves como cadenas y valores como números enteros:

var scores map[string]int
Inicializar mapa

Después de declarar el mapa, debes pasar.makefunción para inicializarlo para que pueda ser utilizado:

scores = make(map[string]int)

Alternativamente, puede utilizar una declaración corta e inicializar:

scores := make(map[string]int)

También puede utilizar literales para la inicialización en el momento de la declaración:

  1. scores := map[string]int{
  2. "alice": 90,
  3. "bob": 85,
  4. "charlie": 88,
  5. }

Características del mapa

  • unicidad clave: En un mapa, cada clave es única. Si intenta insertar una clave existente, se actualizará el valor correspondiente a la clave.
  • trastorno:map está desordenado y el orden de los elementos puede ser diferente cada vez que se itera el mapa.
  • tamaño dinámico:El tamaño del mapa es dinámico, puede agregar o eliminar pares clave-valor según sea necesario.
  • tipo de referencia: Map es un tipo de referencia. Cuando pasas map a una función, lo que realmente pasas es un puntero a la estructura de datos subyacente.

Mapa de operación

Agregar elemento
scores["alice"] = 90
Obtener elemento
value := scores["alice"]

Si la clave no existe, se devolverá un valor cero para ese tipo de valor.

Comprobar si la clave existe

Puede usar el modismo coma -ok para verificar si la clave existe en el mapa:

  1. value, exists := scores["alice"]
  2. if exists {
  3. // 键存在
  4. } else {
  5. // 键不存在
  6. }
Eliminar elemento

usardeleteLa función puede eliminar un par clave-valor del mapa:

delete(scores, "alice")

Si la clave no existe,deleteLa función no hace nada.

Recorre el mapa

usarforUn bucle puede atravesar todos los pares clave-valor del mapa:

  1. for key, value := range scores {
  2. fmt.Printf("%s: %dn", key, value)
  3. }

valor cero del mapa

El valor cero del mapa esnil .unonil Un mapa no tiene una estructura de datos subyacente y no puede agregar elementos.Antes de agregar elementos al mapa, debes usarmakeInicializarlo.

longitud del mapa

Puedes usar el incorporadolenFunción para obtener el número de pares clave-valor en el mapa:

length := len(scores)

tipo de clave de mapa

Las claves del mapa pueden ser de cualquier tipo comparable, como números enteros, números de punto flotante, cadenas, punteros, interfaces (siempre que los valores contenidos dentro de la interfaz sean comparables), estructuras, matrices, etc. Los sectores, mapas y funciones no se pueden utilizar como claves de mapa porque estos tipos no admiten comparaciones de igualdad.

Fácil de cometer errores

En el lenguaje Go, matrices, sectores y mapas son tres estructuras de datos de uso común, cada una de las cuales tiene diferentes características y consideraciones. Aquí hay algunos puntos a tener en cuenta al usarlos:

Formación

  • Evite el uso de matrices demasiado grandes, ya que ocupan mucho espacio en la pila y pueden provocar un desbordamiento de la pila.
  • Las matrices se utilizan cuando se requiere una colección de datos de tamaño fijo.

Rebanada

  • La reasignación de memoria puede ocurrir cuando se expande la división. Intente preasignar suficiente capacidad para evitar una expansión frecuente.
  • Evite el uso de porciones que sean demasiado grandes, ya que pueden ocupar mucho espacio.
  • Tenga en cuenta que el valor cero del sector esnil, debe inicializarse antes de su uso.

mapa

  • El valor cero del mapa esnilnilEl mapa no se puede utilizar para almacenar pares clave-valor y debe inicializarse antes de su uso.
  • En un entorno concurrente, las operaciones de lectura y escritura en el mapa no son seguras para subprocesos y deben protegerse mediante bloqueos mutex u otros mecanismos de sincronización.
  • usardeleteEliminar una clave que no existe no genera un error, pero es seguro verificar si la clave existe.