Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
380 views
in Technique[技术] by (71.8m points)

borrow checker - Rust - Conditional mutating within one-liner

Attention epic rust programmers:

As we all know, one-liners always make for better code. Therefore I, in my journey of learning the power of rust, I have tried to make an insert-function for a struct representing a BinaryTree. For an extra challenge, I wanted it to mutate the Tree, not get a new one.

The struct is as follows:

pub type Node = i32;
type Branch = Option<Box<BinaryTree>>;

#[derive(Debug)]
pub struct BinaryTree {
    node: Node,
    left: Branch,
    right: Branch
}

While my implementation for the insert-function should be:

impl BinaryTree {
    pub fn insert(&mut self, node: Node) {
        (if node <= self.node { &mut self.left } else { &mut self.right }) // get the correct branch
            .as_deref_mut()
            .map(|t| {t.insert(node); t}) // if the branch (Option) is Some, call insert onto the branch and return it
            .get_or_insert(&mut Box::new(BinaryTree { node, left: None, right: None })); // if the branch is some (meaning it got mapped) then just return (do nothing), else insert a new Tree into the branch
    }
}

... which compiles, but doesn't actually mutate the tree. So, the question is where have I gone wrong, since I explicitly state the branches as mutable.

Better one-linery versions are obviously sought after as well!

question from:https://stackoverflow.com/questions/65916070/rust-conditional-mutating-within-one-liner

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your call to map returns a new Option<&mut Box<BinaryTree>>, so calling get_or_insert on that only sets the value of this newly created Option referring to a reference (which also manifests in your passing the reference &mut Box::new(...) -- you'd actually want a value there).

I.e. you actually would need a &mut Option<Box<BinaryTree>> to call get_or_insert.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...