📖 语言基础
TLL 是一门静态类型、支持类型推断的现代编程语言。本章介绍核心语法:变量、类型、函数、控制流、错误处理。
1. 变量与绑定
TLL 中不可变是默认,可变需要显式声明。
let x = 5 // 不可变,类型推断为 int
let y: int = 10 // 不可变,显式类型
mut z = 0 // 可变,类型推断
mut counter: int = 0 // 可变,显式类型
const MAX = 100 // 编译期常量
// 变量遮蔽(Shadowing)允许
let x = 5
let x = x + 1 // 新绑定,旧 x 被遮蔽(非修改)
2. 类型系统
基本类型
| 类型 | 说明 | 默认值 |
|---|---|---|
bool | 布尔 | false |
int | 任意精度整数 | 0 |
i8/i16/i32/i64 | 有符号固定宽度 | 0 |
u8/u16/u32/u64 | 无符号固定宽度 | 0 |
float | 64 位浮点数 | 0.0 |
str | 不可变 UTF-8 字符串 | "" |
char | Unicode 标量值 | '\0' |
复合类型
// 数组(固定大小)
let nums: [int; 5] = [1, 2, 3, 4, 5]
// 列表(动态数组)
let items: List[int] = [1, 2, 3]
items.push(4)
// 映射
let scores: Map[str, int] = {"alice": 95, "bob": 87}
// 元组
let point: (int, int) = (10, 20)
let person: (str, int, bool) = ("Alice", 30, true)
// 结构体
pub struct User {
id: int,
name: str,
email: Option[str],
active: bool = true,
}
// 枚举(代数数据类型)
pub enum Shape {
Circle(float),
Rectangle(float, float),
Point { x: float, y: float },
}
// 可选类型
let nickname: Option[str] = None
let email: str? = null // Option[str] 的语法糖
3. 函数
fn add(a: int, b: int) -> int {
return a + b
}
// 单表达式函数(隐式返回)
fn multiply(a: int, b: int) -> int = a * b
// 无返回值函数
fn greet(name: str) {
io.println("Hello, " + name)
}
// 函数作为值(一等公民)
let op: fn(int, int) -> int = add
let result = op(3, 4) // 7
// 函数类型别名
type BinaryOp = fn(int, int) -> int
4. 控制流
If / Else(也是表达式)
if x > 0 {
io.println("positive")
} else if x < 0 {
io.println("negative")
} else {
io.println("zero")
}
// If 是表达式
let sign = if x > 0 { "positive" } else { "zero" }
循环
// while
mut i = 0
while i < 10 {
io.println(i)
i += 1
}
// for(范围)
for i in 0..10 { // 0 到 9
io.println(i)
}
for i in 0..=10 { // 0 到 10(含)
io.println(i)
}
// for(迭代器)
for item in items {
io.println(item)
}
// break / continue
for i in 0..100 {
if i == 50 { break }
if i % 2 == 0 { continue }
io.println(i)
}
Match 模式匹配
match shape {
Shape.Circle(r) => io.println("circle r={r}"),
Shape.Rectangle(w, h) => io.println("rect {w}x{h}"),
Shape.Point { x, y } => io.println("point ({x},{y})"),
}
// 穷尽性检查:遗漏分支编译错误
// 通配符 _
match code {
200 => "OK",
404 => "Not Found",
_ => "Other",
}
// Match 是表达式
let message = match status {
Ok(data) => "Success: {data}",
Err(e) => "Error: {e}",
}
5. 错误处理
TLL 使用 Result[T, E] 处理可恢复错误,panic 处理不可恢复错误。不支持 try/catch,错误即值。
fn divide(a: int, b: int) -> Result[int, DivideError] {
if b == 0 {
return Err(DivideError.ByZero)
}
return Ok(a / b)
}
// match 处理
match divide(10, 2) {
Ok(result) => io.println("result: {result}"),
Err(e) => io.println("error: {e}"),
}
// ? 操作符(错误传播)
fn calculate() -> Result[int, Error] {
let a = parse_int("42")?
let b = parse_int("10")?
return Ok(a + b)
}
// unwrap(Err 时 panic,谨慎使用)
let value = divide(10, 2).unwrap()
let value = divide(10, 0).unwrap_or(0)
// panic(不可恢复)
fn assert_positive(x: int) {
if x <= 0 {
panic("expected positive, got {x}")
}
}
6. 字符串插值
let name = "Alice"
let age = 30
let message = "Name: {name}, Age: {age}, Next: {age + 1}"
7. 管道操作符
// 嵌套调用
let result = parse(validate(transform(input)))
// 管道(左值作为右函数的第一个参数)
let result = input
|> transform
|> validate
|> parse
// 带参数
let result = input |> transform(mode: "fast") |> validate(strict: true)
8. Defer
fn process_file(path: str) -> Result {
let file = File.open(path)?
defer file.close() // 函数退出时执行,LIFO 顺序
let content = file.read_all()?
io.println(content)
return Ok(void)
}