JF0x0r's Blog
PortfolioBug Hunter ProfileGithub
  • Whoami
  • Aprender Go
    • 🐺¿Qué es GO 🦊
    • 🧠Packages
    • 🎃Modules
    • 🐢Variable - Tipos de Datos
    • 🧌Operadores Matematicos - Lógicos
    • 🥥Flujo If, For, While, Switch
    • 🌼Struct - Methods vs Functions
    • 📽️POO (Programming Oriented Object)
    • 🐯Interface - Interfaces
    • 🎱Punteros * &
    • 🐸Vectores/Arrays, Slices y Maps
    • 🫀El uso de Make en channels, slices, maps
    • 🧛‍♀️Errores en Go - Uso de err ≠ nil
    • 👁️GO Defer
    • 🦷GO Panic
    • 🦋GO Recover
    • 🐦Structs
    • 🐔WaitGroups Go
  • Pentester Lab
  • Guía de Estudio Hacking
  • Bug Bounty
    • 🍓Adobe
    • 🚀Nasa VDP
    • 🧀Figma
      • 🐙User Enumeration via Authentication Flow - Email Exposure
    • 🫐Syfe
    • 🍉Etoro
    • 🥭Glance Networks
  • PortSwigger WebAcademy
    • Server Side Topics
      • SQL Injection
        • 🐔Laboratorio: Inyección SQL ciega
        • 🍫Laboratorio: Datos Ocultos - Aprendiz
        • 🦍Laboratorio: Omitir inicio de sesión Bypass
        • 🔏Laboratorio: Calcular numero Columnas con UNION
        • 🪖Laboratorio: ataque UNION de inyección SQL , búsqueda de una columna que contiene texto
        • 🐧Laboratorio: ataque UNION de inyección SQL , recuperando datos de otras tablas
        • 🧛Laboratorio: ataque UNION de inyección SQL , recuperando múltiples valores en una sola columna
        • 🐬Laboratorio: Inyección SQL con errores condicionales
        • 🐈‍⬛Laboratorio: Inyección SQL basada en errores visibles
        • 💃Laboratorio: Inyección SQL ciega con retrasos de tiempo
        • 🐆Laboratorio: Inyección SQL ciega con retardos de tiempo y recuperación de información
        • 👑Laboratorio: Inyección SQL ciega con interacción fuera de banda
        • 🏞️Laboratorio: ataque de inyección SQL, consulta del tipo y versión de la base de datos en Oracle
        • 🪻Laboratorio: ataque SQLi, consulta del tipo y versión de la base de datos en MySQL y Microsoft
        • 💀Laboratorio: ataque de inyección SQL, enumerando el contenido de la base de datos en bases de datos
        • 🧀Laboratorio: Inyección SQL con omisión de filtro mediante codificación XML
      • Authentication
        • 🐟Laboratorio: Enumeracion de usernames via diferentes responses
        • 👩‍🦽Laboratorio: enumeración de nombres de usuario a través de respuestas sutilmente diferentes
        • ™️Laboratorio: enumeración de nombres de usuario mediante tiempos de respuesta
        • 🦷Laboratorio: protección de fuerza bruta rota, bloqueo de IP
        • 🧢Laboratorio: enumeración de nombres de usuario mediante bloqueo de cuenta
        • 🦠Laboratorio: protección de fuerza bruta rota, múltiples credenciales por solicitud
        • 🐛Laboratorio: bypass simple 2FA
        • 🐯Laboratorio: lógica rota 2FA
        • 👓Laboratorio: 2FA bypass usando un ataque por fuerza bruta
        • 👽Lab: Brute-forcing a stay-logged-in cookie
        • 🦋Laboratorio: Offline password cracking
        • 🧌Laboratorio: Password reset broken logic
        • 👁️Laboratorio: Basic password reset poisoning
        • 👂Laboratorio: Password reset poisoning via middleware
        • 🥻Laboratorio: Fuerza bruta de contraseña mediante cambio de contraseña
        • 🫁Laboratorio: Envenenamiento por restablecimiento de contraseña mediante etiquetas colgantes
      • Path Traversal
        • 🛻Laboratorio: File path traversal, simple case
        • 🦅Laboratorio: File path traversal, traversal sequences blocked with absolute path bypass
        • 🦉Laboratorio: recorrido de ruta de archivo , secuencias transversales eliminadas de forma no recursiv
        • 🍊Laboratorio: File path traversal, traversal sequences stripped with superfluous URL-decode
        • 🕷️Laboratorio: File path traversal, validation of file extension with null byte bypass
      • Command Injection OS
        • 🖥️Laboratorio: OS command injection, simple case
        • 🐹Laboratorio: Blind OS command injection with time delays
        • 👹Blind OS command injection with output redirection
        • 🧛‍♂️Laboratorio: Inyección ciega de comandos del SO con exfiltración de datos fuera de banda
        • 🦟Laboratorio: Inyección ciega de comandos del sistema operativo con interacción fuera de banda
      • Business Logic Vulnerabilities
        • 🧝‍♂️Laboratorio: Confianza excesiva en los controles del lado del cliente
        • 🧙‍♂️Laboratorio: Vulnerabilidad lógica de alto nivel
        • 🤩Laboratorio: Vulnerabilidad falla lógica de bajo nivel
        • 🎻Laboratorio: Manejo inconsistente de entradas excepcionales
        • 🏓Laboratorio: Inconsistent security controls
        • 🥭Laboratorio: Aislamiento débil en terminales de doble uso
        • 🧑‍✈️Laboratorio: Validación de flujo de trabajo insuficiente
        • 📀Laboratorio: Omisión de autenticación a través de una máquina de estado defectuosa
        • 🐦‍⬛Laboratorio: Aplicación defectuosa de las reglas comerciales
        • 🌵Laboratorio: falla en la lógica del dinero infinito
        • 🥑Laboratorio: omisión de autenticación mediante Oracle de cifrado
        • 🧊Lab: Bypassing access controls using email address parsing discrepancies
      • Information Disclosure Vulnerabilities
        • 🧟Laboratorio: Divulgación de información en mensajes de error
        • 🌵Laboratorio: divulgación de información en la página de depuración
        • 🍅Laboratorio: Divulgación del código fuente a través de archivos de respaldo
        • 🤿Laboratorio: omisión de autenticación mediante divulgación de información
        • 🏑Laboratorio: Divulgación de información en el historial de control de versiones
      • SSRF - Server-Side Request Forgery
        • 🧅Laboratorio: SSRF básico frente a otro sistema back-end
        • 🐮Laboratorio: SSRF con filtro de entrada basado en lista negra
        • 🌶️Laboratorio: SSRF con filtro de entrada basado en lista blanca
        • 💽Laboratorio: SSRF with filter bypass via open redirection vulnerability
        • ☎️Laboratorio: SSRF ciega con detección fuera de banda
        • 🥬Laboratorio: SSRF ciega con explotación Shellshock
        • 🐦Laboratorio: SSRF básico contra el servidor local
      • Acess Control
        • 🍑Laboratorio: funcionalidad de administración desprotegida
        • 🍉Laboratorio: funcionalidad de administración desprotegida con URL impredecible
        • 🐱Laboratorio: rol de usuario controlado por el parámetro de solicitud
        • 🐒Laboratorio: La función del usuario se puede modificar en el perfil del usuario
        • 🐴Laboratorio: el control de acceso basado en URL se puede eludir
        • 🍋Laboratorio: El control de acceso basado en métodos se puede eludir
        • 🎾Laboratorio: ID de usuario controlado por parámetro de solicitud
        • 🧆Laboratorio: ID de usuario controlado por parámetro de solicitud, con ID de usuario impredecibles
        • 🦑Laboratorio: ID de usuario controlado por parámetro de solicitud con fuga de datos en redirección
        • 😎Laboratorio: ID de usuario controlado por parámetro de solicitud con divulgación de contraseña
        • 🍗Laboratorio: Referencias directas a objetos inseguros
        • 🧀Laboratorio: proceso de varios pasos sin control de acceso en un solo paso
        • ⛄Laboratorio: Control de acceso basado en referentes
      • File Upload Vulnerabilities
        • 🛼Laboratorio: ejecución remota de código mediante carga de shell web
        • 🥦Laboratorio: carga de shell web mediante omisión de restricción de tipo de contenido
        • ⛵Laboratorio: carga de shell web mediante recorrido de ruta
        • 🛝Laboratorio: carga de shell web mediante omisión de la lista negra de extensiones
        • ⚾Laboratorio: carga de shell web a través de una extensión de archivo ofuscada
        • 🪖Laboratorio: carga de shell web mediante condición de carrera
      • Web Cache Deception
        • 🧀Laboratorio: Explotación del mapeo de rutas para el engaño de caché web
        • 🍨Laboratorio: Explotación de delimitadores de ruta para el engaño de caché web (v2)
        • 🪇Laboratorio: Explotación de la normalización del servidor de origen para el engaño de la caché web
        • 🍺Laboratorio: Explotación de la normalización del servidor de caché para el engaño de la caché web
        • ⚽Laboratorio: Explotación de reglas de caché de coincidencia exacta para el engaño de caché web
      • API Testing
        • 🥨Laboratorio: Explotación de un punto final de API mediante documentación
        • 🛝Laboratorio: Cómo encontrar y explotar un punto final de API no utilizado
        • 🧤Laboratorio: Explotación de una vulnerabilidad de asignación masiva
        • 🍒Laboratorio: Explotación de la contaminación de parámetros del lado del servidor en una cadena de co
        • 🥕Laboratorio: Explotación de la contaminación de parámetros del lado del servidor en una URL REST
      • XXE Injection - XML Entity
        • 🏸Laboratorio: Exploiting XXE using external entities to retrieve files
        • 🥾Laboratorio: Exploiting XXE to perform SSRF attacks
        • 🧑‍🎤Laboratorio: Blind XXE with out-of-band interaction
        • 🦉Laboratorio: Blind XXE with out-of-band interaction via XML parameter entities
        • 🌋Laboratorio: Exploiting blind XXE to exfiltrate data using a malicious external DTD
        • 👾Laboratorio: Exploiting blind XXE to retrieve data via error messages
        • 🌍Laboratorio: Exploiting XXE to retrieve data by repurposing a local DTD
        • 🫀Laboratorio: Exploiting XInclude to retrieve files
        • 👁️Laboratorio: Exploiting XXE via image file upload
      • Race Conditions
        • 🗣️Mutexes Golang
        • ⛸️Laboratorio: Limit overrun race conditions
        • 👽Laboratorio: Bypassing rate limits via race conditions
        • 👩‍🦯Laboratorio: Multi-endpoint race conditions
        • 🧢Laboratorio: Single-Endpoint Race Conditions
        • 🐛Laboratorio: Partial Construction Race Condition
        • 🔩Laboratorio: Exploiting time-sensitive vulnerabilities
      • No-SQL Injection
        • 🪱Laboratorio: Detecting NoSQL injection
        • 💼Laboratorio: Exploiting NoSQL operator injection to bypass authentication
        • 🪖Laboratorio: Exploiting NoSQL injection to extract data
        • 🦺Laboratorio: Exploiting NoSQL operator injection to extract unknown fields
    • Client Side Topics
      • Cross-site scripting (XSS)
        • XSS Reflected
          • ⛑️Laboratorio: XSS reflejado en contexto HTML sin nada codificado
        • XSS Based DOM
          • 🍖Laboratorio: DOM XSS en document.write, el receptor usando la fuente location.search
        • XSS Stored
          • 🪢Laboratorio: Stored XSS into HTML context with nothing encoded
          • 🥌Laboratorio: Stored XSS into onclick event with angle brackets and double quotes HTML-encoded
    • Advanced Topics
      • 0Auth
      • Insecure Deserialization
        • 🧀Laboratorio: Modificar objetos en serie
        • 🧅Laboratorio: Modificar los tipos de datos en serie
        • 🎋Laboratorio: Usando funcionalidad de la aplicación para explotar la desserialización insegura
        • 🎯Laboratorio: Inyección arbitraria de objetos en PHP
        • 🍿Laboratorio: Inyección arbitraria de objetos en PHP
        • 🕸️Laboratorio: Exploiting Java deserialization with Apache Commons
        • 🥷Laboratorio: Exploiting PHP deserialization with a pre-built gadget chain
        • 🏈Laboratorio: Exploiting Ruby deserialization using a documented gadget chain
        • 🎄Laboratorio: Desarrollo de una cadena de gadget personalizada para la deserialización de Java
        • 👨‍🦽Laboratorio: Desarrollo una cadena de gadget personalizada para la deserialización de PHP
  • Hacking Certifications
    • ACP - APISec University
      • 🌍API Security Fundamentals 2025
      • 🫀OWASP API Security Top 10 and Beyond!
      • 🏓API Authentication
      • 🥥API Documentation Best Practices
      • 🌲Securing API Servers
Powered by GitBook
On this page
  • Referencias:
  • Crear Slices en Go (otra forma de crearlos)
  • Agregar elementos a un Slice en Go
  • Longitud y capacidad de Slices en Go
  • Maps →
  • Definición de un mapa:
  • Añadir elementos a un mapa:
  • Recuperar un valor de un mapa:
  • Eliminar un elemento de un mapa:
  • Comprobación de la existencia de una clave:
  • Recorrer un mapa:
  • Ordenar un mapa:
  • Serialización de mapas:
  • Peculiaridades y optimización de slices →
  • Preguntas para practicar:
  • Más preguntas →
  • Más preguntas →
  • Conclusión:
  1. Aprender Go

Vectores/Arrays, Slices y Maps

PreviousPunteros * &NextEl uso de Make en channels, slices, maps

Last updated 7 months ago

Referencias:

Vectores/Arrays →

En programación se conoce vector o arreglo a una zona de almacenamiento contiguo que contiene una serie de elementos del mismo tipo, los elementos de la matriz. Desde el punto de vista lógico una matriz se puede ver como un conjunto de elementos ordenados en fila (o filas y columnas si tuviera dos dimensiones).

Al ser de tamaño fijo, los arrays aseguran que se utilice únicamente la cantidad de memoria necesaria, optimizando así el uso de recursos.

La sintaxis es así:

var nombre_array [longitud]tipo

Donde nombre_array es el nombre del array, longitud es la cantidad de elementos que puede almacenar el array y tipo es el tipo de dato que contendrá el

Ejemplo de un Array en GO →

package main

import "fmt"

func main(){
    var calificaciones [5]int
		
    calificaciones[0] = 89
    calificaciones[1] = 54
    calificaciones[2] = 86
    calificaciones[3] = 34
    calificaciones[4] = 67
    
    fmt.Println(calificaciones) //Salida: [89 54 86 34 67]

}

Diferencia entre arrays y slices en Go

Aunque los arrays y los slices en Go pueden parecer similares a simple vista, hay diferencias clave entre ellos:

  • Arrays:

    • Tamaño fijo en el momento de la declaración

    • Menos flexibles que los slices

    • Útiles cuando se conoce el tamaño requerido previamente

  • Slices:

    • Tamaño dinámico y puede cambiar durante la ejecución del programa

    • Más flexibles que los arrays

    • Útiles cuando se desconoce el tamaño requerido previamente o cuando se espera que cambie

A continuación, se muestra un ejemplo de array y slice en Go para ilustrar las diferencias:

var arrayEjemplo [3]int //declaracion del array

arrayEjemplo[0] = 1
arrayEjemplo[1] = 2
arrayEjemplo[2] = 3

sliceEjemplo := []int{1,2,3} //declaracion slice 3 elementos
sliceEjemplo = append(sliceEjemplo, 4) //añadir un nuevo elemento al slice dinamicamente. 

Declarar e inicializar un array en una sola línea:

nombreArray := [tamaño]Tipo{valor1, valor2, ..., valorN}

Iteración sobre un array usando bucles for

Para recorrer todos los elementos de un array, puedes utilizar un bucle for. Go proporciona dos formas de iterar sobre un array: utilizando un bucle for con índices y utilizando un bucle for con la declaración range.

Bucle for con índices

colores := [3]string{"rojo", "verde", "azul"} // Declaración e inicialización del array 'colores'

// Iteración sobre el array utilizando un bucle for con índices
for i := 0; i < len(colores); i++ {
    fmt.Println(colores[i]) // Imprime cada elemento del array 'colores'
}

Bucle for con la declaración range

colores := [3]string{"rojo", "verde", "azul"} // Declaración e inicialización del array 'colores'

// Iteración sobre el array utilizando un bucle for con la declaración range
for i, color := range colores {
    fmt.Printf("Índice: %d, Color: %s\\n", i, color) // Imprime el índice y el elemento del array 'colores'
}

//Ten en cuenta que si solo necesitas el elemento y no el índice, puedes utilizar el operador guion bajo (_) para ignorar el valor del índice:
for _, color := range colores {
    fmt.Println(color) // Imprime cada elemento del array 'colores' sin utilizar el índice
}

En Go, los tres puntos (...) en una declaración de un array indican que el tamaño del array debe ser inferido automáticamente a partir de los elementos que le asignes. No es exactamente lo mismo que tener un "tamaño variable", sino que el compilador determina el tamaño del array con base en la cantidad de elementos proporcionados en la lista de inicialización.

edades := [...]int{1, 2, 3, 4, 4, 3, 5}

Array Bidimensionales o multidimensionales →

matriz := [3][3]int{
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
} // Inicialización del array bidimensional 'matriz' con valores

elemento := matriz[1][2] // Acceso al elemento en la fila 1 (segunda fila) y columna 2 (tercera columna)
fmt.Println(elemento)    // Imprime 6

Slices →

Ahora que ya sabemos lo que es un array en Go entender lo que es un sliceno debería suponer problema alguno. Si recuerdas, en el apartado anterior aclaraba que los arreglos tienen un tamaño fijo, y pudieron notar que su capacidad y longitud coincidían, por lo posiblemente se estén cuestionando la utilidad de conocer el valor de capacidad. Los slices pueden verse como arreglos de longitud dinámica, siendo un poco más técnicos, un slice apunta a un array, claro que aún no hablamos de punteros, estoy preparando una publicación específica para ellos, por el momento no se preocupen.

Crear Slices en Go (otra forma de crearlos)

Por ejemplo, para crear un slice de tipo int con una longitud inicial de 3 elementos y una capacidad máxima de 5 elementos:


mi_slice := make([]int, 3, 5) //en esta se define un min de elemento y un maximo de capacidad de elementos en el slice.
//Por que la clasica que yo ya conocí es asi:
slice_example := []int{34,54,2} // y ya

En este ejemplo, se crea un slice llamado mi_slice de tipo int con una longitud inicial de 3 elementos y una capacidad máxima de 5 elementos.

sliceEjemplo := []int{1,2,3} //declaracion slice 3 elementos
sliceEjemplo = append(sliceEjemplo, 4) //añadir un nuevo elemento al slice dinamicamente. 

Agregar elementos a un Slice en Go

Para agregar elementos a un slice, se utiliza la función append(). La sintaxis para agregar un elemento a un slice es la siguiente:

nombre_slice = append(nombre_slice, 10)

Longitud y capacidad de Slices en Go

La longitud de un slice se puede obtener utilizando la función len() y la capacidad del slice se puede obtener utilizando la función cap().

Por ejemplo, para obtener la longitud y la capacidad de mi_slice:

fmt.Println(len(mi_slice)) // Imprime la longitud del slice: 3
fmt.Println(cap(mi_slice)) // Imprime la capacidad del slice: 5

Maps →

Definición de un mapa:

Los mapas se definen usando la palabra clave map seguida del tipo de dato de la clave y del tipo de dato del valor.


m := map[string]int{
  "clave1": 1,
  "clave2": 2,
  "clave3": 3,
}

Añadir elementos a un mapa:

Se pueden añadir elementos a un mapa utilizando la sintaxis clave:valor.

m["clave4"] = 4

Recuperar un valor de un mapa:

Se puede recuperar un valor de un mapa utilizando la clave como índice.

valor := m["clave2"]
fmt.Println(valor) // Imprime "2"

Eliminar un elemento de un mapa:

Se puede eliminar un elemento de un mapa utilizando la función delete.

delete(m, "clave3")

Comprobación de la existencia de una clave:

Se puede comprobar si una clave existe en un mapa utilizando la función len.


_, ok := m["clave5"]
if ok {
  // La clave existe
} else {
  // La clave no existe
}

Recorrer un mapa:

Se puede recorrer un mapa utilizando un bucle for.

for clave, valor := range m {
  fmt.Println(clave, valor)
}

Ordenar un mapa:

No es posible ordenar un mapa directamente en GO. Sin embargo, existen diferentes técnicas para obtener un ordenamiento, como convertir el mapa a una lista y luego ordenarla.

Serialización de mapas:

Los mapas se pueden serializar a diferentes formatos como JSON o XML.


json, err := json.Marshal(m)
if err != nil {
  panic(err)
}

fmt.Println(string(json)) // Imprime {"clave1":1,"clave2":2,"clave4":4}

1. Arrays en Go:

Un array es una secuencia contigua de elementos del mismo tipo y de tamaño fijo, lo que significa que no puedes cambiar su longitud una vez declarado.

  • Declaración:

    var arr [5]int  // Array de 5 enteros
    arr[0] = 10     // Asignar valor en la primera posición
    fmt.Println(arr)
  • Inicialización directa: Puedes inicializar el array al declararlo:

arr := [3]int{1, 2, 3}
fmt.Println(arr)
  • Características importantes:

    1. El tamaño es parte del tipo, por lo que [3]int y [5]int son tipos diferentes.

    2. Los arrays no son dinámicos, por lo que no puedes agregar o quitar elementos.

  • Acceso y mutabilidad: Los arrays son mutables, lo que significa que puedes modificar sus elementos directamente usando el índice:

    arr[1] = 20
    fmt.Println(arr)

2. Slices en Go:

Los slices son una abstracción más flexible y poderosa que los arrays. A diferencia de los arrays, los slices tienen un tamaño dinámico y pueden crecer o reducirse.

Declaración:

var s []int  // Un slice de enteros sin tamaño fijo
  • Inicialización: Puedes crear un slice a partir de un array o directamente:

slice := []int{1, 2, 3}
fmt.Println(slice)
  • Slice a partir de un array:

arr := [5]int{10, 20, 30, 40, 50}
slice := arr[1:4] // Slice que toma elementos de índice 1 al 3
fmt.Println(slice) // [20 30 40]
  • Capacidad y longitud: Los slices tienen dos propiedades importantes: la longitud (len) y la capacidad (cap):

fmt.Println(len(slice))  // 3 (número de elementos)
fmt.Println(cap(slice))  // 4 (capacidad restante del array subyacente)

La capacidad indica cuántos elementos se pueden agregar antes de que el slice necesite redimensionarse.

  1. Copiar slices: Para copiar un slice en otro

slice2 := make([]int, len(slice))  // Crear un nuevo slice con longitud específica
copy(slice2, slice)
fmt.Println(slice2)

Aquí, make se usa para crear un slice vacío con una longitud específica.

  1. Cortar slices (slicing) Puedes crear sub-slices dinámicos de un slice:

subSlice := slice[1:3]
fmt.Println(subSlice) // [30 40]

Peculiaridades y optimización de slices →

  1. Compartir memoria, Los slices comparten el mismo array subyacente, por lo que cambiar el valor en un slice afecta a los otros slices creados del mismo array:

arr := [5]int{1, 2, 3, 4, 5}
slice1 := arr[1:3]
slice2 := arr[2:4]
slice1[1] = 100
fmt.Println(arr)     // [1 2 100 4 5]
fmt.Println(slice2)  // [100 4]
  1. Redimensionar slices, El redimensionamiento de un slice puede crear un nuevo array, lo que tiene un costo en rendimiento cuando se manejan grandes cantidades de datos. Es recomendable predefinir la capacidad de un slice si se sabe cuántos elementos se van a almacenar.

  2. Append y redimensionamiento:

slice := []int{1, 2, 3}
fmt.Println(len(slice), cap(slice)) // 3, 3

slice = append(slice, 4)
fmt.Println(len(slice), cap(slice)) // 4, 6 (capacidad aumentada automáticamente)
  1. Reducir un slice: Eliminar elementos de un slice sin perder la referencia

slice := []int{1, 2, 3, 4, 5}
slice = slice[:len(slice)-1]  // Eliminar el último elemento
fmt.Println(slice)            // [1 2 3 4]

Preguntas para practicar:

  1. ¿Cuál es la diferencia entre la longitud y la capacidad de un slice?

  2. ¿Qué ocurre cuando modificas un slice que proviene de un array?

  3. Si creas un slice desde un array, ¿modificar el slice afecta el array original? Explica por qué.

  4. Escribe una función que acepte un slice de enteros y devuelva el promedio de esos enteros.

  5. ¿Qué hace la función append() internamente si se excede la capacidad del slice?

Cuando estés listo, seguimos con el siguiente tema.

Respuestas:

  1. Correcto. La longitud (len) es el número de elementos que actualmente contiene el slice, mientras que la capacidad (cap) es el número de elementos que puede contener antes de que Go redimensione el slice.

  2. Parcialmente correcto. Modificar un slice afecta al array original si el slice aún está basado en el array subyacente. Los slices no son independientes del array; al contrario, comparten memoria. Así que, si modificas un slice, esos cambios se reflejan en el array original.

  3. Incorrecto. Los slices no son copias del array original. Si creas un slice a partir de un array, ambos compartirán la misma memoria. Modificar el slice también modifica el array original, ya que ambos están referenciando la misma región de memoria.

  4. Código incorrecto. En tu función, hay algunos problemas:

    • No has inicializado la variable suma.

    • Estás usando índices incorrectos dentro del loop.

    • Además, la función debería devolver float64 porque estamos calculando un promedio.

    Aquí te dejo la corrección:

func promedio(slice []int) float64 {
    suma := 0
    for _, valor := range slice {
        suma += valor
    }
    return float64(suma) / float64(len(slice))
}
  1. Incorrecto. Cuando append() excede la capacidad del slice, no retorna un error ni un panic. En lugar de eso, Go crea un nuevo array con mayor capacidad, copia los elementos del array original a este nuevo array, y luego agrega el nuevo elemento. El slice devuelto apunta a este nuevo array.

Más preguntas →

  1. ¿Cómo puedes asegurarte de que un slice tiene suficiente capacidad antes de agregarle nuevos elementos?

  2. ¿Cuál es la diferencia entre declarar un slice con var y crearlo con make?

  3. ¿Qué ventaja tiene usar copy() en slices en lugar de hacer la asignación directa?

  4. ¿Cómo puedes reducir la capacidad de un slice sin cambiar su longitud actual?

Respuestas:

  1. Correcto, puedes asegurarte de que un slice tenga suficiente capacidad al usar make() y especificar la capacidad adecuada. Sin embargo, si no sabes con exactitud cuántos elementos agregarás, puedes optar por sobreasignar capacidad o monitorear el uso de append() para manejar redimensionamientos automáticos.

  2. Correcto. La diferencia entre var y make() es fundamental:

    • Usar var simplemente declara el slice, pero no le asigna memoria ni capacidad.

    • Usar make() sí reserva memoria para el array subyacente y asigna tanto longitud como capacidad, garantizando que el slice esté completamente inicializado y listo para usar.

  3. Incorrecto en parte. El uso de copy() no hace que los slices compartan la misma dirección de memoria. De hecho, copy() crea una copia de los valores en un nuevo espacio en memoria. La ventaja de usar copy() es que puedes duplicar los valores de un slice en otro slice sin que ambos compartan la misma memoria, lo que es útil si no quieres que los cambios en un slice afecten al otro.

  4. Correcto, puedes reducir la longitud de un slice cambiando sus límites como en el ejemplo que diste. Sin embargo, esto solo afecta la longitud, no la capacidad. Si quieres reducir la capacidad, podrías usar copy() para copiar los valores en un nuevo slice con menor capacidad.

Más preguntas →

  1. ¿Qué sucede si haces un slice de un array y luego expandes el slice más allá de la capacidad del array original?

  2. Si tienes un slice A y creas un nuevo slice B a partir de él (sin usar copy()), ¿qué sucede cuando modificas el contenido del slice B?

  3. ¿Cómo puedes inicializar un slice de longitud y capacidad cero usando make()?

  4. ¿Cuál es la diferencia en comportamiento entre un slice vacío []int{} y un slice nil en Go?

Respuestas:

  1. Incorrecto en parte. Si intentas expandir un slice más allá de la capacidad del array original con append(), Go creará un nuevo array que pueda acomodar los nuevos elementos, y el slice comenzará a referenciar este nuevo array. El array original permanece sin cambios. No habrá un error, simplemente se asignará un nuevo array en memoria si la capacidad se supera.

  2. Correcto, si creas un nuevo slice a partir de otro sin usar copy(), ambos slices compartirán el mismo array subyacente. Por lo tanto, modificar uno de los slices afectará al otro, ya que apuntan a la misma memoria.

  3. Correcto, has definido un slice con longitud y capacidad cero correctamente con make([]int, 0, 0).

  4. Correcto, un slice vacío ([]int{}) está inicializado pero no contiene elementos, mientras que un slice nil no ha sido inicializado en absoluto. Un slice nil tiene longitud y capacidad cero, pero también su referencia es nula, mientras que el slice vacío ya tiene una referencia asignada.


Conclusión:

Los mapas en GO son una herramienta poderosa para almacenar y recuperar datos de forma eficiente. Dominar las diferentes características de los mapas te ayudará a crear programas más robustos y escalables.

🐸
Array y Slice en Go (Golang) — SteemitSteemit
Arrays en GoOregoom.com
Logo
Logo