来自OCaml,很容易创建一个存在于某些公共接口上的类型,但其定义是隐藏的.我正试着在《铁 rust 与失败》中做同样的事情.

我想要的应该是这样的:

mod inner{
  pub(super) type MyActualType = ...
}
pub type MyType = inner::MyActualType

trait MyTypeExt{
...
}
impl MyTypeExt for MyType{
...
}

目标是外部只能看到在MyTypeExt中定义的方法,而不是inner::MyType中所拥有的所有方法.例如,MyType可能是我只希望能够在非常受控制的上下文中创建和使用的i32-我希望a : MyType + b : MyType是一个编译器错误.(在上面的代码中并非如此.)

我意识到我能做到

pub struct MyType{v : MyActualType} //note the lack of visibility qualifier on v

但我的理解是,除了用一堆包装和展开来拥挤实现的语法之外,这可能会对性能产生影响.我对OCaml版本的理解是,一旦完成可见性/类型判断,该类型将被视为任何其他i32,不会对性能造成影响.

有办法做到这一点吗?

推荐答案

我认为你想要目前不稳定的功能type_alias_impl_trait. 您可以使用它定义内部模块,如下所示:

#![feature(type_alias_impl_trait)]
mod other {
    mod inner {
        pub(super) type MyActualType = i32;
    }
    pub type MyType = impl MyTypeExt;

    pub trait MyTypeExt: std::fmt::Display {
        fn print(&self) {
            println!("{self}")
        }
    }
    impl MyTypeExt for inner::MyActualType {}

    pub fn a() -> MyType {
        5i32 as inner::MyActualType
    }
}

use other::MyTypeExt;
fn main() {
    let a = other::a();

    // the following errors with:
    // error[E0369]: cannot add `{integer}` to `MyType`
    //let b = a + 9;

    // this is fine
    a.print();
}

Playground

我不太确定你这么说是什么意思,

这实际上将在编译时具有盒装的值.

但如果您认为这会增加 struct 的运行时开销,那么您就错了,单元素 struct 或只有一个非ZST struct 的 struct 是laid out like their only non ZST field,在本例中类似于MyActualType

Rust相关问答推荐

为什么父作用域中的变量超出了子作用域

为什么我需要在这个代码示例中使用&

如何go 除铁 rust 中路径组件的第一项和最后一项?

在使用AWS SDK for Rust时,如何使用硬编码访问密钥ID和密钥凭据?

Pin<;&;mut可能将Uninit<;T>;>;合并为Pin<;&;mut T>;

类型批注需要静态生存期

有没有可能让泛型Rust T总是堆分配的?

如何将单个 struct 实例与插入器一起传递到Rust中的映射

try 创建随机数以常量

如何修复&q;无法返回引用函数参数的值在异步规则中返回引用当前函数&q;拥有的数据的值?

如何将实现多个特征的 struct 传递给接受这些特征为&;mut?

实现 Deref 的 struct 可以返回对外部数据的引用吗?

`UnsafeCell` 在没有锁定的情况下跨线程共享 - 这可能会导致 UB,对吗?

Nom 解析器无法消耗无效输入

返回迭代器考虑静态生命周期类型

std::vector::shrink_to_fit 如何在 Rust 中工作?

在构建器模式中捕获 &str 时如何使用生命周期?

无法理解 Rust 对临时值的不可变和可变引用是如何被删除的

Rust 异步和 AsRef 未被发送

有没有办法使用 NASM 语法进行内联汇编?