返回私有项目的私有内部模块给出“公共接口中的私有类型”错误

2024-03-08

在下面的示例中,模块outer有一个私有类型Private和一个私有内部模块inner. inner能够访问Private(因为子模块可以访问其父模块的私有项目,即使它们不是公共停车)。

inner定义一个函数not_really_public_interface()。虽然它被标记为公开,它实际上只适用于outer因为inner本身并不公开。

outer.rs

struct Private;
mod inner {
  use super::Private;
  pub fn not_really_public_interface() -> Private {
    Private
  }
}

这编译没有任何问题。

outer应该可以使用inner::not_really_public_interface()获得Private,只要确保不导出即可。那么让我们这样做:

pub fn main() {
  let _ = self::inner::not_really_public_interface();
}

Right?

stderr

error[E0446]: private type `Private` in public interface
 --> src/outer.rs:4:3
  |
4 | /   pub fn not_really_public_interface() -> Private {
5 | |     Private
6 | |   }
  | |___^ can't leak private type

Wat.这对我来说是违反直觉的,原因如下:

  • 前面的代码不会产生错误,即使它定义了一个带有 Rust 认为“泄漏”的接口的函数。该错误仅发生在outer尝试use这个功能。
  • 唯一的地方inner可能会“泄漏”Private is to 定义它的模块.

所以我的问题是:

  • 这里究竟发生了什么,导致 Rust 得出此接口的任何部分存在泄漏的结论?好像可以治疗Private就好像它被定义在inner.
  • 是否有一个上下文可以让这句话完全有意义?我的第一个想法是这是编译器中的错误或隐私设计中的疏忽,但我怀疑情况确实如此。
  • 有没有办法在不创建另一个模块的情况下解决这个问题?我相信我可以创建一个包装模块,然后制作Private内部公开outer and inner,但我不想这样做。

功能not_really_public_interface is公共所以它可以被使用any其他模块。但是Privatestruct 只能由您的 root 访问并且inner模块。

如果导入另一个模块就会发生泄漏not_really_public_interface。 Rust 抱怨说这could发生这种情况是因为它在本地报告错误,而不是对所有模块和板条箱中的所有用法采取“全局”视图。最终,这种方法对于人类来说推理起来更具可预测性,对于机器来说速度更快。

Rust 可以让你更精确地控制可见性。如果你告诉它这个函数是only可供上一级模块使用(supermodule) 那么它就知道不存在泄漏的可能性:

mod inner {
    use super::Private;

    pub(super) fn not_really_public_interface() -> Private { Private }
}

你也可以使用crate代替super,表示同一个 crate 中的任何模块。或者,如果超级模块有一个名称,例如my_mod,你可以使用pub(in ::my_mod)专门针对它。

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

返回私有项目的私有内部模块给出“公共接口中的私有类型”错误 的相关文章

随机推荐

  • ImageIO 对原始图像的支持 (jrawio)

    我一直在寻找原始图像支持 并找到了这个库 jrawio 1 6 1 它扩展了 imageio 以添加原始支持 它似乎有效 但速度非常慢 我见过跑得更快的蜗牛 我的代码在几秒钟内处理 Jpeg 而处理一个不太大的 cr2 文件或 nef 则需
  • 如何使用 UIButtonBarItem 触发方法?

    我有一个带有工具栏的 xib 上面有 2 个按钮 全部用 IB 制作 我可以将插座连接到按钮 但是当我单击它们时 该方法不会被触发 这是为什么 在我的头文件中我有这个 property nonatomic retain IBOutlet U
  • WinExec 和 ShellExecute 之间有哪些区别?

    我需要执行另一个应用程序 我想知道我是否应该使用WinExec代替ShellExecute或相反亦然 两种方法有哪些区别 有应该优先选择的吗 WinExec长期以来已被弃用 仅出于向后兼容性的原因而保留 它用于启动可执行文件 不要使用它 因
  • 使用ajax调用php并返回多个变量?

    我正在尝试使用 javascript 调用 php 脚本 然后该脚本会将多个变量返回给我的 javascript 以便我可以操作它们 这是我的JS ajax url test php data id lastFileId success f
  • 使用 escaped_list_separator 和 boost split

    我正在使用 boost 字符串库 刚刚发现 split 方法非常简单 string delimiters string str string with comma delimited tokens and delimiters inside
  • R将EXIF数据写入JPEG文件

    对于 R 我发现有机会只读取 EXIF 数据 R 中是否有可能将 EXIF 数据写入 JPEG 文件 感谢所有回复的人 结果 我得到了以下解决方案 Install ExifTool https sno phy queensu ca phil
  • 从查找表创建新变量

    我的数据集中有以下列 presult aresult I single I double I triple I home run SS strikeout 我想添加第三列 bases 它取决于列 areresult 中结果的值 例如 我希望
  • SASS 文件内链接的缓存清除图像

    我对 Laravel 5 0 相当陌生 但对 PHP 不太熟悉 我一直在使用 Elixir 来编译我的 SASS 从我的资源目录复制图像并通过mix version防止缓存的功能 然而 这对于 CSS 图像和 JavaScript 来说非常
  • 多字节字符是否会干扰正则表达式中的结束行字符?

    使用这个正则表达式 regex1 z 以下字符串匹配 hello regex1 gt 5 regex1 gt 5 但使用这些正则表达式 regex2 z regex3 n z 他们表现出差异 hello regex2 gt 5 hello
  • 用例之间的 UML 关系(扩展/包含)

    我不太理解以下主题 因为它与我读到的内容有点含糊 Inlcude就像对下一部分的引用一样 没有它 用例就不完整 这部分应该从更多地方引用 否则它的使用没有意义 但我见过一个例子 其中 include 仅在某些 IF 语句中为真 例如 添加新
  • 从 pandas dataframe 列更新 sqlalchemy orm 列的正确方法是什么

    我已经加载了一些数据并修改了数据框中的一列 并且想要更新数据库以反映更改 I tried db session query sqlTableName update sqlTableName sql col name pdDataframe
  • 使用 Android Native、Android Studio 和改造在本地网络中信任我自己的自签名证书

    我正在创建一个简单的 Android 应用程序 将在封闭的本地网络中使用 在此本地网络中 正在运行 Flask 服务器 该服务器配置为通过 nginx 代理使用自签名证书 服务器的后端应用程序使用自签名证书可以正常工作 我已经使用浏览器和邮
  • Rails 三种开发模式的区别

    Rails 中的三种模式有什么区别 In development mode Rails reloads models each time a browser sends in a request so the model will alwa
  • 从python文件中提取函数并将其写入其他文件

    我已经编写了一个包含很多函数的 python 文件 我决定将它们全部拆分到不同的文件中 并使用它们的名称和相同的导入 代码看起来像这样 import class TestExtractors unittest TestCase def te
  • 元素隐式具有“any”类型,因为类型“Window”没有索引签名?

    我试图在 Typescript 中创建一个 Factory 类 但遇到以下错误 src ts classes Factory ts 8 10 错误 TS7017 元素隐式具有 any 类型 因为类型 Window 没有索引签名 我尝试搜索此
  • 有没有办法从java调用imagej宏(.ijm)(即将宏存储为字符串并使用imagej的java控件执行它)?

    将问题反转为 如何从 ImageJ 宏调用 执行 java 程序 每当我写 imagej 时 我都会提到斐济 当然 一个简单的解决方案是从 java 字符串创建 ijm 并使用以 ijm 作为参数的系统调用来调用 imagej 但我正在寻找
  • Supervisord celery 的用户不正确

    我有一些使用 celery 运行的定期任务 由supervisord 守护 但是在尝试为我为supervisord 进程设置的用户的主目录中创建一个目录后 我收到了 权限被拒绝 错误 看完之后os environ在运行芹菜任务中的字典我注意
  • 打开 PDF:WPF

    我想通过单击按钮打开 PDF 文件 我会将 PDF 文件保留在项目的解决方案 命名空间中 谁能给我解决这个问题吗 要启动标准 PDF 查看器 您只需启动一个外部进程即可 Process proc new Process proc Start
  • 控制ipython历史长度

    标题几乎说出了我想要的 我想在我的 ipython history 中有超过 1000 行的输入 这意味着将显示较旧的按向上箭头命令 这可能吗 可能在 ipython config 的某个地方 Thanks In http 2sn org
  • 返回私有项目的私有内部模块给出“公共接口中的私有类型”错误

    在下面的示例中 模块outer有一个私有类型Private和一个私有内部模块inner inner能够访问Private 因为子模块可以访问其父模块的私有项目 即使它们不是公共停车 inner定义一个函数not really public