Central Docs
Catálogo Inicio

`buffer`

buffer representa un bloque de memoria dinámica cruda compuesto por bytes. Su tamaño es exacto y forma parte de la declaración. Un buffer no crece ni cambia de capacidad después de ser creado.

buffer no es un alias de byte[N]:

  • byte[N] es un array ordinario con almacenamiento estático según el contexto donde se declare;
  • buffer[N] solicita una reserva de memoria dinámica de exactamente N bytes.

No existe conversión implícita entre ambos tipos.

Creación

El tamaño debe ser una expresión entera resoluble en compilación y debe ser mayor que cero:

datos: buffer[8 * 100] = 0

La reserva contiene exactamente 800 bytes. El inicializador escalar 0 rellena toda la reserva con cero; no crea un solo elemento de tamaño 800.

El tamaño no puede ser cero ni negativo:

empty: buffer[0]       ; error
negative: buffer[-4]   ; error

La memoria se solicita en tiempo de ejecución, pero su capacidad queda determinada por el tipo durante la compilación.

Escritura y lectura

Un buffer[N] puede indexarse como una secuencia de byte:

datos: buffer[4] = 0
datos[0] = 65
datos[1] = 66
value: byte = datos[0]

El índice debe referirse a una posición entre 0 y N - 1. En código seguro, un índice cuyo valor solo se conozca en tiempo de ejecución debe comprobarse contra la capacidad del buffer. Un acceso fuera de rango produce un error de ejecución; no se convierte silenciosamente en aritmética de punteros.

El contenido de un buffer es mutable y se interpreta como datos crudos. El tipo no añade terminación NUL, semántica de texto ni conversión automática a char[] o chain.

Tamaño inferido

Los corchetes vacíos pueden usarse cuando el inicializador permite calcular la capacidad completa:

buffer1: buffer[3] = {1, 2, 3}
buffer2: buffer[2] = {4, 5}
gigante: buffer[] = buffer1 + buffer2

En este caso, gigante se resuelve como buffer[5].

buffer[] en una declaración con inicializador no significa un buffer de tamaño desconocido ni uno que pueda crecer. Significa que el compilador debe inferir la capacidad a partir del valor inicial.

Concatenación

La suma de dos buffers crea una nueva reserva y copia sus contenidos en orden:

left: buffer[2] = {10, 20}
right: buffer[3] = {30, 40, 50}
all: buffer[] = left + right ; buffer[5]

La capacidad resultante es la suma de las capacidades de los operandos:

buffer[N1] + buffer[N2] = buffer[N1 + N2]

Los operandos originales no se modifican. La operación no amplía ninguno de ellos y puede fallar si no es posible obtener la nueva reserva.

Liberación

Del reconoce el tipo buffer y libera el bloque dinámico que posee la variable:

datos: buffer[8 * 100] = 0
Del datos

Después de liberar, el descriptor de datos queda en cero. Del no es un método y no añade atributos implícitos al tipo.

Parámetros de función

Un buffer puede recibirse como préstamo y debe declarar Len_t:

func consume(data: buffer[], length: Len_t) usize:
    return length

Len_t contiene la longitud actual en bytes del descriptor. Size_t no se admite para buffer, porque todos sus elementos tienen tamaño 1.

buffer[N] exige un buffer con esa capacidad exacta; buffer[] acepta cualquier capacidad conocida en tiempo de ejecución. El parámetro conserva el descriptor por valor, pero la memoria sigue perteneciendo al llamador: la función receptora no puede ejecutar Del sobre él.

También puede declararse un préstamo exclusivo:

func consume(data: unique buffer[], length: Len_t, region: Region_t) usize:
    return length

Region_t es inmutable, oculto en la llamada y solo se acepta cuando el compilador demuestra una procedencia de almacenamiento concreta. La función no puede recibir dos argumentos que representen la misma región unique. Los buffers mantienen su descriptor por valor; por eso esta comprobación no cambia todavía la ABI ni añade noalias al descriptor.

Todavía no se permite copiar buffers ni retornarlos desde una función. La transferencia de propiedad se definirá después con el ABI correspondiente; esto evita aliasing y dobles liberaciones mientras esa regla no exista.

Alcance actual

Este documento fija la representación, creación, indexación, inicialización, concatenación, liberación y expansión Len_t de buffer. La transferencia de propiedad, el retorno desde funciones y la liberación automática al salir de un ámbito quedan pendientes.