何时在空结构上使用 impl [关闭]

2024-04-12

我看到了以下代码 https://github.com/paul-schaaf/solana-escrow/blob/4a2b92e6a6585f9b73aaad87aaea1cbfd5f0134a/program/src/processor.rs#L17在互联网上:

pub struct Processor;

impl Processor {
    pub fn process(

    ) -> i32 {
       // some stuff here
    }
}

并用作:

let a = Processor::process();

拥有什么好处struct到底在这里吗?如果没有它,同样的事情能以某种方式实现吗?


以下是您可能遇到的一些更常见的示例。我确信还有其他内容我忘记了,但这些希望对您将来阅读 Rust 代码时有所帮助。

创建结构来保存特征的不同实现

您可能会发现自己处于这样一种情况:能够使用自定义处理程序会很好,但又希望避免在每个结构中存储函数的开销。一个简单的替代方案是为其创建一个特征,并定义类型,其唯一目的是在其上实现不同版本的特征。

通过这种方式,您可以像编译时类型修饰符一样使用它们,从而可以在以后轻松交换或重新定义核心功能,而无需任何额外的开销或需要将额外的信息存储在结构中。

trait Smoothing {
    fn smooth(a: i32, b: i32) -> i32;
}

struct LinearStrategy;
impl Smoothing for LinearStrategy {
    fn smooth(a: i32, b: i32) -> i32 {
        (a + b) / 2
    }
}

struct GeometricStrategy;
impl Smoothing for GeometricStrategy {
    fn smooth(a: i32, b: i32) -> i32 {
        i32::sqrt(a * a + b * b)
    }
}

struct ComplexStruct<T> {
    /* etc. */
    _phantom: PhantomData<T>,
}

// Change how ComplexStruct operates at compile time
impl<T: Smoothing> ComplexStruct<T> {
    pub fn sample(&self, x: i32) -> i32 {
        T::smooth(self.raw_sample(x - 1), self.raw_sample(x + 1))
    }
}

我能找到的最好的例子可能是Vec。乍一看可能不是这样,但是Vec有 2 个类型参数。在Vec<T, A = Global>, the A是使用的分配器Vec。默认情况下,它设置为全局分配器,但在某些情况下,能够轻松地将其与其他东西切换,并且仍然可以访问所有正常功能,这真的很方便。Vec.

FFI 的占位符

当为 C/其他库创建 rust api 时,添加类型来镜像 C api 而不包含相同的数据可能是有意义的。通常情况下,最终看起来像这样,其中指针被安全的 rust 替代方案和占位符生命周期包装(因为 rust 不拥有此数据)。

pub struct Foo<'a> {
    ptr: *mut sys::Foo,
    _phantom: PhantomData<&'a ()>,
}

但是,在需要强制为资源调用构造函数/析构函数的情况下,使用结构体也可能有意义。由于 Rust 调用结构体drop当函数超出范围然后从内存中删除时,执行这些规则非常容易。在这种情况下,通过拥有一个结构体,我们可以强制满足一些先决条件,以获得对结构体中函数的访问。

pub struct FooApi;

impl FooApi {
    pub fn new() -> Self {
        unsafe { sys::init_thread_foo(); }
        FooApi
    }

    /// Some call that is only safe if sys::init_thread_foo() has been called
    pub fn do_something(&self) { /* ... */}
}

/// Call FFI function to dispose of this resource once this FooApi is no longer needed
impl Drop for FooApi {
    fn drop(&mut self) {
        unsafe {
            sys::dispose_thread_foo();
        }
    }
}

冗长

有时结构可能会被模块替换。然而,根据开发人员的不同,在考虑对对象进行操作更具有概念意义的情况下,他们可能更喜欢使用结构体。通常,这些情况相当罕见,并且通常表明某个类型之前或将来将被分成特征并泛化。或者,它也可以用于有几个等效但不相同的替代方案可以在之间交换的情况(例如:CPU 类型)。

到目前为止,这些是我想到的几个原因,但我可能会回来补充更多。

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

何时在空结构上使用 impl [关闭] 的相关文章

随机推荐

  • 如何使用 Ninject 设置可选方法拦截?

    假设我有一个类 我有时想 但现在总是 拦截一些 但不是全部 方法 据我了解 这可以通过以下方式完成 InterceptAround 在我的 Ninject 模块中 在更高级别的代码中 或者在这些方法上使用 InterceptAttribut
  • C# COM 跨线程

    我们正在开发一种软 件来控制科学测量设备 它提供了一个 COM 接口 定义了几个函数来设置测量参数并在测量数据时触发事件 为了测试我们的软件 我正在实现该设备的模拟 com 对象运行一个循环 定期触发事件 客户端应用程序中的另一个循环现在应
  • 捕获单个网络摄像头帧。在 PHP 中使用

    有没有办法从用户网络摄像头捕获单个帧并将其传递到服务器端 我尝试使用navigator getUserMedia 它允许我创建一个 LocalMediaStream 对象 我可以将其传递给视频元素 但似乎没有可以理解的方法来获取视频本身用于
  • 无效的 Web 服务调用,缺少参数值

    我已经看这个有一段时间了 看不出问题出在哪里 任何帮助是极大的赞赏 WebMethod true ScriptMethod UseHttpGet true ResponseFormat ResponseFormat Json public
  • 乘客错过了生产环境中的开发宝石

    我的生产服务器上有一个奇怪的行为 我通过 Capistrano 将 Rails 3 应用程序部署到生产服务器 Capistrano 脚本在部署结束时重新启动乘客 当我打开应用程序时 我看到一条乘客错误消息 Could not find au
  • 防止回车键触发按钮

    我有一个搜索输入框 当用户按下 Enter 时不需要执行任何操作 我正在使用 EmberJS 和 Jquery 以及以下代码 目前 它可以禁止触发弹出窗口 但由于某些原因 在 IE9 中 当按下 Enter 键时 切换按钮将成为焦点 在 C
  • 多个类的父类的部分特化

    我想对模板类使用部分专业化 以便该模板类的所有子级都将使用该专业化 让我用一个例子来解释一下 template lt typename T unsigned int rows unsigned int cols gt class BaseM
  • Heroku 应用程序上的远程 mysql 数据库

    我可以使用个人 Web 服务器上的 mysql 数据库而不是 heroku 的数据库吗 我这样配置我的生产数据库 production adapter mysql2 database somedatabase username someus
  • FastReport 5.3 Designer无法访问事件

    我在用着快速报告Delphi 10 1 Berlin 中的版本 5 3 14 我正在移植最初编写的 VCL 应用程序DelphiXE 当我打开报告时快速报表设计器单击对象检查器上的 事件 选项卡不会执行任何操作 我也无法单击报告的 代码 选
  • 解释日期:Console.Writeline 与 string.Format

    给出以下 C 代码 var dt DateTime Now Console WriteLine 0 MM dd yy 1 dt string Format 0 MM dd yy dt 当短日期 在 Windows 7 下 Control P
  • 多核::应用?

    有没有类似的东西sapply in the multicore图书馆 或者我必须unlist mclapply 为了达到这个目的 如果它不存在 原因是什么 提前致谢 如果这是一个愚蠢的问题 抱歉 在图书馆parallel 你有mcmappl
  • 来自全新 Yeoman 安装的 gruntserve 返回 - 警告:未找到任务“serve”

    运行后yo angular进而cd进入应用程序的根文件夹 与应用程序文件夹处于同一级别 gruntfile package json等 我尝试grunt serve我收到上述错误 Grunt 不会为我启动服务器 我到处寻找但找不到说要跑np
  • 如何在 Mathematica 中将包含小数点的字母数字(参考)数字转换为字符串

    我有以下类型 DAA76647 1 的参考号 我想将其原封不动地转换为 Mathematica 中的字符串 That is myfn DAA76647 1 给出作为输出 DAA76647 1 是否有捷径可寻 输入不能是字符串 除了转换为字符
  • 创建与智能感知配合使用的 JavaScript 函数

    我想利用 Visual Studio Intellisense 因此我已阅读 http msdn microsoft com en us library bb514138 aspx http msdn microsoft com en us
  • 如何在C++中重用字符串变量

    这是正确的吗 工作正常 string str in dat ifstream fin str c str ios binary ios ate Do I need to clear the string before assigning n
  • 我可以将 CSS 过渡应用于溢出属性吗?

    我正在尝试设置一个transition delay to the overflow的财产body when a div通过添加一个类来单击body如下 div click function body addClass no overflow
  • 如何在 NativeScript 中使用 swift 库?

    我正在尝试使用这个 ios 图表库 https github com danielgindi ios charts在 NativeScript 中 这个库是用 Swift 编写的 而不是用 Objective C 编写的 我可以使用它吗 我
  • 编译并运行 Java 应用程序的源代码

    我需要从我的 Java 应用程序编译并运行用 Python Pascal 或 C 编写的源代码 单个文件 我需要知道 如果编译过程成功 编译后的程序的返回输出 我怎样才能做到这一点 我一直在做同样的事情 public String comp
  • 从 ng carousal 顶部删除幻灯片编号文本

    我正在使用 ng bootstrap 的轮播
  • 何时在空结构上使用 impl [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我看到了以下代码 https github com paul schaaf solana escrow blob 4a2b92e6a6585f9