在使用关联类型的情况下,如何为通用容器实现 Borrow?

2024-01-26

我想实施Borrow for UserFriendlyDataStructure提供对internal_data函数内的字段应该与数据提供者无关。的类型internal_data字段由与特征相关的类型决定TraitA。请注意,Sealed特征确保这里的这些特征都不能被其他板条箱实现;这是我严格提供的功能。此外,类型TraitA::Data受到空特征的限制DataTrait阻止UserFriendlyDataStructure以免被用作该类型。

下面的例子解释得最好:

use std::borrow::Borrow;
use std::marker::PhantomData;

mod private {
    pub trait Sealed {}
}

pub trait DataTrait: private::Sealed {}

pub trait TraitA: private::Sealed {
    type Data: DataTrait;
}

pub struct UserFriendlyDataStructure<A: TraitA> {
    internal_data: A::Data,
    _a: PhantomData<A>,
}

impl<A: TraitA> Borrow<A::Data> for UserFriendlyDataStructure<A> {
    fn borrow(&self) -> &A::Data {
        &self.internal_data
    }
}

pub fn important_function<A: TraitA, T: Borrow<A::Data>>(data: &T) {
    let _internal_data = data.borrow();
    // Do lots of work.
}

#[cfg(test)]
mod tests {
    use super::*;

    pub struct TestData(u32);

    impl super::private::Sealed for TestData {}

    impl DataTrait for TestData {}

    pub struct TestProvider;

    impl super::private::Sealed for TestProvider {}

    impl TraitA for TestProvider {
        type Data = TestData;
    }

    #[test]
    fn basic_test() {
        let ufds: UserFriendlyDataStructure<TestProvider> = UserFriendlyDataStructure {
            internal_data: TestData(100),
            _a: PhantomData::default(),
        };

        important_function::<TestProvider, _>(&ufds);
    }
}

不幸的是,编译器抱怨:

error[E0119]: conflicting implementations of trait `std::borrow::Borrow<UserFriendlyDataStructure<_>>` for type `UserFriendlyDataStructure<_>`:
  --> src/lib.rs:19:1
   |
19 | impl<A: TraitA> Borrow<A::Data> for UserFriendlyDataStructure<A> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T> std::borrow::Borrow<T> for T
             where T: ?Sized;

有办法实现我想做的事情吗?


可以通过引入冗余的第二类型参数来诱使编译器接受代码,该参数被限制为与A::Data:

impl<A, D> Borrow<D> for UserFriendlyDataStructure<A>
where
    A: TraitA<Data = D>,
    D: DataTrait,
{
    fn borrow(&self) -> &A::Data {
        &self.internal_data
    }
}

我不知道为什么会这样,只是限制A::Data: DataTrait没有。我认为编译器应该接受这两个版本。

()

Edit:事实上我们需要冗余类型D上面的代码似乎是当前编译器实现的缺点 https://github.com/rust-lang/rust/issues/50237,并有望在实验型推理机得到解决chalk https://github.com/rust-lang-nursery/chalk被集成到编译器中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在使用关联类型的情况下,如何为通用容器实现 Borrow? 的相关文章

随机推荐

  • 在 postgreSQL 中创建表

    我不明白这个查询有什么问题 查询工具不想在 PostgreSQL 中创建表 CREATE TABLE article article id bigint 20 NOT NULL auto increment article name var
  • 通过chart.js中图例的一键事件隐藏或显示两个数据集

    我想展示 30 天的 2 个班次的机器停机时间的可视化 白天 12 小时 和夜间 12 小时 因此 我将堆叠条形图与组一起使用 并且看起来不错 接受我不想让图例显示两个班次 白天和晚上 带组的堆积条形图 https i stack imgu
  • struts2 修剪从表单获得的所有字符串

    我使用struts2开发Web应用程序 我想改进从表单中获取字符串的方法 为此 需要修剪所有字符串 如果获得的字符串为空 则设置null到字段 为此 我创建了字符串转换器 public class StringConverter exten
  • 是否可以从 http 标头中找到文件名

    通常在下载文件时 假设使用QNetworkAccessManager 文件名不存在于链接末尾 在这种情况下如何获得正确的文件名 即使链接不包含名称提示 Firefox 也始终会下载具有正确名称和扩展名的文件 我们可以使用 mime 类型获得
  • Log4j2 Syslog Appender(TCP 协议)在多行中发送异常堆栈跟踪并显示错误的日志级别

    我正在使用 log4j2 和 syslog 附加程序 我使用 TCP 作为协议和 Kiwi 系统日志服务器 发送错误消息时 异常堆栈跟踪通过 TCP 分多行发送 每一行位于一个数据包中 堆栈跟踪的第一行显示 Kiwi syslog 服务器中
  • 如何从 C# 显示“显示设置”窗口

    如何从 C 显示 Windows 显示设置 分辨率设置 窗口 可以调整屏幕分辨率的那个 我找到了一种方法通过 p invoke 更改显示设置 http pinvoke net default aspx user32 ChangeDispla
  • DocuSign API:在同一信封中发送多个文档的签名问题

    使用 C DocuSign API SDK 4 5 2 我将在同一个信封中寄出 3 份文件以供签名 每个文档将使用相同的服务器模板 它只是使用锚标记将签名元素放置在文档上 我可以寄出信封 然后从 DocuSign 收到电子邮件以查看 签署文
  • 仅返回具有最近 TIME 值的记录?

    我有一个表需要进行一些数据转换 这是一个简单的跟踪表 如下所示 SSN9 0 KEY 例如 123456789 非空 DATE8 0 KEY 例如 20131202 非空 TIME6 0 KEY 例如 133000 非空 打印 新Z 例如2
  • 使用 Namecheap DNS 的 Amazon S3 静态托管 - 如何正确路由非 www 前缀 URL

    我一直在阅读其他帖子 试图深入了解这个问题 但我需要一些澄清 当我进入时 我能够让所有域请求完美地到达我的 Amazon S3 存储桶www example com MyDirectory 如果我输入example com MyDirect
  • 使用 Glide 加载到 Imageview 但延迟

    我使用 Glide 从 Firebase 加载 ImageView 当我运行我的应用程序时 我的 ImageView 会延迟 就像我视频中的牙齿一样 https www youtube com watch v 6Mj0Xq3M8n0 htt
  • DB Design允许用户定义产品、产品规格并让自己插入订单

    我正在设计一个数据库 因为我需要开发这样一个 CRM 用户可以在其中指定新产品 产品规格和定价 然后让自己为上一步中指定的产品插入订单 当然 插入的数据需要根据它们在数据库中指定的内容进行评估 我举个例子可能会更清楚 user1 创建一个产
  • 我的项目不支持多设备屏幕视图

    我有一个菜单屏幕 XML 当我打开项目宽屏幕时 它不适应所有屏幕尺寸 我怎样才能克服这个问题 当我想添加有关此问题的图片时 我认为我需要 10 次代表 观点 有人可以帮助我吗
  • 寻找 C++ 的应用程序 GUI 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在考虑编写一个非常简单的绘画程序 我想要一种更高级的方法来将数据输入到我的程序中 例如颜色 画笔的
  • 命名空间“卡住”为终止,我如何删除它

    我有一个 卡住 的命名空间 我删除了它 显示在这个永恒的 终止 状态中 假设您已经尝试强制删除资源 例如 Pod 停留在终止状态 https stackoverflow com q 35453792 而你却束手无策地试图恢复名称空间 您可以
  • 命令行从 TFS“获取最新”,无需映射工作区等

    我假设 tf exe get project recursive 需要这个奇怪的工作区映射 已知的 TFS 服务器等 有什么办法可以做这个最简单的事情 连接到thisTFS 服务器使用this一组凭据 获取最新的源代码this项目并把它he
  • 如何从程序窗口外部获取鼠标事件

    我想拖动这个角色 图像 所以我使用这个方法来获取鼠标位置 WndProc HWND hWnd UINT message WPARAM wParam LPARAM lParam switch message case WM LBUTTONDO
  • 具有白色轮廓的 OpenGL 彩色位图字体

    我有一个 libgdx 游戏 我想在其中使用带有轮廓的位图字体 我希望能够使用 setColor 设置字体颜色 但是 我总是希望轮廓保持白色 对我来说实现这一目标的最佳方法是什么 我假设我应该使用片段着色器进行所需的颜色操作 我创建了一个位
  • 在finally块中抛出异常

    有没有一种优雅的方式来处理抛出的异常finally block 例如 try Use the resource catch Exception ex Problem with the resource finally try resourc
  • 找不到方法 android java.lang.NoClassDefFoundError 引用的类

    我正在调用一个单独的类 我已经在与我的包相同的包中编写了MainActivity类已保存 但是当我运行该应用程序时它给了我java lang NoClassDefFoundError 我不明白为什么无法识别同一包中定义的另一个类 我尝试过很
  • 在使用关联类型的情况下,如何为通用容器实现 Borrow?

    我想实施Borrow for UserFriendlyDataStructure提供对internal data函数内的字段应该与数据提供者无关 的类型internal data字段由与特征相关的类型决定TraitA 请注意 Sealed特