Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you borrow a mutable reference during a match?

Tags:

rust

I found this but could not get my code to work. I still have the sneaking suspicion that I need ref somehow.

I am trying to make a reasonable Table class in Rust to learn more about the language and running into some trouble with understanding the borrow checker and mutability concepts as well as their corresponding syntax.

I want the table class to be flexible and allow for different column types where the data types within the columns are homogeneous. So, a column of ints, floats, strings etc.


I started without flexible data types and came up with this hashmap mapping ints (the column labels in this case) to vectors of ints (the data within the columns).

use std::collections::HashMap; 

fn main() {
    let mut d: HashMap<isize, Vec<isize>> = HashMap::new();
    d.insert(0, Vec::new());
    d.get_mut(&0).unwrap().push(0); 

    println!("{:?}", d);
    // nice {0: [0]}
}

To implement flexible data types, enum seemed like a decent start so that is where I started but I am stuck on the implementation.

use std::collections::HashMap; 

#[derive(Debug)] 
enum VT {
    A(Vec<isize>),
    B(Vec<f64>),
}

fn main() {
    let mut d: HashMap<isize, VT> = HashMap::new();
    d.insert(0, VT::A(Vec::new()));

    match d.get_mut(&0).unwrap() {
        &mut VT::A(v) => v.push(0),
        &mut VT::B(v) => v.push(0.1), // would not be reached as-is 
    } 

    println!("{:?}", d);
}
// cannot borrow immutable local variable `v` as mutable :(

Ultimately, having a library similar to pandas would be the dream. For now, implementing a table is good Rust practice.

like image 273
user25064 Avatar asked Apr 15 '15 23:04

user25064


People also ask

How do you borrow as mutable in Rust?

First, we change s to be mut . Then we create a mutable reference with &mut s where we call the change function, and update the function signature to accept a mutable reference with some_string: &mut String . This makes it very clear that the change function will mutate the value it borrows.

What is a mutable reference in Rust?

Back to Rust. A mutable reference is a borrow to any type mut T , allowing mutation of T through that reference. The below code illustrates the example of a mutable variable and then mutating its value through a mutable reference ref_i .

What is borrowing in Rust?

Rust supports a concept, borrowing, where the ownership of a value is transferred temporarily to an entity and then returned to the original owner entity.

What is a reference rust?

A reference represents a borrow of some owned value. You can get one by using the & or &mut operators on a value, or by using a ref or ref mut pattern. For those familiar with pointers, a reference is just a pointer that is assumed to not be null.


1 Answers

From Rust 1.26 onwards, any &/ref and &mut/ref mut pairs can be omitted, with the compiler inferring them. (This is a slightly simplistic explanation, but it’s the essence of it.)

match d.get_mut(&0).unwrap() {
    VT::A(v) => v.push(0),
    VT::B(v) => v.push(0.1),
}

Before Rust 1.26 (from mid-2018, so any readers now are probably using a newer version), write your match block like one of these two:

match d.get_mut(&0).unwrap() {
    &mut VT::A(ref mut v) => v.push(0),
    &mut VT::B(ref mut v) => v.push(0.1),
}
match *d.get_mut(&0).unwrap() {
    VT::A(ref mut v) => v.push(0),
    VT::B(ref mut v) => v.push(0.1),
}

In patterns ref mut takes a mutable reference, even as &mut dereferences a mutable reference.

(The generally preferred convention was match *foo { X => … } rather than match foo { &mut X => … }, due to less noise on the more numerous match branch lines, but it flipped the other way after the Rust 1.26 changes, since now that has less noise associated with it.)

like image 56
Chris Morgan Avatar answered Oct 23 '22 03:10

Chris Morgan