Skip to content

表达式

表达式是能产生值的代码片段。RedScript 的表达式从简单的字面量到复杂的 match 表达式都有涵盖。


字面量

整数字面量

rs
42
-7
0
2147483647

类型:int(32 位有符号计分板整数)。

double / 定点数字面量

rs
3.14        // 类型:fixed(内部存储为 31400)
-0.5        // 类型:fixed
45.0 as double  // 类型:double

带小数点的字面量默认是 fixed(×10000 存储)。要得到 double,需显式转换:1.5 as double

字符串字面量

rs
"hello"
f"Score: {score}"   // 使用 {expr} 的 f-string 插值

字符串是不可变的文本值。标准插值写法是 f-string:f"...{expr}..."。普通字符串("...")不会插值。

布尔字面量

rs
true
false

类型:bool

Option 字面量

rs
Some(42)        // 包装一个 Option<int> 值
Some("hello")   // 包装一个 Option<string> 值
None            // 空的 Option

Some(x)NoneOption<T> 的两个构造器。另见下文的 if let / match


运算符

算术运算符

运算符描述示例
+加法a + b
-减法a - b
*乘法a * b
/除法a / b
%取余(取模)a % b
-(一元)取负-a

fixed 运算: fixed 运算是按比例正确实现的。正常使用 */ 即可,编译器会在下降阶段加入 ×10000 补偿。 math.mcrs 的遗留辅助函数仍可能使用 ×1000 比例(如 mulfixdivfixsin_fixed 等),它们不是语言级 fixed

比较运算符

运算符描述示例
==等于a == b
!=不等于a != b
<小于a < b
>大于a > b
<=小于等于a <= b
>=大于等于a >= b

逻辑运算符

运算符描述示例
&&a && b
||a || b
!!a

运算符优先级(由高到低)

优先级运算符结合性
7-(一元)、!
6*/%
5+-
4<><=>=
3==!=
2&&
1||

使用括号可覆盖默认优先级:

rs
let x: int = (2 + 3) * 4;   // 20,而不是 14

函数调用

rs
// 普通函数调用
say("Hello, world!");

// 带参数
tell(@a, f"你有 {score} 分");
give(@s, "diamond", 3);

参数从左到右依次求值,然后调用函数。


方法调用

方法通过点号在值上调用:

rs
let v: Vec2 = Vec2 { x: 3, y: 4 };
let len: int = v.length_sq();   // 调用 Vec2::length_sq
let scaled: Vec2 = v.scale(2);  // 调用 Vec2::scale

链式方法调用

当每个方法都返回一个值时,可以链式调用:

rs
let result: Vec2 = v.scale(2).add(other);

数组索引

arr[index] 访问数组元素:

rs
let arr: int[] = [10, 20, 30];
let first: int = arr[0];   // 10
let last: int  = arr[2];   // 30

索引从 0 开始。越界访问是未定义行为。


结构体字段访问

. 访问结构体字段:

rs
struct Point { x: int, y: int }

let p: Point = Point { x: 3, y: 7 };
let px: int = p.x;   // 3
let py: int = p.y;   // 7

类型转换

as 将值转换为另一种类型:

rs
let x: int    = 42;
let f: fixed  = x as fixed;    // int → fixed(× 10000)
let d: double = x as double;   // int → double
let back: int = f as int;      // fixed → int(÷ 10000,截断小数)

完整转换语义见 types.md


Option 构造器

rs
let a: Option<int>    = Some(42);
let b: Option<string> = Some("hello");
let c: Option<int>    = None;

Option<T> 是内置泛型类型,表示可能为空的值。Some(expr) 包装一个值;None 表示缺失。


enum 构造器

简单 enum(无载荷)

rs
enum Direction { North, South, East, West }

let dir: Direction = Direction::North;

带载荷字段的 enum

rs
enum Color {
    Red,
    RGB(r: int, g: int, b: int),
}

let c: Color = Color::RGB(r: 255, g: 128, b: 0);

载荷字段必须命名。在括号内以 field: value 对的形式传入。


match 表达式

match 对表达式的值进行分支。每个 arm 有一个模式和一个代码块。

匹配整数 / 范围

rs
let score: int = 85;

match score {
    90..100 => { say("A"); },
    80..89  => { say("B"); },
    70..79  => { say("C"); },
    _       => { say("不及格"); },
}

范围两端均包含min..max)。_ 是通配符 arm。

匹配 enum

rs
enum Phase { Idle, Moving, Attacking }

let phase: Phase = Phase::Moving;

match phase {
    Phase::Idle      => { say("休息中"); },
    Phase::Moving    => { say("移动中"); },
    Phase::Attacking => { say("攻击!"); },
}

匹配带载荷的 enum

rs
match color {
    Color::RGB(r, g, b) => { tell(@s, f"r={r} g={g} b={b}"); },
    Color::Red           => { say("纯红"); },
    _                    => { },
}

匹配 Option

rs
let maybe: Option<int> = find_score(@p);

match maybe {
    Some(v) => { tell(@s, f"分数:{v}"); },
    None    => { say("未找到分数"); },
}

unwrap_or

安全地从 Option<T> 中提取值,如果为 None 则返回默认值:

rs
let maybe: Option<int> = find_score(@p);
let score: int = maybe.unwrap_or(0);   // 如果为 None,返回 0

等价于:

rs
let score: int = match maybe {
    Some(v) => v,
    None    => 0,
};

Lambda 表达式

rs
let double = (x: int) => x * 2;

let clamp = (v: int) => {
    if (v < 0) { return 0; }
    if (v > 100) { return 100; }
    return v;
};

Lambda 捕获词法作用域,可以传递给高阶函数。

Released under the MIT License.