> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/all-out-docs/docs-es/programacion/arrays-and-collections.md).

# Referencia avanzada del lenguaje

CSL te ofrece unas cuantas herramientas “parecidas a arrays” que cubren la mayoría de las necesidades de gameplay: arrays fijos, slices y arrays dinámicos. Esta página es la guía práctica para usarlos sin pisar minas.

## Glosario rápido

* **Array fijo**: `[N]T` — su tamaño se conoce en tiempo de compilación.
* **Slice / array administrado**: `[]T` — una vista sobre datos de un array (a menudo usado para parámetros).
* **Array dinámico**: `[..]T` — lista redimensionable con `conteo` y `capacidad`.

```go
fixed: [4]int = {1, 2, 3, 4};
view: []int = fixed; // vista slice

list: [..]int = {10, 20};
```

{% hint style="info" %}
Los métodos de los arrays dinámicos usan llamadas normales con punto (por ejemplo, `list.append(x)`). Los campos también usan acceso con punto (por ejemplo, `list.count`).
{% endhint %}

## Arrays dinámicos (`[..]T`)

Los arrays dinámicos son el tipo de “lista por defecto” para el código de gameplay.

### Creación y añadido

```go
players_seen: [..]string = {"Ada", "Grace"};
players_seen.append(player.get_user_id());
```

Los literales de arrays dinámicos pueden contener expresiones en tiempo de ejecución y pueden devolverse directamente cuando el tipo esperado es `[..]T`:

```go
make_values :: proc(seed: int) -> [..]int {
    return {seed, seed + 1};
}
```

También se admiten valores por defecto de campos de clase en arrays dinámicos. Cada instancia de clase recibe almacenamiento mutable independiente:

```go
Loadout :: class {
    slots: [..]string = {"sword", "potion"};
}
```

### Reserva de capacidad (rendimiento)

Si sabes que vas a añadir muchos elementos, reserva primero para evitar reasignaciones repetidas.

```go
results: [..]Enemy;
results.reserve(128);
```

### Eliminación de elementos

Por lo general eliges entre **eliminación rápida** (el orden no importa) y **eliminación ordenada** (conservar el orden).

```go
values: [..]int;
values.append(10);
values.append(20);
values.append(30);

values.unordered_remove_by_value(20); // intercambia con el último, rápido
values.ordered_remove_by_value(10);   // desplaza, conserva el orden
```

También puedes eliminar por índice:

```go
values.unordered_remove_by_index(0);
values.ordered_remove_by_index(0);
```

### Vaciado

```go
values.clear(); // O(1): solo establece el conteo en 0
```

## Pasar arrays a procedimientos

Muchas API aceptan `[]T` (un slice/vista). Los arrays dinámicos pueden pasarse donde se espera `[]T` .

```go
sum :: proc(arr: []int) -> int {
    total := 0;
    for v: arr {
        total += v;
    }
    return total;
}

nums: [..]int;
nums.append(1);
nums.append(2);
nums.append(3);

total := sum(nums); // [..]int -> []int implícito
```

## Patrones de iteración

### Iterar elementos

```go
for v: nums {
    log_info("v=%", {v});
}
```

### Iterar índices

Usa `..<` cuando quieres un bucle normal de "0 hasta, pero sin incluir, count":

```go
for i: 0..<nums.count {
    log_info("nums[%]=%", {i, nums[i]});
}
```

Algunas colecciones del motor proporcionan iteradores. `inventory.slots()` visita cada ranura en orden, produce `null` para las ranuras vacías, y expone la ranura real como el índice opcional:

```go
for item, slot: inventory.slots() if item != null {
    log_info("el objeto % está en la ranura %", {item.get_definition().id, slot});
}
```

{% hint style="warning" %}
`..` los rangos son inclusivos. `..<` los rangos excluyen el límite superior.
{% endhint %}

Los bucles inversos usan `#reverse`:

```go
for i: 0..<nums.count #reverse {
    log_info("nums[%]=%", {i, nums[i]});
}
```

## Tablas hash

Usa `Hashtable(Key_Type, Value_Type)` cuando necesitas búsqueda rápida por clave. Admite claves enteras y de cadena, junto con los métodos habituales de búsqueda, inserción, sobrescritura, eliminación e iteración.

```go
scores: Hashtable(string, s64);
scores.add("alice", 10);
scores.add_or_overwrite("bob", 25);

score, ok := scores.find("alice");
if ok {
    log_info("puntuación de alice: %", {score});
}

for value, key: scores {
    log_info("% = %", {key, value});
}
```

Usa `add` cuando las claves duplicadas deben provocar una aserción. Usa `add_or_overwrite` cuando se espera actualizar una clave existente. `try_add` devuelve `true` si la clave ya existía y deja el valor anterior sin cambios.

## Clausuras y callbacks

Los literales de procedimiento pueden capturar valores del entorno, pero los procedimientos capturadores son expresiones de callback y no pueden almacenarse en colecciones ni en otras ubicaciones. Un parámetro de procedimiento debe marcarse `#no_captures` antes de poder almacenarse, y entonces quienes lo llamen solo podrán pasar procedimientos no capturadores; consulta [Clausuras y callbacks](/all-out-docs/docs-es/programacion/syntax.md#closures-and-callbacks) para las reglas de uso y el patrón de userdata explícito.

## Referencia de API

Cada proyecto incluye una `api_references/` carpeta que contiene la API central actual. Abre el `.csl_engine` archivo correspondiente para inspeccionar un tipo o procedimiento.
