一个类似的问题被问到Erlang中的参数化模块,它是关于"什么".我的问题是"为什么"?
OTP技术委员会 - 影响R16的决定包含董事会对此问题的决定,但我不知道该决定背后的原因.
编程中的状态模块Erlang 2ndEdition由Joe Armstrong详细介绍了这个特性,但我没有看到作者的态度.
如果我们阅读官方文档函数调用,我们会看到此功能是故意浏览的.事实上,官方文档强烈反对使用此功能,请参阅效率函数调用.如果是这样,为什么乔·阿姆斯特朗在他的书中提到了这样的特征呢?
我认为这个功能非常棒.如上所述,我的客户端代码如下所示
Obj:find(Key),
Obj:is_key(Key),
Run Code Online (Sandbox Code Playgroud)
然后,我们不关心是否Obj
由dict:new()
,或者gb_tree:new()
不幸地创建,dict
并且gb_tree
不共享一致的 界面,例如我们gb_tree:lookup
而不是gb_tree:find
.
我想要:对于一个特征,例如Foo
,任何都fn(T1,T2)->()
应该实现它,并且我不关心T1
或T2
是否是引用。
trait Foo {
fn hello_world(&self) -> String {
"hello world".into()
}
}
impl<T1, T2> Foo for fn(T1, T2) -> () {}
fn a_dummy_sample_function(_: i32, _:i32) {}
fn main() {
let fn_ptr : fn(i32, i32)->() = a_dummy_sample_function;
(fn_ptr).hello_world();
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,效果很好。
如果我将第一个参数的类型更改&i32
为
trait Foo {
fn hello_world(&self) -> String {
"hello world".into()
}
}
impl<T1, T2> Foo for fn(T1, T2) -> () {}
fn foo_imp(_: &i32, _:i32) {}
fn main() { …
Run Code Online (Sandbox Code Playgroud) variadic宏提到了关于gcc的VA_ARGS.
我做了以下实验.
#define EVAL(f,...) eval(f,build_args(args,__VA_ARGS__ , args_end))
Run Code Online (Sandbox Code Playgroud)
和
EVAL(f,a) // => eval(f,build_args(args,a, args_end))
EVAL(f,a,b) // => eval(f,build_args(args,a,b, args_end))
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好,但是
EVAL(f) // => eval(f,build_args(args, , args_end))
Run Code Online (Sandbox Code Playgroud)
我必须提供至少一个参数,我根据手册解决问题,使用'##'.
#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,a) // => eval(f,build_args(args,a, args_end))
EVAL(f,a,b) // => eval(f,build_args(args,a,b, args_end))
EVAL(f) // => eval(f,build_args(args, args_end))
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好,但是
#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,EVAL(g,a)) // => eval(f,build_args(args,EVAL(g,a) , args_end))
Run Code Online (Sandbox Code Playgroud)
我们可以看到第二个EVAL
没有扩展,但没有'##',第二个EVAL
是扩展的.
#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,EVAL(g,a)) // => eval(f,build_args(args,
// eval(g,build_args(args,a , args_end),
// …
Run Code Online (Sandbox Code Playgroud)