Fundamentos
Archivos, espacios de nombres, Main, comentarios, variables, tipos primitivos, literales, operadores, flujo de control y cadenas en Antril.
En esta página
Esta página cubre lo que usa cualquier archivo de Antril. Para empezar, aquí tienes un programa completo:
import System;
into namespace Tour
{
/// Sums the numbers below `limit` that are multiples of 3 or 5.
SumOfMultiples(i32 limit) : i32
{
i32 total = 0;
loop (i32 n = 1..limit)
{
if (n % 3 == 0 || n % 5 == 0)
total += n;
}
return total;
}
Main()
{
i32 result = SumOfMultiples(10);
Console.WriteLine($"The sum is {result}");
}
}
larva run
The sum is 23
Archivos y espacios de nombres
Un archivo .ant es una lista de import seguida de declaraciones: tipos, funciones y constantes.
into namespace Name { … } coloca declaraciones dentro de un espacio de nombres. El mismo espacio de nombres puede abrirse en muchos archivos y bibliotecas. Las declaraciones que están fuera de cualquier bloque into namespace pertenecen al espacio de nombres global.
import hace visibles nombres en todo el archivo:
| Forma | Qué hace visible |
|---|---|
import System; |
Todos los nombres públicos de System. |
import List, Dictionary from System; |
Solo esos nombres. |
import System.Text as T; |
El espacio de nombres con otro nombre: T.JsonValue. |
import A, B from D as X, Y; |
Esos nombres, cada uno con el alias que ocupa su misma posición. |
Siempre puedes escribir un nombre completo en su lugar: System.Console.WriteLine("hi").
Un tipo o una función también puede indicar su espacio de nombres en su encabezado, relativo al lugar donde está escrito. Equivale a envolverlo en un bloque into namespace:
import System;
public class Shape into namespace Geo
{
public:
static Sides() : i32 => 4;
}
Area(f64 side) : f64 into namespace Geo => side * side;
Main()
{
Console.WriteLine(Geo.Area(3) + Geo.Shape.Sides());
}
Main
Un programa empieza en una función libre llamada Main. Hay exactamente una por programa.
Main()
{
Console.WriteLine("hello");
}
Main también puede declararse con un resultado entero, Main() : i32: Larva imprime ese resultado cuando el programa termina. Main puede recibir números desde la línea de comandos, pero todavía no texto; consulta Archivos fuente.
Comentarios
// To the end of the line.
/* Across
several lines. */
/// A documentation comment: it describes the declaration below it.
/// The editor shows it on hover, and `larva show` prints it.
Area(f64 w, f64 h) : f64 => w * h;
Variables y constantes
Una variable se declara con su tipo primero. Varias variables del mismo tipo pueden compartir una declaración.
i32 count = 0;
str name = "Antril";
i32 width = 4, height = 3;
Una variable de un tipo valor (números, bool, tipos value) a la que no se le asigna nada empieza en cero.
const declara una constante. Su valor se calcula cuando el programa se compila, y puede declararse en un espacio de nombres, en un tipo o dentro de un cuerpo.
import System;
into namespace Config
{
const i32 Retries = 3;
const str Name = "server";
const str Label = Name + "-" + "main";
const i64 Big = Int32.MaxValue + 1i64;
Main()
{
const f64 Half = 0.5;
Console.WriteLine(Label);
Console.WriteLine(Big);
Console.WriteLine(Retries * Half);
}
}
larva run
server-main
2147483648
1.5
nameof(x) da el nombre de una variable, miembro, tipo o función como una cadena constante: nameof(count) es "count", y nameof(i32) es "Int32".
Tipos primitivos
| Tipo | Qué es |
|---|---|
bool |
true o false. |
i8 i16 i32 i64 i128 i256 |
Enteros con signo de 8 a 256 bits. |
u8 u16 u32 u64 u128 u256 |
Enteros sin signo de 8 a 256 bits. |
f16 f32 f64 f128 f256 |
Números de punto flotante IEEE de 16 a 256 bits. |
iptr uptr |
Enteros del tamaño de un puntero. |
str |
Texto: un System.String. |
any |
Cualquier valor: la raíz de todas las clases (System.Any). Un valor guardado en any se encapsula (boxing). |
void |
Ningún valor: lo que devuelve una función sin resultado. |
Cada primitivo es un tipo de la biblioteca estándar (i32 es System.Int32, f64 es System.Float64), con miembros como Int32.MaxValue, Int32.Parse(text) y ToString().
Antril no tiene un tipo de carácter aparte. Un literal de carácter como 'A' es su punto de código, un número: un u16 cuando no se espera otro tipo. System.Char tiene funciones sobre puntos de código, como Char.IsDigit('7').
Literales
import System;
Main()
{
i32 count = 42;
i64 big = 9_000_000_000;
u8 small = 255u8;
f32 ratio = 0.5f32;
f64 pi = 3.14159;
i32 mask = 0xFF;
i32 bits = 0b1010;
u128 huge = 340282366920938463463374607431768211455u128;
u16 letter = 'A';
bool ready = true;
str name = "Antril\n";
Console.WriteLine(count + mask + bits);
Console.WriteLine(big);
Console.WriteLine(huge);
Console.WriteLine(letter);
Console.Write(name);
}
larva run
307
9000000000
340282366920938463463374607431768211455
65
Antril
- Un literal entero es un
i32, o uni64si no cabe. Un literal con punto decimal es unf64. Donde se espera un tipo, el literal toma ese tipo. - Un sufijo indica el tipo:
255u8,1i64,0.5f32,3f128. 0xinicia un número hexadecimal y0buno binario._separa dígitos.- Las cadenas usan los escapes
\n,\t,\"y\\. nulles el valor vacío de un tipo anulable (consulta Tipos).
Conversiones
Las conversiones que no pueden perder información son implícitas: un entero a otro más ancho del mismo signo, un entero sin signo a uno con signo más ancho, un entero a un flotante, f32 a f64. Todo lo demás necesita una conversión explícita (cast):
i64 wide = 5; // implicit
i32 narrow = (i32)wide; // a cast
i8 truncated = (i8)200; // -56: a cast keeps the low bits
i32 whole = (i32)3.9; // 3
Operadores
| Categoría | Operadores |
|---|---|
| Aritméticos | + - * / %, y -x |
| Comparación | == != < <= > >= |
| Lógicos | && || ! |
| A nivel de bits | & | ^ ~ << >> |
| Asignación | = += -= *= /= %= &= |= ^= <<= >>= |
| Incremento | ++ -- (antes o después de la variable) |
| Condicional | c ? a : b |
| Nulos | a ?? b (a salvo que sea null), a?.b (null si a es null) |
| Tipos | x is T, x is T name, x as T |
| Rangos | a..b (excluye b), a..=b (incluye b) |
+ concatena cadenas, y convierte en texto un número o un objeto que esté del otro lado: "n = " + 5 es "n = 5". == sobre cadenas compara su contenido.
Los tipos pueden declarar sus propios operadores; consulta Funciones y genéricos.
Flujo de control
if
if (temperature > 30)
Console.WriteLine("hot");
else if (temperature > 15)
Console.WriteLine("mild");
else
Console.WriteLine("cold");
Las llaves solo hacen falta cuando hay más de una instrucción.
loop
Antril tiene una sola palabra clave para todo tipo de bucle:
| Forma | Qué hace |
|---|---|
loop (T x in items) { … } |
Cada elemento de un arreglo, una cadena o una colección. |
loop (condition) { … } |
Mientras se cumpla la condición. loop (true) se repite hasta un break. |
do { … } loop (condition); |
Se ejecuta una vez y luego mientras se cumpla la condición. |
loop (i32 i = 0..10) { … } |
i de 0 a 9. 0..=10 incluye el 10. |
loop (i32 i = 0; i < 10; i += 2) { … } |
Inicio, condición, paso. |
loop (i32 i = 1) { … } |
Sin fin: i empieza en 1 y aumenta en uno cada vez. |
break sale del bucle y continue pasa a la siguiente vuelta.
import System;
Main()
{
loop (i32 i = 0..3)
Console.Write(i);
Console.WriteLine();
loop (i32 k = 0; k < 10; k += 3)
Console.Write(k);
Console.WriteLine();
i32 n = 1;
loop (n < 100)
n *= 3;
Console.WriteLine(n);
do n -= 50; loop (n > 0);
Console.WriteLine(n);
loop (i32 c = 1)
{
if (c > 3)
break;
Console.Write(c);
}
Console.WriteLine();
loop (str word in ["alpha", "beta"])
Console.WriteLine(word.ToUpper());
}
larva run
012
0369
243
-7
123
ALPHA
BETA
switch
switch compara un valor con patrones, como instrucción o como expresión. _ coincide con cualquier cosa.
import System;
Describe(i32 n) : str => n switch
{
< 0 => "negative",
0 => "zero",
1..10 => "small",
_ => "large",
};
Main()
{
i32 count = 2;
switch (count)
{
0 => Console.WriteLine("none");
1 or 2 => Console.WriteLine("a few");
_ => Console.WriteLine("many");
}
Console.WriteLine(Describe(-3) + ", " + Describe(5) + ", " + Describe(50));
}
larva run
a few
negative, small, large
Los patrones pueden ser:
- constantes:
0,"abc",Color.Red; - comparaciones:
< 0,>= 90; - rangos:
1..10,1..=9; - combinaciones con
and,orynot; - tipos, con un nombre opcional:
Circle c; - propiedades:
{ X: 0, Y: > 1 }; - posiciones, para registros, tuplas y tipos con
Deconstruct:Point(0, var y),(1, _); null.
Una condición when después de un patrón agrega una comprobación: Circle c when c.Radius > 10 => …. Los mismos patrones funcionan después de is: if (p is { X: 0 }).
Cadenas
str es texto inmutable. Algunos de sus miembros:
str s = " Hello World ".Trim();
s.Length; // 11
s.ToUpper(); // "HELLO WORLD"
s.Substring(6, 5); // "World"
s.IndexOf("World"); // 6
s.StartsWith("Hell"); // true
s.Replace("World", "you"); // "Hello you"
"a,b,c".Split(','); // a List<str>
String.Join("-", parts); // joins a list
Una cadena interpolada empieza con $. Cada {…} contiene una expresión, con un ancho opcional después de , (negativo: alineado a la izquierda) y un formato después de ::
import System;
Main()
{
f64 price = 3.5;
i32 quantity = 4;
Console.WriteLine($"{quantity} x {price} = {price * quantity}");
Console.WriteLine($"[{quantity,5}] [{quantity,-5}] [{price:F2}]");
}
larva run
4 x 3.5 = 14
[ 4] [4 ] [3.50]
Para construir un texto largo poco a poco, usa StringBuilder (consulta la descripción general de la biblioteca).
Escribir en la consola
Console.WriteLine escribe un valor y un salto de línea; Console.Write escribe sin el salto de línea. Ambos aceptan todos los tipos primitivos, cadenas y cualquier otro valor (que se muestra con su ToString()). Console.ReadLine() lee una línea, o devuelve null al final de la entrada.
Como un literal de carácter es un número, Console.Write('A') escribe 65. Escribe "A" si quieres texto.
Siguiente: Tipos.
Editar esta página en GitHub Reportar un problema