如何实例化基于闭包的类型
How to instantiate a type that is based on a closure
在我的项目中,我使用类型定义来保存具有特定函数签名的闭包,如下所示:
// Standardized function signature
pub type InternalOperation = impl Fn(Ast, Rc<RefCell<VTable>>, Rc<RefCell<FTable>>) -> Ctr;
pub struct ExternalOperation {
// ...
// The project is on gitlab called relish if you are interested
}
/* A stored function may either be a pointer to a function
* or a syntax tree to eval with the arguments
*/
pub enum Operation {
Internal(InternalOperation),
External(ExternalOperation)
}
// function which does not need args checked
pub struct Function {
pub function: Operation,
// many more things like argument types and function name
}
我尝试实例化一个函数:
pub fn get_export(env_cfg: bool) -> Function {
return Function{
name: String::from("export"),
loose_syms: true,
eval_lazy: true,
args: Args::Lazy(2),
function: Operation::Internal(
|a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> Ctr {
// so much logic here to manage variables in b
// if env_cfg is true, entries in b are tied to environment variables
})
}
}
但是我遇到了以下错误:
error[E0308]: mismatched types
--> src/vars.rs:49:13
|
49 | / |a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> Ctr {
50 | | let inner = a.borrow_mut();
51 | | match &inner.car {
52 | | Ctr::Symbol(identifier) => {
... |
96 | | return Ctr::None;
97 | | }
| |_____________^ expected opaque type, found closure
|
我尝试过的:
- 正在将 InternalOperation 声明为匿名函数。这可行,但我无法存储闭包。
- 我试图使用 InternalOperation(......) 来声明闭包,根据语法规则这是不正确的
我在这里使用闭包,以便我的应用程序的用户配置可以在函数操作的主体内使用。是否可以以这种方式使用闭包,或者我是否需要重构我的代码以以其他方式应用 env_cfg 值?
我假设 type_alias_impl_trait
功能已打开。如果不是,则此代码无论如何都不应编译,因为没有此功能 impl Trait
不允许在类型别名中使用。
理论上,此功能应将类型别名的任何使用视为“定义用途”,即我们可以从中推断出不透明类型的用途。实际上,它(还)没有针对许多用途实施。据我所知,目前只有函数 return 类型被认为是定义用途。
但是,在您的情况下,您希望编译器从表达式中推断出类型。 它应该知道 Operation::Internal
的第一个字段是 InternalOperation
类型,因此 它应该知道 InternalOperation
是get_export()
里面回调的类型。 理论上这应该可行,除非编译器(当前)不应用此知识。
您可以通过为 return 回调创建一个新函数来解决此问题:
fn get_callback(env_cfg: bool) -> InternalOperation {
|a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> Ctr {
// so much logic here to manage variables in b
// if env_cfg is true, entries in b are tied to environment variables
}
}
pub fn get_export(env_cfg: bool) -> Function {
Function {
name: String::from("export"),
loose_syms: true,
eval_lazy: true,
args: Args::Lazy(2),
function: Operation::Internal(get_callback(env_cfg)),
}
}
在我的项目中,我使用类型定义来保存具有特定函数签名的闭包,如下所示:
// Standardized function signature
pub type InternalOperation = impl Fn(Ast, Rc<RefCell<VTable>>, Rc<RefCell<FTable>>) -> Ctr;
pub struct ExternalOperation {
// ...
// The project is on gitlab called relish if you are interested
}
/* A stored function may either be a pointer to a function
* or a syntax tree to eval with the arguments
*/
pub enum Operation {
Internal(InternalOperation),
External(ExternalOperation)
}
// function which does not need args checked
pub struct Function {
pub function: Operation,
// many more things like argument types and function name
}
我尝试实例化一个函数:
pub fn get_export(env_cfg: bool) -> Function {
return Function{
name: String::from("export"),
loose_syms: true,
eval_lazy: true,
args: Args::Lazy(2),
function: Operation::Internal(
|a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> Ctr {
// so much logic here to manage variables in b
// if env_cfg is true, entries in b are tied to environment variables
})
}
}
但是我遇到了以下错误:
error[E0308]: mismatched types
--> src/vars.rs:49:13
|
49 | / |a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> Ctr {
50 | | let inner = a.borrow_mut();
51 | | match &inner.car {
52 | | Ctr::Symbol(identifier) => {
... |
96 | | return Ctr::None;
97 | | }
| |_____________^ expected opaque type, found closure
|
我尝试过的:
- 正在将 InternalOperation 声明为匿名函数。这可行,但我无法存储闭包。
- 我试图使用 InternalOperation(......) 来声明闭包,根据语法规则这是不正确的
我在这里使用闭包,以便我的应用程序的用户配置可以在函数操作的主体内使用。是否可以以这种方式使用闭包,或者我是否需要重构我的代码以以其他方式应用 env_cfg 值?
我假设 type_alias_impl_trait
功能已打开。如果不是,则此代码无论如何都不应编译,因为没有此功能 impl Trait
不允许在类型别名中使用。
理论上,此功能应将类型别名的任何使用视为“定义用途”,即我们可以从中推断出不透明类型的用途。实际上,它(还)没有针对许多用途实施。据我所知,目前只有函数 return 类型被认为是定义用途。
但是,在您的情况下,您希望编译器从表达式中推断出类型。 它应该知道 Operation::Internal
的第一个字段是 InternalOperation
类型,因此 它应该知道 InternalOperation
是get_export()
里面回调的类型。 理论上这应该可行,除非编译器(当前)不应用此知识。
您可以通过为 return 回调创建一个新函数来解决此问题:
fn get_callback(env_cfg: bool) -> InternalOperation {
|a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> Ctr {
// so much logic here to manage variables in b
// if env_cfg is true, entries in b are tied to environment variables
}
}
pub fn get_export(env_cfg: bool) -> Function {
Function {
name: String::from("export"),
loose_syms: true,
eval_lazy: true,
args: Args::Lazy(2),
function: Operation::Internal(get_callback(env_cfg)),
}
}