英文:
Is there any way to save pointer of any function in the struct?
问题
I've been wondering is there any way to get pointer of function with unspecified arguments and output types (unspecification of output type isn't as necessary as arguments). For example, in C++ when you are spawning new thread you pass function pointer without any specification.
As I see it can be solved with trait that would represent fn
in the same way as std::marker::Tuple
represents Tuple
object.
Example:
struct Cont<F: FN_TRAIT> {
func: F,
}
impl<F: FN_TRAIT> Cont<F> {
fn new(func: F) -> Self {
Self { func: func }
}
fn start(&self, args: dyn std::marker::Tuple) {
self.func.call(args);
}
}
fn temp(a: i32, b: i32) {
println!("{}", a + b);
}
fn main() {
let a = Cont::new(temp);
a.start((0, 1));
}
I tried to find the way to represent fn
with trait in the struct and then call it with std::marker::Tuple
as arguments.
英文:
I've been wondering is there any way to get pointer of function with unspecified arguments and output types (unspecification of output type isn't as necessary as arguments). For example, in C++ when you are spawning new thread you pass function pointer without any specification.
As I see it can solved with trait that would represent fn
in the same way as std::marker::Tuple
represents Tuple
object.
Example:
struct Cont <F: FN_TRAIT> {
func: F,
}
impl<F: FN_TRAIT> Cont <F> {
fn new(func: F) -> Self {
Self { func: func }
}
fn start(&self, args: dyn std::marker::Tuple) {
self.func.call(args);
}
}
fn temp(a: i32, b: i32) {
println!("{}", a + b);
}
fn main() {
let a = Cont::new(temp);
a.start((0,1));
}
I tried to find the way to represent fn
with trait in the struct and then call it with std::marker::Tuple as arguments.
答案1
得分: 0
你可以使用泛型来完成大部分与C++类似的操作:
struct Cont<Args, F> {
args: Args,
fun: F,
}
impl<Args, F> Cont<Args, F> {
fn new(fun: F, args: Args) -> Self {
Cont { args, fun }
}
}
impl<A, R, F: FnOnce(A) -> R> Cont<(A,), F> {
fn call(self) -> R {
(self.fun)(self.args.0)
}
}
impl<A0, A1, R, F: FnOnce(A0, A1) -> R> Cont<(A0, A1), F> {
fn call(self) -> R {
(self.fun)(self.args.0, self.args.1)
}
}
fn main() {
let c1 = Cont::new(|x| 2 * x, (0,));
let c2 = Cont::new(|x, y| x + y, (2, 3));
println!("{} {}", c1.call(), c2.call());
}
(注意:我只提供了代码的翻译部分,没有其他内容。)
英文:
You can do it with generics mostly the same as C++ does it:
struct Cont<Args, F> {
args: Args,
fun: F,
}
impl<Args, F> Cont<Args, F> {
fn new (fun: F, args: Args) -> Self {
Cont { args, fun, }
}
}
impl<A, R, F: FnOnce (A) -> R> Cont<(A,), F> {
fn call (self) -> R {
(self.fun) (self.args.0)
}
}
impl<A0, A1, R, F: FnOnce (A0, A1) -> R> Cont<(A0, A1), F> {
fn call (self) -> R {
(self.fun) (self.args.0, self.args.1)
}
}
fn main() {
let c1 = Cont::new (|x| 2*x, (0,));
let c2 = Cont::new (|x, y| x+y, (2, 3));
println!("{} {}", c1.call(), c2.call());
}
Except that you need to add an implementation for each possible number of arguments (this can probably be simplified with a macro).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论