ReScript:JavaScript 的 Rust 式特性
如果 Rust 是“披着机器学习外衣的 C++”,那么 ReScript 就是“披着机器学习外衣的 JavaScript”。
ReScript是什么?
ReScript是“来自未来的快速、简单、完全类型的 JavaScript”。这意味着 ReScript 拥有闪电般的编译器速度、易于学习的类 JavaScript 语法、强大的静态类型,以及模式匹配和变体类型等令人惊叹的特性。在 2020 年之前,它被称为“BuckleScript”,并且与ReasonML密切相关。
ReScript 正在不断发展壮大,并持续添加新功能,使其成为更具吸引力的 JavaScript 替代方案。ReScript v11近期发布,并带来了一些非常实用的用户体验改进。
让我们快速了解一下 Rust 和 ReScript 的一些共同特性,并举一些代码示例。
类型
Rust 和 ReScript 都是强类型、静态类型的语言,它们都源自 OCaml。所有元素都有类型,并且类型保证正确。与 TypeScript 不同的是,anyReScript 中没有类型定义。
ReScript 大量依赖类型推断,这有助于减少类型注释中的一些冗余信息。
// Typescript
let add = (a, b) => a + b // infers (any, any) => any
// ReScript
let add = (a, b) => a + b // infers (int, int) => int
您可以根据需要添加类型注解。
// ReScript
let add = (a: int, b: int): int => a + b
基于表达式
Rust 和 ReScript 都是基于表达式的语言,这意味着大多数代码行或代码块都会返回一个值。你也不需要为表达式显式地编写 return 语句,代码块中的最后一个值就是返回值。
// rust
fn main() {
let y = {
let x = 3;
x + 1
};
println!("The value of y is: {y}"); // the value of y is: 4
}
// rescript
let main = () => {
let y = {
let x = 3
x + 1
}
Console.log(`The value of y is: ${y->Int.toString}`) // the value of y is: 4
}
模式匹配
模式匹配是一种强大的方法,可以根据类型或数据进行条件判断。您可以将其视为一个功能强大的switch语句,可以匹配数据类型或值。如果您未能处理所有可能的情况,Rust 和 ReScript 会报错,这使得重构更加容易。如果您需要添加新的情况,您将确切地知道应该在代码的哪个位置进行修改,以确保正确处理。
// Rust
fn main() {
let n = 42;
match n {
10 => println!("The number ten."),
42 => println!("Answer to the Ultimate Question of Life, the Universe, and Everything."),
_ => println!("Some other number."),
}
}
// rescript
let main = () => {
let x = 42
switch x {
| 10 => Console.log("The number ten.")
| 42 =>
Console.log(
"Answer to the Ultimate Question of Life, the Universe, and Everything.",
)
| _ => Console.log("Some other number.")
}
}
带标签的联合类型和变体类型
Rust 的标记联合体和 ReScript 变体类型不仅允许你创建类型,还允许你为该类型赋予数据。这可以与模式匹配结合使用,以确保处理所有可能的情况。
我写的这篇文章展示了如何使用 ReScript 的变体类型将业务逻辑与编译器连接起来。
// Rust
enum Widget {
Red(u8),
Blue(u8),
None,
}
fn main() {
let x = Widget::Red(42);
match x {
Widget::Red(_) => println!("You have a red widget!"),
Widget::Blue(_) => println!("You have a blue widget!"),
Widget::None => println!("You have no widget!"),
}
}
// ReScript
type widget =
| Red(int)
| Blue(int)
| None
let main = () => {
let x = Red(42)
switch x {
| Red(_) => Console.log("You have a red widget!")
| Blue(_) => Console.log("You have a blue widget!")
| None => Console.log("You have no widget!")
}
}
Option而不是undefined或null
无需处理空值或未定义错误可以节省大量时间,并避免生产环境中的错误和麻烦。Option它强制您显式处理任何可能未定义的值,并且这种类型化方式可以清晰地表明何时预期某个值未定义。
// Rust
fn main() {
let n = Some("Josh");
match n {
Some(name) => println!("Hello there {:?}!", name),
None => println!("Who are you?")
}
}
// rescript
let main = () => {
let n = Some("Josh")
switch n {
| Some(name) => Console.log(`Hello there ${name}!`)
| None => Console.log("Who are you?")
}
}
Result而不是抛出错误
这两种语言都提供了一种Result类型,可以表示表达式执行失败后的响应。这有助于处理预期错误,避免程序崩溃。预期错误可能包括 API 超时或400错误请求的响应。它允许程序跟踪错误信息并优雅地处理错误,而无需抛出异常。
// rust
fn main() {
let n: Result<&str, &str> = Ok("Josh");
match n {
Ok(name) => println!("Hello there {:?}!", name),
Err(err) => println!("Error: {:?}", err),
}
}
// rescript
let main = () => {
let n: result<string, string> = Ok("Josh")
switch n {
| Ok(name) => Console.log(`Hello there ${name}`)
| Error(err) => Console.log(`Error: ${err}`)
}
}
了解更多关于ReScript的信息
如果您有兴趣了解更多关于 ReScript 的信息,请访问官方网站或访问论坛!
文章来源:https://dev.to/jderochervlk/rescript-rust-like-features-for-javascript-27ig