Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何将具体的装箱对象转换为盒式特征对象

如何将具体的装箱对象转换为盒式特征对象
EN

Stack Overflow用户
提问于 2022-09-10 04:02:07
回答 1查看 100关注 0票数 0

解决这个问题肯定还有其他方法,但我只是好奇,是否有办法使下面的代码以某种方式在Rust中工作,我还不知道。

下面的代码示例(游乐场)

代码语言:javascript
运行
AI代码解释
复制
use std::sync::{Arc, Mutex};

trait ProvidesFoo {
    fn magic(&mut self);
}

struct Foo {
    magic_value: u32
}

impl Default for Foo {
    fn default() -> Self {
        Self {magic_value: 42}
    }
}

impl ProvidesFoo for Foo {
    fn magic(&mut self) {
        println!("ProvidesFoo magic {}", self.magic_value);
    }
}

pub type SharedFooConcrete = Arc<Mutex<Box<Foo>>>;
pub type SharedFooTraitObj = Arc<Mutex<Box<dyn ProvidesFoo + Send + Sync>>>;

struct FooProvider {
    foo_as_trait_obj: SharedFooTraitObj

}

impl FooProvider {
    fn magic_and_then_some(&mut self) {
        let mut fooguard = self.foo_as_trait_obj.lock().unwrap();
        fooguard.magic();
        println!("Additional magic");
    }
}

fn uses_shared_foo_boxed_trait_obj(foo: SharedFooTraitObj) {
    let mut foo_provider = FooProvider {
        foo_as_trait_obj: foo
    };
    foo_provider.magic_and_then_some();
}
fn uses_shared_foo_concrete(foo: SharedFooConcrete) {
    let mut fooguard = foo.lock().unwrap();
    fooguard.magic();
}

fn main() {
    let shared_foo = Arc::new(Mutex::new(Box::new(Foo::default())));
    uses_shared_foo_concrete(shared_foo.clone());
    uses_shared_foo_boxed_trait_obj(shared_foo);
}

将无法编译,出现以下错误:

代码语言:javascript
运行
AI代码解释
复制
error[E0308]: mismatched types
  --> fsrc-example/src/bin/test2.rs:52:37
   |
52 |     uses_shared_foo_boxed_trait_obj(shared_foo);
   |     ------------------------------- ^^^^^^^^^^ expected trait object `dyn ProvidesFoo`, found struct `Foo`
   |     |
   |     arguments to this function are incorrect
   |
   = note: expected struct `Arc<Mutex<Box<(dyn ProvidesFoo + Send + Sync + 'static)>>>`
              found struct `Arc<Mutex<Box<Foo>>>`
note: function defined here

确实有一种方法可以将一个盒式特征对象“强制转换”到它的具体类型,如所示的这里,但这基本上是相反的。我来自C++背景,所以我熟悉这种类型的API,其中派生对象可以作为基类传递。

我提到和使用的另一个可能的解决方案是有一个包装器结构,它将SharedFooTraitObject作为字段并在上面实现magic_and_then_some()操作。然后,可以传递包装器结构,并克隆库代码的Arc<Mutex>ed字段,而库代码只需要特征对象。

我只是好奇这种类型的强制/投射在锈蚀中是否可行。

好心的问候,RM

EN

回答 1

Stack Overflow用户

发布于 2022-09-10 09:41:35

我不确定我是否正确地理解了你想要的东西;抱歉,如果我错了。

我删除了所有的包装类型,以便集中于具体类型的引用和对dyn特性的引用。

提供对具体类型的引用,其中对dyn特征的引用是由语言隐式处理的,因为所有信息都是在编译时提供的。可以提供指向适当的虚拟表的fat指针,因为具体类型是众所周知的。

另一方面,当使用dyn特性时,编译器不再知道原始类型,然后在不可能对具体类型的引用提供对dyn特征的引用的情况下。

如果我们真的想实现这一点,我们需要一些运行时检查。特性可以为此目的提供帮助。当我们下陷时,我们确定了混凝土的类型,这样我们就可以得到对这种混凝土类型的参考。

现在,当谈到Arc<Mutex<Box<Foo>>>Arc<Mutex<Box<dyn ProvidesFoo + Send + Sync>>>时,不可能发生隐式或显式转换,因为这不仅仅是胖指针和普通指针之间的转换问题:所有权和同步在MutexArc中起作用。我们不能克隆Arc并期望新的指针包含一种与原始指针不同的指针;如果我们能够构建另一个Arc,其中包含期望的指针,那么第二个Arc将完全独立于原始的指针,因此这将是一个完全不同的所有权语义。

我只是建议您在所有地方保持Arc<Mutex<Box<dyn ProvidesFoo + Send + Sync>>>,如果这是您的API所需要的,并且只要您需要返回一个具体的类型,您就可以获得它包含的动态引用,并使用这个示例中所示的Any解决方案。

代码语言:javascript
运行
AI代码解释
复制
use std::any::Any;

trait MyTrait: Any {
    fn show(&self);
    fn action(&mut self);
    fn as_any(&self) -> &dyn Any;
    fn as_any_mut(&mut self) -> &mut dyn Any;
}

struct MyStructA {
    value: i32,
}

impl MyStructA {
    fn new(value: i32) -> Self {
        Self { value }
    }
}

impl MyTrait for MyStructA {
    fn show(&self) {
        println!("value is {}", self.value);
    }
    fn action(&mut self) {
        self.value += 1;
        self.show();
    }
    fn as_any(&self) -> &dyn Any {
        self
    }
    fn as_any_mut(&mut self) -> &mut dyn Any {
        self
    }
}

struct MyStructB {
    txt: String,
}

impl MyStructB {
    fn new(txt: String) -> Self {
        Self { txt }
    }
}

impl MyTrait for MyStructB {
    fn show(&self) {
        println!("txt is {}", self.txt);
    }
    fn action(&mut self) {
        self.txt.push_str(" •");
        self.show();
    }
    fn as_any(&self) -> &dyn Any {
        self
    }
    fn as_any_mut(&mut self) -> &mut dyn Any {
        self
    }
}

fn use_impl_trait(t: &mut impl MyTrait) {
    print!("impl: ");
    t.action();
}

fn use_dyn_trait(t: &mut dyn MyTrait) {
    print!("dyn: ");
    t.action();
}

fn main() {
    {
        println!("~~~~ using concrete types ~~~~");
        let mut msa = MyStructA::new(100);
        let msa_ref = &mut msa;
        use_dyn_trait(msa_ref);
        use_impl_trait(msa_ref);
        let mut msb = MyStructB::new("xxx".to_owned());
        let msb_ref = &mut msb;
        use_dyn_trait(msb_ref);
        use_impl_trait(msb_ref);
    }
    {
        println!("~~~~ using dynamic types ~~~~");
        let mut msa = MyStructA::new(200);
        let msa_dyn_ref: &mut dyn MyTrait = &mut msa;
        use_dyn_trait(msa_dyn_ref);
        if let Some(msa_ref) =
            msa_dyn_ref.as_any_mut().downcast_mut::<MyStructA>()
        {
            use_impl_trait(msa_ref);
        }
        let mut msb = MyStructB::new("yyy".to_owned());
        let msb_dyn_ref: &mut dyn MyTrait = &mut msb;
        use_dyn_trait(msb_dyn_ref);
        if let Some(msb_ref) =
            msb_dyn_ref.as_any_mut().downcast_mut::<MyStructB>()
        {
            use_impl_trait(msb_ref);
        }
    }
}
/*
~~~~ using concrete types ~~~~
dyn: value is 101
impl: value is 102
dyn: txt is xxx •
impl: txt is xxx • •
~~~~ using dynamic types ~~~~
dyn: value is 201
impl: value is 202
dyn: txt is yyy •
impl: txt is yyy • •
*/
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73671664

复制
相关文章
【笔记】《计算机图形学》(4)——光线追踪
这系列的笔记来自著名的图形学虎书《Fundamentals of Computer Graphics》,这里我为了保证与最新的技术接轨看的是英文第五版,而没有选择第二版的中文翻译版本。不过在记笔记时多少也会参考一下中文版本
ZifengHuang
2020/07/29
2.6K0
【笔记】《计算机图形学》(4)——光线追踪
CGAL:线段和多边形之间的交点?
CGAL:线段和多边形之间的交点? [英] CGAL: Intersection between a segment and a polygon? 查看:422 发布时间:2020/9/30 21
用户3519280
2023/07/06
5460
模拟试题B
1.灰度等级为256级,分辨率为2048*1024的显示器,至少需要的帧缓存容量为( )
步行者08
2018/10/09
4.3K2
爱因斯坦的光线
爱因斯坦的光线
宇相
2018/09/18
6170
爱因斯坦的光线
模拟试题A
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wpxu08/article/details/70208378
步行者08
2018/10/09
3.6K0
链表相交,找交点
力扣题目链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists-lcci
代码随想录
2021/12/22
8230
链表相交,找交点
光线追踪介绍
摘要 图像渲染就是一个这样的过程,输入一组物体,输出一个像素矩阵。把这个像素矩阵输送给显卡,显示器上就可以显示出来图像。本篇介绍下这个过程用到的算法,就是光线追踪。
一只小虾米
2022/10/25
1.1K0
光线追踪介绍
光学词汇6-系统基本概念6-主光线和边缘光线
主光线(chief ray)是从物体的一个偏离光轴的点发出,并且经过光学系统孔径光阑的中心的光线。主光线代表着从物体某一点发出的光束的中心线。
HawkWang
2023/09/01
1.8K0
光学词汇6-系统基本概念6-主光线和边缘光线
photo-distortion
Opticaldistortion=Δyy×100%TVdistortion=Δh2h×100%
为为为什么
2022/11/24
1.6K0
photo-distortion
模拟试题C
2.用编码裁剪法裁剪二维线段时,判断下列直线段采用哪种处理方法。假设直线段两个端点M、N的编码为1000和1001(按TBRL顺序)( )
步行者08
2018/10/09
2.1K0
光线传媒的爆款尴尬
突如其来的疫情,给整个国内院线电影蒙上了阴霾,也给整个电影产业链带来了持久的影响。作为电影产业链的一员,光线传媒受损严重。
刘旷
2020/08/25
4650
光线传媒的爆款尴尬
机器视觉(第3期)----图像采集之镜头原理详述
上期我们一起学习了光源相关的知识,知道了怎么选择光源,链接如下: 机器视觉(第2期)----图像采集之照明综述 镜头是一种光学设备,用于聚集光线在摄像机内部成像。镜头的作用是产生锐利的图像,以得到被测物的细节,这一期我们将一起学习使用不同镜头产生不同的成像几何,以及镜头像差是如何产生的。希望通过本期学习,我们能够掌握如何选择镜头以及像差产生的原因。 作为一个机器视觉算法人员,来介绍光学系统方面的知识,有些地方理解起来还是有些难度的,小编已经再旁边放了几摞砖,欢迎大家来拍。希望能够和大家一起交流,共同进步。
智能算法
2018/04/03
3.1K0
机器视觉(第3期)----图像采集之镜头原理详述
【笔记】《游戏编程算法与技巧》7-12
本篇是看完《游戏编程算法与技巧》后做的笔记的下半部分. 这本书可以看作是《游戏引擎架构》的入门版, 主要介绍了游戏相关的常见算法和一些基础知识, 很多知识点都在面试中会遇到, 值得一读.
ZifengHuang
2022/08/30
2.2K0
求两个链表的交点
已知链表A的头节点指针headA,链表B的头节点指针headB,两个链表相交,求两链表交点对应的节点。 [](LeetCode 160)
小飞侠xp
2018/08/29
9120
VTK:实现光照效果,从一根线到一个面
导读:很多地方需要查看光照度什么的,目前也有很多软件来处理。今天就做了一个关于光照效果的内容。从早上10点开始,到下午3点半,开始写头条号。大概就这么长时间。中午没有休息,没有吃饭。
曾高飞
2022/02/17
1.5K1
「黑悟空」实机演示炸裂登场,英伟达大秀光追技术
---- 新智元报道   编辑:Aeneas 桃子 【新智元导读】「黑悟空」时隔一年后炸裂回归,4K光追 + DLSS,让玩家大呼过瘾。 时隔一年,「黑悟空」归来再度登上热榜。 这次,除了官方发布了一段6分钟实机剧情片段,英伟达更是带来了8分钟实机试玩片段。 重磅的是,这是「黑悟空」首次支持4K  RTX ON光追+NVIDIA DLSS技术。 网友们看后瞬间热血沸腾。 首支4K光追 + DLSS 2020年,黑悟空首次曝光,惊艳全球。 到了2021年,大秀UE5的测试,那白雪纷纷的地面
新智元
2022/08/26
7620
「黑悟空」实机演示炸裂登场,英伟达大秀光追技术
链表相交,找出交点
题目链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists-lcci/
代码随想录
2021/06/17
7520
Day2-球球
用户10759271
2023/09/19
1500
点击加载更多

相似问题

找到光线和多边形的交点的最快方法是什么?

41

光线-平面交点,用于确定交点的Z

10

线与球的交点

11

求光线的最远交点

11

光线不能准确地确定交点

239
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文