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

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.

主站蜘蛛池模板: 昌都县| 江城| 彭山县| 安乡县| 通许县| 博客| 合川市| 舒兰市| 丽江市| 乐清市| 雷山县| 且末县| 舒城县| 元阳县| 民勤县| 保德县| 宁陵县| 大英县| 镇远县| 米林县| 中西区| 平潭县| 海门市| 九龙城区| 和龙市| 杨浦区| 南靖县| 太仆寺旗| 大洼县| 清河县| 定安县| 宿州市| 乡宁县| 永川市| 弋阳县| 满城县| 盐边县| 桃园县| 云安县| 顺平县| 临清市|