I have some experience with Rust, generally understand ownership and borrowing, but having javascript background, I just can't wrap my head around the dereference operator.
I use an ORM that lets me run a transaction in a closure. The closure receives a mutable reference to the Transaction struct, this struct can then be used in database operations. It looks something like this:
let result = db.transaction(async |transaction| {
query!("SELECT * FROM user").fetch_one(transaction).await?
}).await?;
transaction here is of type &mut Transaction. So if there are 2 or more queries in a transaction, the code won't compile:
let result = db.transaction(async |transaction| {
query!("INSERT INTO user VALUES ('foo', 'bar', 'baz')").execute(transaction).await?;
query!("SELECT * FROM user").fetch_one(transaction).await?
}).await?;
Which seems reasonable from the compiler's point of view: &mut Transaction doesn't implement Copy, so it is moved in the execute() call. Looks like a bad API design by the library authors that makes the transaction() method unusable. However, with this little trick the code compiles fine:
let result = db.transaction(async |transaction| {
query!("INSERT INTO user VALUES ('foo', 'bar', 'baz')").execute(&mut *transaction).await?;
query!("SELECT * FROM user").fetch_one(&mut *transaction).await?
}).await?;
So the question is, why would the compiler allow me to do it, effectively create two mutable references to the same thing?