Reputation: 1561
I'm updating some old Rust code that used smart pointers and other memory management code that was deprecated and removed prior to the version 1 release.
Is there a direct replacement for the likes of the old smart pointers or is it better to use the likes of Box for allocating memory?
I have code such as (and this is very much simplified!)
struct my_rectangle {
x: i32,
y: i32,
length: i32,
breadth: i32,
}
fn allocate_rect() {
let x: ~my_rectangle = ~my_rectangle{x: 5, y: 5, length: 25, breadth:15};
}
and
fn firstMethod() {
let memblock: @int = @256;
secondMethod(memblock);
println!(“%d”, *memblock);
}
fn secondMethod(memblock: @int) {
let secMemblock: @int = memblock;
}
This works fine prior to 1.0 but now fails to build.
Upvotes: 3
Views: 271
Reputation: 430663
The other answers cover the principles, so here's your specific examples updated:
struct MyRectangle {
x: i32,
y: i32,
length: i32,
breadth: i32,
}
fn allocate_rect() {
Box::new(MyRectangle {
x: 5,
y: 5,
length: 25,
breadth: 15,
});
}
use std::rc::Rc;
fn first_method() {
let memblock = Rc::new(256);
second_method(memblock.clone());
println!("{}", memblock);
}
fn second_method(memblock: Rc<isize>) {
let sec_memblock = memblock;
}
int
and uint
became isize
and usize
, respectively. However, you shouldn't just blindly transform these - often times a specific sized integer is better.CamelCase
while functions use snake_case
.println!
no longer uses printf-style format strings. Instead, there are placeholders like {}
and {:?}
corresponding to traits like Display
and Debug
.println!
.second_method
would transfer ownership of the argument and then you couldn't print it. You need to call clone
to increment the reference count and pass the cloned value to the function.I second the recommendation to evaluate if you really need to box many of these values. In some cases, you may be able to accept a reference or perform a copy of the value (which should be cheap).
Upvotes: 3
Reputation: 177
You can replace ~T
by Box<T>
, and ~[T]
by Vec<T>
. The @T
smartpointers can be replaced by Rc<T>
, and @[T]
by Rc<RefCell<Vec<T>>>
. Be careful not to create cycles with Rc<T>
, there is no cycle-collector anymore. If the code you wish to update looks anything like the code in your examples, then I would recommend not using pointers at all. ~T
(or Box<T>
) in particular tends to be overused, and can often be replaced by a simple T
.
Upvotes: 3
Reputation: 65742
~T
was changed to Box<T>
. ~expr
should now be Box::new(expr)
.
@T
was removed; it was meant to be a pointer to a garbage-collected object, but that was never really the case. The standard library provides reference-counted pointer, Rc<T>
and Arc<T>
, that should cover most use cases.
Rust has changed quite a bit until 1.0. You might want to read The Rust Programming Language to get yourself up to date.
Upvotes: 6