Add*_*son 3 methods naming visibility rust
我注意到Rust的Vec::len方法只是访问vector的len属性.为什么不len只是一个公共财产,而不是围绕它包装一个方法?我认为这是为了在以后实现发生变化的情况下,没有什么会破坏,因为它Vec::len可以改变它获取长度的方式而没有任何用户Vec知道.但我不知道是否还有其他原因.
我的问题的第二部分是关于何时设计API.如果我正在构建自己的API,并且我有一个带有len属性的结构,我应该len私有并创建一个公共len()方法吗?在Rust中公开字段是不好的做法吗?我不这么认为,但我没有注意到Rust经常这样做.例如,我有以下结构:
pub struct Segment {
pub dol_offset: u64,
pub len: usize,
pub loading_address: u64,
pub seg_type: SegmentType,
pub seg_num: u64,
}
Run Code Online (Sandbox Code Playgroud)
这些字段中的任何一个是私有的,而是具有类似的包装函数Vec吗?如果是这样,为什么呢?在Rust有一个很好的指导方针吗?
一个原因是为实现某种长度概念的所有容器提供相同的接口.(如std::iter::ExactSizeIterator.)
在这种情况下Vec,len()表现得像一个吸气剂:
impl<T> Vec<T> {
pub fn len(&self) -> usize {
self.len
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这确保了标准库的一致性,但这个设计选择还有另一个原因......
这个吸气剂可以防止外部变形len.如果Vec::len <= Vec::buf::cap不满足条件,则Vec方法可能会尝试非法访问内存.例如,执行Vec::push:
pub fn push(&mut self, value: T) {
if self.len == self.buf.cap() {
self.buf.double();
}
unsafe {
let end = self.as_mut_ptr().offset(self.len as isize);
ptr::write(end, value);
self.len += 1;
}
}
Run Code Online (Sandbox Code Playgroud)
将尝试写入内存超过容器拥有的内存的实际结束.由于这一关键要求,len禁止修改.
哲学
在库代码中使用这样的getter绝对是好的(疯狂的人可能会尝试修改它!).
但是,应该以最小化getter/setter要求的方式设计他们的代码.一个班级应该尽可能地对自己的成员采取行动.应通过方法向公众提供这些行动.在这里,我指的是做有用事情的方法- 而不仅仅是返回/设置变量的普通ol'getter/setter.特别是通过使用构造函数或方法可以使setter变得多余.Vec向我们展示了一些这样的"制定者":
push
insert
pop
reserve
...
Run Code Online (Sandbox Code Playgroud)
因此,Vec实现了提供对外界访问的算法.但它自己管理着它的内脏.
| 归档时间: |
|
| 查看次数: |
598 次 |
| 最近记录: |