Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Rust中正确表示基于堆栈的语言?_Rust - Fatal编程技术网

如何在Rust中正确表示基于堆栈的语言?

如何在Rust中正确表示基于堆栈的语言?,rust,Rust,我试图模仿(Haskell)的第3节。特别是,我正在考虑使用基于堆栈的语言,而不是命令式语言,并且我正在尝试使用正确的惯用代码来表示数据 假设您想要制作一个小的(非常小的),它有一些基本的算术运算,没有用户定义的函数,并且可以处理十进制数和整数。例如: 1 2 + -> Stack contains: 3 发生什么事了?从左到右读取,在堆栈上按1和2,+将推出1和2,然后将3(=1+2)推到堆栈上 我的想法是要考虑 3 /代码>需要解析的“原语”类型。有整数、十进制数和函数。此外,

我试图模仿(Haskell)的第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>),
}