I've seen this code in the Rust documentation:
fn eat(&self) {
println!("{} is done eating.", self.name);
}
what does the & in &self mean?
This means you'll be passing in a reference to the object, as opposed to moving the object itself. It's important to distinguish this because if your function looked like:
fn eat(self) {
println!("{} is done eating.", self.name);
}
and you tried calling it then using the variable after, you'd get an error
object = Foo::new();
object.eat();
object.something(); // error, because you moved object in eat
because when you don't specify &, rust moves the value into the function and your original binding no longer has ownership. check out this minimal example I created (playground version):
struct Foo {
x : u32
}
impl Foo {
fn eat(self) {
println!("eating");
}
fn something(&self) {
println!("else");
}
}
fn main() {
println!("Hello, world!");
let g = Foo { x: 5 };
g.eat();
g.something(); // if this comes before eat, no errors because we arent moving
}
Now switch something to be called before eat. Because something only takes a reference, g still has ownership and you can continue on. eat on the other hand moves g and you no longer can use g.
Related
In the context of a series of programming lessons, I have decided to use Rust instead of C++ as the support programming language.
One aspect of these lessons is dedicated to OOP (dynamic dispatch) relying on interfaces (dyn traits): composition of minimal interfaces instead of deep inheritance trees.
I know OOP does not fit well with modern languages and approaches, but the existing codebase and the habits of the teams since the 90s are still so present that the students must be at least aware of this paradigm (even if we don't encourage its usage for new developments).
In this playground is shown a minimal example inspired from an exercise formerly done in C++ (many other things exist around this excerpt).
At the abstract level, an Entity has an internal state (a position here, to keep it simple) and several dynamic components responsible for various behaviours (drawing, animation, reaction to events...).
These dynamic components implement some predefined interfaces (dyn traits) and can be freely defined at the application level (the abstract level does not have to know the details of these components).
Some of these components can have some internal data which could even be mutated.
For example, in this minimal code, a Shape component if mainly dedicated to drawing (no mutable operation is required for the entity or this component in general), but an Animator component can cause mutations on the entity (let's say its position), on the component itself and even on other components (change the color of the next drawing for example).
As requested in a comment, here is the code inline:
mod common {
pub trait Shape {
fn draw(
&self,
entity: &Entity,
);
fn change_color(
&mut self,
color: String,
);
}
pub trait Animator {
fn animate(
&mut self,
entity: &mut Entity,
);
}
#[derive(Debug)]
pub struct Pos {
pub x: f64,
pub y: f64,
}
pub struct Entity {
pos: Pos,
shape: Box<dyn Shape>,
animator: Box<dyn Animator>,
}
impl Entity {
pub fn new(
pos: Pos,
shape: Box<dyn Shape>,
animator: Box<dyn Animator>,
) -> Self {
Self {
pos,
shape,
animator,
}
}
pub fn pos(&self) -> &Pos {
&self.pos
}
pub fn pos_mut(&mut self) -> &mut Pos {
&mut self.pos
}
pub fn change_color(
&mut self,
color: String,
) {
self.shape.change_color(color);
}
pub fn draw(&self) {
self.shape.draw(self);
}
pub fn animate(&mut self) {
let anim = &mut self.animator;
anim.animate(self);
}
}
}
mod custom {
use super::common::{Animator, Entity, Shape};
pub struct MyShape {
color: String,
}
impl MyShape {
pub fn new(color: String) -> Self {
Self { color }
}
}
impl Shape for MyShape {
fn draw(
&self,
entity: &Entity,
) {
println!("draw at {:?} with {:?}", entity.pos(), self.color);
}
fn change_color(
&mut self,
color: String,
) {
self.color = color;
}
}
pub struct MyAnim {
count: i32,
}
impl MyAnim {
pub fn new() -> Self {
Self { count: 0 }
}
}
impl Animator for MyAnim {
fn animate(
&mut self,
entity: &mut Entity,
) {
let pos = entity.pos_mut();
if (self.count % 2) == 0 {
pos.x += 0.1;
pos.y += 0.2;
} else {
pos.x += 0.2;
pos.y += 0.1;
}
self.count += 1;
if self.count >= 3 {
entity.change_color("red".to_owned());
}
}
}
}
fn main() {
use common::{Entity, Pos};
use custom::{MyAnim, MyShape};
let mut entity = Entity::new(
Pos { x: 0.0, y: 0.0 },
Box::new(MyShape::new("green".to_owned())),
Box::new(MyAnim::new()),
);
entity.draw();
for _ in 0..5 {
entity.animate();
entity.draw();
}
}
As you can see, the provided code cannot be compiled since, at line 66, anim is a mutable reference to the Animator component responsible for the dynamic dispatch but the parameter of the method is also a mutable reference to the Entity as a whole which contains the previous Animator.
This parameter is needed if we want the Animator to be able to make changes on the entity.
I'm stuck with this situation and I can only think about workarounds that look quite ugly to me:
don't pass the entity as a parameter but each of its field (except the animator) as many parameters: what's the point of defining structs then? (if an entity is made of twelve fields, should I pass eleven parameters every time I would act on this entity?)
embed each field of an entity in a RefCell and pretend every parameter of every function is a non-mutable reference, then borrow_mut() everywhere we want to and hope it won't panic: for me, it's like giving-up the idea that function prototypes tell and enforce the intent of the code (let's add some Rc everywhere in order to totally forget who owns what, and we obtain Java ;^)
I'm certain I did some bad choices about what deserves to be exclusive (&mut) or shared (&), but I can't see a reasonable limit.
In my opinion, when an entity has to be animated, it's its own concern: there is nothing to be shared, except looking at the state of the surrounding environment (but not changing it).
If we share everything and rely on interior-mutability in order to enable safe mutations at run-time (thanks to the ref-count) it sounds to me like: «let's drive like crazy, as if there were no traffic regulations, as long as no one complains (try_borrow()/try_borrow_mut()) and we don't have any accident (panic!())».
Could anyone suggest a better organisation of my structs/functions in order to enable the intended behaviour: an entity made of a few dynamic (as in OOP) components responsible for the details of the actions on the concerned entity?
I want to return an iterator (in particular, a Filter). I used a previous answer that suggests returning a boxed iterator. The problem is that my filter captures self and I get:
error: closure may outlive the current function, but it borrows self, which is owned by the current function
But I think I'm being explicit that self has lifetime 'a and so does the Box I'm returning:
fn occupied_iter_x<'a>(&'a self) -> Box<Iterator<Item=i32> + 'a> {
Box::new( (0..32).filter( |&pos| match self.at(pos) { Occupied::Empty => false, _ => true } ) )
}
This is an attempt to simplify my first effort, where I created a new FooIterator which owns a reference to self in basically the same way.
If I use most of the same syntax to simply capture self as a member reference it works fine:
struct Foo { junk: i32 }
struct FooIterator<'a> { foo: &'a Foo }
impl Foo {
fn foo<'a>(&'a self) -> Box<FooIterator<'a>> {
Box::new( FooIterator { foo: self } )
}
}
You get an error because your closure receives a reference to self, which itself is a reference. However, since the reference points to a local variable, that reference becomes invalid as soon as the function returns.
To fix this, add the move keyword before the closure. This instructs the compiler to move the closed-over variables in the closure, rather than pass a reference to those variables to the closure.
fn occupied_iter_x<'a>(&'a self) -> Box<Iterator<Item=i32> + 'a> {
Box::new( (0..32).filter(move |&pos| match self.at(pos) { Occupied::Empty => false, _ => true } ) )
}
I currently want to define a struct for a Piston game using GamerIterator:
pub struct MyGame<'a> {
game_window: GameWindowGLFW,
game_iter: GameIterator<'a, GameWindowGLFW>,
//...
}
The GameIterator is generic in the GameWindow and its lifetime. I want to tell the compiler that it has the same lifetime as the field "game_window"/"the whole struct" and leave out the lifetime for the struct.
I also have difficulties initializing this:
MyGame {
game_window: GameWindowGLFW::new(GameWindowSettings {/*...*/},
game_iter: GameIterator::new(&mut game_window, &game_iter_settings), // game_window cannot be used here
//...
}
I think that I can work around the initialization issue by using Option<GameIterator<...>> and an init() method, but I would like to avoid this because I can guarantee that game_iter is present after new() finishes.
What is the idiomatic way to write this?
Not only is there an issue with initialization, there could also be issues with destruction, if GameIterator implemented Drop: the compiler would have to know that it needs to destruct game_iter before game_window, otherwise game_window would have a reference to a destroyed GameWindowGLFW while running its drop() method.
There's no way to pass the lifetime of the struct itself as a lifetime argument. The only thing you can do is remove the game_window field from MyGame and pass a GameWindowGLFW instance to MyGame's initializer. If you want to encapsulate this so that the user doesn't need to create a GameWindowGLFW, you could write a method that creates a GameWindowGLFW and a MyGame on the stack and calls a closure that accepts a MyGame argument only.
pub struct MyGame<'a> {
game_iter: GameIterator<'a, GameWindowGLFW>,
//...
}
impl<'a> MyGame<'a> {
fn new(game_window: &'a mut GameWindowGLFW) -> MyGame<'a> {
MyGame {
game_iter: GameIterator { game_window: game_window },
}
}
}
fn start_game(callback: |game: &mut MyGame|) {
let mut game_window = GameWindowGLFW;
let mut game = MyGame::new(&mut game_window);
callback(&mut game);
}
fn main() {
start_game(|game| {
/* use game here */
});
}
I am very new to Rust but I am trying to work out how to modify an instance of an enum. I need to use managed boxes for other reasons, but it seems to make changing an enum's field hard.
#[feature(managed_boxes)];
enum State { A(int), B }
fn main() {
let mut state = #A(123);
match *state {
A(ref mut i) => { *i = 456 }
B => { }
}
println!("{:?}", state)
}
I get the error cannot borrow immutable anonymous field as mutable. The mut seems to only say that state, the variable, is mutable. I want to tell Rust the whole thing is mutable. I find forced immutability one of the most annoying things of Rust.
Some time ago managed boxed had their own "hierarchy" of mutability. The following code used to work then:
#[feature(managed_boxes)];
enum State { A(int), B }
fn main() {
let state = #mut A(123);
match *state {
A(ref mut i) => { *i = 456 }
B => { }
}
println!("{:?}", state)
}
But managed boxes are scheduled to be removed from the language. In current version of Rust #mut is not a valid token. You have to use RefCell, a mutable cell which provides mutability inside managed pointers. Currently it looks somewhat like this:
#[feature(managed_boxes)];
use std::cell::RefCell;
enum State { A(int), B }
fn main() {
let state = #RefCell::new(A(123));
{
let mut r = state.borrow_mut();
match r.get() {
&A(ref mut i) => { *i = 456 }
&B => { }
}
}
println!("{:?}", state)
}
You will get rather extensive output on the terminal though, because it will print internals of RefCell structure. See documentation on std::cell module for more information on cells and how to use them.
In the future Rust won't have special syntax for managed boxes at all. Garbage collection will be implemented in libraries. I believe the code will look like this (Rust authors, please correct me if I'm wrong):
use std::cell::RefCell;
enum State { A(int), B }
fn main() {
// state is of type Gc<RefCell<State>>
let state = box(Gc) RefCell::new(A(123));
// Dereference will work for library pointer types, not sure about autodereference
let mut r = (*state).borrow_mut();
match r.get() {
&A(ref mut i) => { *i = 456 }
&B => { }
}
println!("{:?}", *state)
}
I am fiddling around with Rust, going by the examples, trying to make a class. I have been looking at the example of StatusLineText
It keeps raising the errors:
error: `self` is not available in a static method. Maybe a `self` argument is missing? [E0424]
self.id + self.extra
^~~~
error: no method named `get_total` found for type `main::Thing` in the current scope
println!("the thing's total is {}", my_thing.get_total());
^~~~~~~~~
My code is rather simple:
fn main() {
struct Thing {
id: i8,
extra: i8,
}
impl Thing {
pub fn new() -> Thing {
Thing { id: 3, extra: 2 }
}
pub fn get_total() -> i8 {
self.id + self.extra
}
}
let my_thing = Thing::new();
println!("the thing's total is {}", my_thing.get_total());
}
You need to add an explicit self parameter to make methods:
fn get_total(&self) -> i8 {
self.id + self.extra
}
Functions without the explicit self parameter are considered associated functions, which can be called without a specific instance.