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

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.

主站蜘蛛池模板: 临潭县| 长兴县| 旬邑县| 宣城市| 昭觉县| 青龙| 玉树县| 台中县| 南京市| 甘孜县| 科技| 泾川县| 新郑市| 松原市| 法库县| 遂溪县| 栾城县| 潞西市| 运城市| 三门县| 怀宁县| 驻马店市| 阿拉善盟| 新丰县| 红河县| 望谟县| 澜沧| 百色市| 灵山县| 登封市| 德保县| 唐河县| 桂阳县| 沙湾县| 杨浦区| 宾川县| 镇平县| 高唐县| 余庆县| 馆陶县| 涿鹿县|