1 个稳定版本
1.0.0 | 2024 年 4 月 1 日 |
---|
#649 在 Rust 模式
8KB
79 行
flip_flop.rs
此库实现了从 Perl 和 Ruby 中提取的 翻转操作符,作为一个 Rust 宏。
变更日志
- 2024 年 4 月 1 日:版本 1.0.0。
用法
宏 flip_flop!
接受两个布尔表达式,用括号包裹并使用两个点 (..
) 或三个点 (...
) 分隔。
flip_flop!((x == 5)..(x == 10))
// or
flip_flop!((x == 5)...(x == 10))
该宏从左表达式为真时返回 true,直到右表达式为真,通过维护一个隐藏的 bool 状态来实现。
..
和 ...
之间的区别是,在 ...
中,当左表达式首次变为真时,也会评估右表达式,这使得可以在同一迭代中将翻转内部状态重置。此行为与 Perl 匹配。
操作符的内部状态存储在静态的 AtomicBool
中,因此线程之间共享,类似于 Perl 的行为。
示例
以下代码中的打印语句从 i == 5
变为真时开始执行,直到 i == 10
变为真。
use flip_flop::flip_flop;
fn main() {
for i in 0..20 {
// Prints 5, 6, 7, 8, 9, 10.
if flip_flop!((i == 5)..(i == 10)) {
println!("{i}")
}
}
}
输出
5
6
7
8
9
10
提取序列示例
以下代码提取所有以 1
开始,后跟任何数字,直到找到 2
的序列。
use flip_flop::flip_flop;
fn main() {
let xs = [0, 1, 2, 0, 0, 1, 0, 2, 0, 0, 0, 0, 2, 2, 2, 0, 1, 1, 2, 0];
let ys = xs
.into_iter()
.filter(|&x| flip_flop!((x == 1)..(x == 2)))
.collect::<Vec<_>>();
println!("Original: {:?}", xs);
println!("Filtered: {:?}", ys);
}
输出
Original: [0, 1, 2, 0, 0, 1, 0, 2, 0, 0, 0, 0, 2, 2, 2, 0, 1, 1, 2, 0]
Filtered: [1, 2, 1, 0, 2, 1, 1, 2]
FizzBuzz 示例
这是使用翻转操作符实现的经典 FizzBuzz 问题。 来源。
use flip_flop::flip_flop;
// https://juliansimioni.com/blog/deconstructing-fizz-buzz-with-flip-flops-in-ruby
fn main() {
let (mut a, mut b, mut c) = (false, false, false);
for i in 1..=100 {
#[rustfmt::skip]
println!(
"{}\r{}{}",
i,
if flip_flop!(({a = !a; a})..({a = !a; a})) { "" } else { "Fizz" },
if flip_flop!(({b = !b; b})...(!flip_flop!(({c = !c; c})..({c = !c; c})))) { "" } else { "Buzz" },
);
}
}
输出(移除后 \r
隐藏的文本)
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
…
错误
此 crate 的行为应与 Perl 和 Ruby 匹配,但可能存在未正确处理的情况。如果您发现任何错误,请提出问题(或拉取请求)!
许可证
本项目受以下任一许可证的许可:
- Apache 许可证第 2.0 版 (https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (https://opensource.org/licenses/MIT)
任由您选择。