控制流
条件和循环都使用花括号。这样多写两笔,但读代码时很容易看出边界。
条件与循环
kelyra
fn clamp_to_zero(value: i32) -> i32 {
if value < 0 {
return 0;
} else {
return value;
}
}while 在条件为真时重复执行;break 结束循环,continue 开始下一轮。
for ... in
可迭代对象需要公开 iter(),其迭代器需要公开返回 Maybe<T> 的 next();迭代器本身有 next() 时也能直接遍历。
kelyra
import std.util.iterator;
import std.util.maybe;
class Cursor {
current: i32;
limit: i32;
pub init(current: i32, limit: i32) {
this.current = current;
this.limit = limit;
}
pub fn next() -> std.util.maybe.Maybe<i32> {
if current >= limit {
return std.util.maybe.none<i32>();
}
let value = current;
current = current + 1;
return std.util.maybe.some<i32>(value);
}
}
class Sequence {
first: i32;
limit: i32;
pub init(first: i32, limit: i32) {
this.first = first;
this.limit = limit;
}
pub fn iter() -> Cursor {
return Cursor(first, limit);
}
}
fn twice(value: i32) -> i32 { return value * 2; }
fn above_two(value: i32) -> bool { return value > 2; }
@main
fn main() -> i32 {
let total: i32 = 0;
for item in Sequence(1, 6) {
if item == 2 {
continue;
}
if item == 5 {
break;
}
total = total + item;
}
if total != 8 {
return 1;
}
let sequence = Sequence(0, 3);
for item in &sequence {
total = total + item;
}
if total != 11 {
return 2;
}
let numbers: [3]i32;
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
let view: []const i32 = numbers[:];
for item in std.util.iterator.slice<i32>(view) {
total = total + item;
}
if total != 17 {
return 3;
}
for item in std.util.iterator.pipe<i32>(view).map(twice).filter(above_two).take(1) {
total = total + item;
}
if total != 21 {
return 4;
}
let cursor = Cursor(0, 2);
for item in &cursor {
total = total + item;
}
if total != 22 {
return 5;
}
return 42;
}标准库的 std.util.iterator 提供切片适配器与惰性 pipe。目前 map 回调须是无捕获函数,且保持元素类型不变。
枚举与 match
纯枚举可以给成员指定整数值。match 支持枚举、布尔值和整数等值匹配;对枚举与布尔值要覆盖所有可能分支。
kelyra
enum Color: u8 {
Red,
Green = 3,
Blue,
}
enum Status {
Ready,
Done,
}
fn read_once(counter: *i32) -> Color {
*counter = *counter + 1;
return Color.Green;
}
fn early(flag: bool) -> i32 {
match flag {
true => {
return 2;
},
false => {
return 3;
},
};
}
@main
fn main() -> i32 {
let status: Status;
let counter: i32 = 0;
let color: i32 = match read_once(&counter) {
Color.Red => 1,
Color.Green => {
let value: i32 = 2;
value
},
Color.Blue => 3,
};
let truth: i32 = match Color.Red == Color.Red {
true => 1,
false => 0,
};
let number: i32 = match 7 {
3 => 10,
_ => 4,
};
let initial: i32 = match status {
Status.Ready => 1,
Status.Done => 0,
};
let code: i32 = (Color.Blue as u8) as i32;
return color + truth + number + initial + counter + early(false) + code;
}当前没有带载荷的枚举、范围模式和守卫。更多细节见枚举与 match 设计说明。