【问题标题】:Is there a way to overwrite the assignment operator for a Rust type? [duplicate]有没有办法覆盖 Rust 类型的赋值运算符? [复制]
【发布时间】:2020-03-31 13:17:17
【问题描述】:

我的问题如下:我想建立一个类似原始的结构,其值范围更有限。如

#[repr(transparent)]
struct MyLimitedInt {
  v: i8,
}

但确保v 的值始终介于-1010 之间。我知道我可以实现 std::ops 特征以检查加法等的值,但似乎没有一种方法可以在仍然检查边界的同时以类似原始的方式构造 MyLimitedInt 的实例(如在let my_v: MyLimitedInt = -12; 中,这应该将值限制为-10)。

在类 C 语言中,我可能可以通过覆盖类型的 = 运算符来做到这一点,但是有没有办法在 Rust 中实现类似的结果,而不需要更冗长的构造函数或设置器?

【问题讨论】:

    标签: rust operator-overloading


    【解决方案1】:

    赋值运算符不能在 Rust 中重载。但是,您可以重载其他运算符或改用方法 - 例如:

    use std::cmp::{min, max};
    
    #[repr(transparent)]
    struct MyLimitedInt {
      v: i8,
    }
    
    impl MyLimitedInt {
      pun fn from_clamped(value: i8) -> Self {
        Self { v: min(10, max(value, -10))
      }
    
      /// Sets the value of the int, constraining it to the range [-10, 10]
      pub fn set_clamped(&mut self, value: i8) {
        *self = Self::from_clamped(value);
      }
    }
    

    这可以通过算术运算符的重载进行扩展,使其更像原语一样可用:

    use std::ops::Add;
    
    impl Add for MyLimitedInt {
      type Output = Self;
    
      fn add(self, other: Self) -> Self {
        Self::from_clamped(self.value + other.value)
      }
    }
    
    impl Add<i32> for MyLimitedInt {
      type Output = Self;
    
      fn add(self, other: i32) -> Self {
        Self::from_clamped(self.value + other.value)
      }
    }
    

    这样就可以将加法运算符与MyLimitedInt 一起使用,自动限制结果:

    let x = MyLimitedInt::from_clamped(20) + 5; // 10
    let y = MyLimitedInt::from_clamped(-20) + x; // 0
    

    【讨论】:

    • 当然,这就是我现在实施的方式。但我主要想知道是否有办法让这样的分配看起来更像处理原始类型。对您选择的函数命名也是一个挑剔:在try_x 函数上,我通常期望返回Result-type,在这种情况下,我可能会简单地调用该函数setset_checked
    • 我称之为set_clampedset_saturating,FWIW。 (比较saturating_add
    • @Sty 我添加了一个示例,说明如何使用其他可重载运算符使其更自然 - 这更接近您想要的吗?
    • @apetranzilla 再次,我知道这一点(并在问题中明确说明),这就是为什么我主要关注= 运算符功能。我知道它不能被特征超载,我会接受一个回答说“它不能完成,这就是原因”。我想我主要是希望有一些更晦涩的方法能够以某种方式直接调用这样的from_clamped 函数作为(或立即自动跟随)原始值分配的一部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多