官术网_书友最值得收藏!

Adding entries

The transaction log can now be created and hold entries, but there is no way to add anything to the list. Typically, a list has the ability to add elements to either end—as long as there is a pointer to that end. If that was not the case, any operation would become computationally expensive, since every item has to be looked at to find its successor. With a pointer to the end (tail) of the list, this won't be the case for the append operation; however, to access a random index on the list, it would require some time to go through everything.

Naming is—especially if English is your second language—often tricky. Operations have different names by the language or library used. For example, common names for adding items to a list include push (can add to the front or back), push_back, add, insert (usually comes with a positional parameter), or append . On top of being able to guess method names, some imply completely different processes than others! If you design an interface or library, find the most descriptive and simple name possible and reuse whenever you can!

This is one of the things that a linked list does really well—adding items to either end. There are a few critical things that should not be overlooked, though:

  • Creating the Node object within the method makes for a nicer API and better ownership handling.
  • Edge cases such as empty lists.
  • Incrementing the length is a good idea.
  • The RefCell is used to retrieve mutable ownership for setting a new successor using its borrow_mut() function (interior mutability).

Once that is thought of, the actual implementation is not too bad. Rust's Option type offers a method to retrieve ownership of a value it contains, replacing it with None (see also the documentations for Option.take()https://doc.rust-lang.org/std/option/enum.Option.html#method.take and mem::replace()https://doc.rust-lang.org/stable/std/mem/fn.replace.html), which conveniently shortens the code required to append a new node:

pub fn append(&mut self, value: String) {
let new = Node::new(value);
match self.tail.take() {
Some(old) => old.borrow_mut().next = Some(new.clone()),
None => self.head = Some(new.clone())
};
self.length += 1;
self.tail = Some(new);
}

With that, it's now possible to create a log of any string commands passing through. However, there is something important missing here as well: log replay.

主站蜘蛛池模板: 伊川县| 江陵县| 会宁县| 晋州市| 北流市| 桦川县| 泸州市| 新和县| 汤阴县| 伊通| 连江县| 左贡县| 锡林浩特市| 湘乡市| 于都县| 阆中市| 城固县| 元氏县| 清河县| 崇礼县| 朝阳市| 闵行区| 星子县| 东宁县| 乌鲁木齐县| 托克托县| 东乡县| 扎赉特旗| 清水河县| 巢湖市| 乐清市| 阿拉善左旗| 永清县| 宁远县| 邵武市| 光泽县| 三穗县| 商水县| 武安市| 呈贡县| 安徽省|