Struct 设置锈蚀对象参数的性能

Struct 设置锈蚀对象参数的性能,struct,constructor,rust,instantiation,Struct,Constructor,Rust,Instantiation,到目前为止,我一直在想我在Rust中遇到的实例化结构的不同方法。因此,当所有内容都是公共的时,有一种最基本/最简单的手动设置所有字段的方法: let a = Structure { arg1: T, arg2: T, ... } 当需要隐私和更好的界面和/或默认设置时,通常使用“constructor”,例如us new(),等等: 现在,到目前为止,我觉得这有点道理。然而,似乎有第三种常见的方法来做同样的事情,这让我最困惑。以下是一个具体的例子: let mut image_file = O

到目前为止,我一直在想我在Rust中遇到的实例化结构的不同方法。因此,当所有内容都是公共的时,有一种最基本/最简单的手动设置所有字段的方法:

let a = Structure { arg1: T, arg2: T, ... }
当需要隐私和更好的界面和/或默认设置时,通常使用“constructor”,例如us new(),等等:

现在,到目前为止,我觉得这有点道理。然而,似乎有第三种常见的方法来做同样的事情,这让我最困惑。以下是一个具体的例子:

let mut image_file = OpenOptions::new()
                        .write(true)
                        .truncate(true)
                        .create(true)
                        .open(file_path)
                        .unwrap();
因此,我的问题是:

  • 这些不同的解决方案(如果有)对性能有什么影响
  • 每种方法的一般优点和缺点是什么
  • 有更多的方法可以做到这一点吗
  • 哪一个是最佳实践

  • 您已经确定了创建结构的3种方法:

  • 直接:直接初始化其字段
  • 构造函数:调用初始化结构的单个函数
  • 生成器:组装
    struct
    元素,然后最终初始化
    struct
  • 有更多的方法可以做到这一点吗

    直接初始化有两种变体:要么直接初始化每个字段,要么初始化几个字段并使用
    struct S{f0,…others}
    对其他字段进行“默认设置”,其中
    others
    S
    的一个实例

    构造函数和生成器的方式有指数级的变化,这取决于您对参数的分组方式,在某些情况下,两者之间的界线会很模糊

    但是,所有方法都必须在某个点上收敛并使用(1)创建
    S
    的实例

    每种方法的一般优点和缺点是什么

    这是。。。在某种程度上,这是无关紧要的

    3个备选方案中的每一个都满足不同的需求:

    • 直接初始化需要可访问的字段;由于
      pub
      字段很少,因此它主要用于板条箱中,但客户不可用
    • 构造函数和生成器允许建立不变量,因此是主要客户端接口
    构造函数很简单,但不灵活:如果不破坏向后兼容性,就不能添加新参数(当然,另一个构造函数可以);另一方面,构建器是灵活的,以冗长为代价

    这些不同的解决方案(如果有)对性能有什么影响

    理想情况下,在优化的二进制文件中,构造函数和生成器的成本应该相同。如果有关系,请提供个人资料

    如果它们建立不变量,直接初始化将比这两种方法都要快,因为它没有。不过,比较非等效功能的性能并不重要

    哪一个是最佳实践

    避免直接初始化

    直接初始化不建立不变量,而是由周围的代码来建立它们,因此,这意味着任何时候使用直接初始化时,不变量检查代码都是重复的,这违反了DRY原则

    直接初始化也不利于封装,阻止了底层结构的任何进一步更改,包括所用字段的类型。这通常是不可取的

    和往常一样,也有例外。最突出的是,实现构造函数或构建器需要使用直接初始化


    在构造器和构建器之间进行选择更为主观。通常,当参数很少时,我建议使用构造函数,即使这意味着要编写一些参数,例如
    Vec::{new,with_capacity}
    。如果需要为每个有意义的参数组合编写一个构造器,那么当构造器的数量失控时,请使用构造器。

    问题的标题与内容不太匹配;“你问的问题比原来说的多得多。”@MatthieuM。是的,你说得对。看来正是因为这个原因,问题被搁置了。非常感谢Matthieu!这澄清了很多事情,我唯一不确定是否理解的是关于直接初始化、不变量和封装的部分。@dawid:Imagine
    struct偶数{number:i64}
    。契约(也称为不变量,因为它从不变化)是它的
    number
    字段总是偶数。如果有人可以直接初始化它(如果
    number
    pub
    ),那么迟早会有人写
    甚至{number:3}
    。哎呀。因此,您应该有一个构造函数
    fn new(n:i64)->选项
    ,如果
    n
    为偶数,则返回
    Some(偶数{number:n})
    ,否则返回
    None
    ,从而建立
    偶数::number
    始终为偶数的不变量。
    let mut image_file = OpenOptions::new()
                            .write(true)
                            .truncate(true)
                            .create(true)
                            .open(file_path)
                            .unwrap();