function - 在 rust trait 中实现构造函数

标签 function constructor rust traits

我想定义几个类似的类型 struct A(Option)、struct B(Option) 等,其中浮点值被限制在一个范围内。这些结构的行为可能略有不同,但每种类型的构造函数都是相同的:如果值已经受到约束,则返回 Some(value),否则返回 None。 避免必须为每种类型单独实现每个构造函数;我想在特征中实现它。这真的不可能吗?

使用下面的代码,我被告知 Self 不是一个函数,我

can't use Self as a constructor, you must use the implemented struct

.

#[derive(Debug)]
struct A(Option<f64>);

trait Constrained {
    const MIN: f64;
    const MAX: f64;

    fn is_constrained(value: f64) -> bool {
        value >= Self::MIN && value <= Self::MAX
    }

    fn new(value: f64) -> Self where Self: std::marker::Sized {
        if Self::is_constrained(value) {
            Self(Some(value))
        } else {
            Self(None)
        }
    }
}

impl Constrained for A {
    const MIN: f64 = -360.0;
    const MAX: f64 = 360.0;
/*
    fn new(value: f64) -> A {
        if Self::is_constrained(value) {
            Self(Some(value))
        } else {
            Self(None)
        }
    }
*/
}


fn main() {
    let some_val: A = A::new(1000.0);
    println!("{:?}", some_val);
}

注释掉特征中新函数的实现(从 where 之前开始),并取消注释每个单独结构的 impl 当然可行,但这会导致每种类型的代码不必要地加倍。 是否有任何可能或计划对此进行概括?

最佳答案

从你的代码来看,你似乎有几个要求:

  • 实现结构必须为字段提供存储 Option<f64>
  • 实现必须提供两个常量,MAX 和 MIN。

您真正要寻找的是结构上的 const 泛型。不幸的是,截至 2019 年 8 月,它仍然是一个高度不稳定且不完整的夜间功能。或者,您可以求助于宏。

derive_more crate 允许你导出 From<Option<f64>>对于每个只包含一个字段的实现结构元组。也就是说,您可能想要这样:

#[derive(From)]
pub struct A(Option<f64>);

// just a blanket impl with two consts

然后你的特征可以要求实现者也实现 From<Option<f64>> ,这是这里所需的构造函数:

pub trait Constrained : From<Option<f64>> {
    const MAX: f64;
    const MIN: f64;

    // Your is_constrained method
    // Use Self::from(None) instead of Self(None)
}

这会改进您在 From 中的尝试可以从现有宏自动派生(它也是 Rust 风格的惯用构造函数)。

重点是 Rust 特性不能对实现者的精确结构强加任何要求。某些实现者有另一个未使用的(或与 Constrained 无关的)字段也是有效的;那么你的trait不够灵活。


旁注:看起来您的特征将来可能不方便传递,因为特征常量项不是很灵活。也许您将来会希望使用示例宏来生成整个定义+impl。

关于function - 在 rust trait 中实现构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57440412/

相关文章:

c++ - 在类中定义公共(public)结构

C++ - 生成子类实例的父类(super class)构造函数

testing - 使用带有 actix-web 的工作 POST 路由的测试超时

JavaScript 执行函数数组,如果全部返回 True,则返回 True

jquery - 如何为单个函数引用两个 div 元素?

javascript - 如何测试 Javascript 中函数的相等性

c++ - 如何防止实现一个打算在 C++ 中不实现的方法?

javascript - JavaScript中的动态函数名称

rust - 如何通过在 Rust 中实现 `Option` 来返回由 `Deref` 包装的引用?

rust - 如何将 Option<T> 转换为零个或一个元素的迭代器?