在特征对象上使用回调

费里奥

我试图在特征对象上使用回调函数。我将问题简化为以下代码(playpen):

trait Caller {
    fn call(&self, call: fn(&Caller)) where Self: Sized {
        call(self)
    }
}

struct Type;
impl Caller for Type {}

fn callme(_: &Caller) {}

fn main() {
    let caller: Box<Caller> = Box::new(Type);
    caller.call(callme); // does not work
    //callme(&*caller);  // works
}

导致

<anon>:14:12: 14:24 error: the trait `core::marker::Sized` is not implemented for the type `Caller` [E0277]
<anon>:14     caller.call(callme); // does not work
                     ^~~~~~~~~~~~

添加Sized绑定会Caller导致:

<anon>:3:14: 3:18 error: cannot convert to a trait object because trait `Caller` is not object-safe [E0038]

我真的不明白为什么我需要Sized特质。有趣的是,如果我直接使用回调,它会起作用。我该如何工作?

编辑:感谢的答案,我现在想出了一个不错的解决方案

trait Caller {
    fn borrow(&self) -> &Caller;
    fn call(&self, call: fn(&Caller)) {
        call(self.borrow())
    }
}

struct Type;
impl Caller for Type {
    fn borrow(&self) -> &Caller { self }
}

fn callme(_: &Caller) {}

fn main() {
    let caller: Box<Caller> = Box::new(Type);
    caller.call(callme);
}
休恩

的参数callfn call需要的性状对象&Caller,因此调用它需要强迫的self(类型的参考&Self),以一个&Caller性状对象。只有在&Self使用细指针而非特质对象或&[T]切片之类的粗指针时,强制才可能执行&Self确切地说是什么时候是细指针Self: Sized编译器默认将Selfin trait设为not Sized,因此需要额外的限制。Sized特征代表该类型有一个在编译时已知的大小,没有必要存储额外的信息(指针旁边,使其成为“胖”)来计算它在运行时。

不幸的是,这留下了一个漏洞:AFAIK,实际上不可能将这种方法作为默认方法,并且仍然无法在特征对象上调用它,因为特征对象&Caller具有Self = Callernot方法Sized但是,如果为每种类型手动实现该方法,则应该可以使用:

trait Caller {
    fn call(&self, call: fn(&Caller));
}

struct Type;
impl Caller for Type {
    fn call(&self, call: fn(&Caller)) {
        call(self)
    }
}

fn callme(_: &Caller) {}

fn main() {
    let caller: Box<Caller> = Box::new(Type);
    caller.call(callme);
}

call特质中方法声明不再需要,where Self: Sized因为它不尝试执行特质对象强制本身,并且具体实现对如何获得&Caller特质对象具有更多控制对于Sized类型,它可以直接工作,就像原始where Self: Sized代码一样。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在angucomplete-alt选定对象属性上使用回调函数?

来自分类Dev

Rust FFI将特征对象作为上下文传递来调用回调

来自分类Dev

如何使用回调

来自分类Dev

Android:如何在Crouton onDisplayed()上使用回调

来自分类Dev

如何模拟采用回调对象和调用者的方法,使用回调来委托结果

来自分类Dev

了解如何使用回调

来自分类Dev

.off无法使用回调

来自分类Dev

boost :: python:使用回调

来自分类Dev

如何使用回调机制?

来自分类Dev

了解如何使用回调

来自分类Dev

使用回调导入模块

来自分类Dev

在函数回调中使用回调

来自分类Dev

销毁对象时调用回调函数

来自分类Dev

Typescript通用回调对象的严格性

来自分类Dev

使用回调时express.js请求/响应对象的生命周期

来自分类Dev

在Javascript / Jquery中,是否可以使用回调参数间接调用对象方法?

来自分类Dev

如何在SharePoint客户端对象模型中使用回调函数?

来自分类Dev

使用回调函数作为Component @Input()时的Angular2未定义对象属性

来自分类Dev

使用回调函数时节点js中响应对象的范围

来自分类Dev

使用回调/侦听器链接RxJava可观察对象

来自分类Dev

在Android中使用回调而不是实例化对象的优点是什么

来自分类Dev

在Javascript / Jquery中,是否可以使用回调参数间接调用对象方法?

来自分类Dev

使用回调时express.js请求/响应对象的生命周期

来自分类Dev

Angular $ resources何时使用回调函数以及如何获取对象“干净”

来自分类Dev

Javascript - 使用回调将元素复制到对象的数组

来自分类Dev

在外部库的表单验证规则上使用回调函数-Codeigniter

来自分类Dev

使用python WeakSet启用回调功能

来自分类Dev

我需要使用回调吗?

来自分类Dev

setInterval无法使用回调函数

Related 相关文章

  1. 1

    如何在angucomplete-alt选定对象属性上使用回调函数?

  2. 2

    Rust FFI将特征对象作为上下文传递来调用回调

  3. 3

    如何使用回调

  4. 4

    Android:如何在Crouton onDisplayed()上使用回调

  5. 5

    如何模拟采用回调对象和调用者的方法,使用回调来委托结果

  6. 6

    了解如何使用回调

  7. 7

    .off无法使用回调

  8. 8

    boost :: python:使用回调

  9. 9

    如何使用回调机制?

  10. 10

    了解如何使用回调

  11. 11

    使用回调导入模块

  12. 12

    在函数回调中使用回调

  13. 13

    销毁对象时调用回调函数

  14. 14

    Typescript通用回调对象的严格性

  15. 15

    使用回调时express.js请求/响应对象的生命周期

  16. 16

    在Javascript / Jquery中,是否可以使用回调参数间接调用对象方法?

  17. 17

    如何在SharePoint客户端对象模型中使用回调函数?

  18. 18

    使用回调函数作为Component @Input()时的Angular2未定义对象属性

  19. 19

    使用回调函数时节点js中响应对象的范围

  20. 20

    使用回调/侦听器链接RxJava可观察对象

  21. 21

    在Android中使用回调而不是实例化对象的优点是什么

  22. 22

    在Javascript / Jquery中,是否可以使用回调参数间接调用对象方法?

  23. 23

    使用回调时express.js请求/响应对象的生命周期

  24. 24

    Angular $ resources何时使用回调函数以及如何获取对象“干净”

  25. 25

    Javascript - 使用回调将元素复制到对象的数组

  26. 26

    在外部库的表单验证规则上使用回调函数-Codeigniter

  27. 27

    使用python WeakSet启用回调功能

  28. 28

    我需要使用回调吗?

  29. 29

    setInterval无法使用回调函数

热门标签

归档