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

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.

主站蜘蛛池模板: 永修县| 承德县| 静宁县| 潼南县| 繁昌县| 汉中市| 漠河县| 桃源县| 德阳市| 九龙城区| 高安市| 巴南区| 搜索| 磐安县| 昭通市| 长顺县| 蒙自县| 尼玛县| 隆德县| 乌什县| 射洪县| 井研县| 平武县| 莆田市| 广平县| 治多县| 双城市| 虎林市| 铁力市| 原平市| 梁河县| 喜德县| 宜丰县| 临潭县| 永嘉县| 霍城县| 南漳县| 包头市| 雅安市| 治县。| 蓝田县|