如何在Rust中正确表示基于堆栈的语言?
我试图模仿(Haskell)的第3节。特别是,我正在考虑使用基于堆栈的语言,而不是命令式语言,并且我正在尝试使用正确的惯用代码来表示数据 假设您想要制作一个小的(非常小的),它有一些基本的算术运算,没有用户定义的函数,并且可以处理十进制数和整数。例如:如何在Rust中正确表示基于堆栈的语言?,rust,Rust,我试图模仿(Haskell)的第3节。特别是,我正在考虑使用基于堆栈的语言,而不是命令式语言,并且我正在尝试使用正确的惯用代码来表示数据 假设您想要制作一个小的(非常小的),它有一些基本的算术运算,没有用户定义的函数,并且可以处理十进制数和整数。例如: 1 2 + -> Stack contains: 3 发生什么事了?从左到右读取,在堆栈上按1和2,+将推出1和2,然后将3(=1+2)推到堆栈上 我的想法是要考虑 3 /代码>需要解析的“原语”类型。有整数、十进制数和函数。此外,
1 2 +
-> Stack contains: 3
发生什么事了?从左到右读取,在堆栈上按1和2,+
将推出1
和2
,然后将3
(=1+2
)推到堆栈上
我的想法是要考虑<代码> 3 /代码>需要解析的“原语”类型。有整数、十进制数和函数。此外,小数和整数都是“名词”,函数是“动词”。因此,当执行一个程序时,我的想法是,通过扩展
结果
枚举的概念,您可以在Rust中表示这些想法。我提出了以下方案:
enum Noun {
Integer(i64),
Decimal(f64)
}
enum Primitive<T> {
Noun(T),
Verb(Fn(Vec<Noun>) -> Noun),
}
// Not really important, just giving a main so it can be ran
fn main() {
println!("Hello, world!");
}
在Rust中这样做的标准方法是什么?类型Fn(Vec)->名词描述一个trait对象,表示该特征的任何类型的占位符。由于该特性可以通过捕获额外变量的普通函数或闭包来实现,因此编译器无法知道为此类对象分配多少空间。trait对象是“动态大小”的,因此不能存在于堆栈上
解决错误消息的一个选项是将存储在堆上:
enum Primitive<T> {
Noun(T),
Verb(Box<dyn Fn(Vec<Noun>) -> Noun>),
}
函数指针只能指向不捕获任何变量的普通函数或闭包,因此是静态大小的,因此可以存储在堆栈上
就个人而言,我可能会实现一个名为Function
或类似的定制特性,并使用
enum Primitive<T> {
Noun(T),
Verb(Box<dyn Function>),
}
enum原语{
名词(T),
动词(方框),
}
自定义trait将为您提供更大的灵活性,可以将元数据和其他方法附加到trait对象,例如检索函数将使用的输入数量的方法
enum Primitive<T> {
Noun(T),
Verb(fn(Vec<Noun>) -> Noun),
}
enum Primitive<T> {
Noun(T),
Verb(Box<dyn Function>),
}