pub struct Character {
name: String,
hp: i32,
level: i32,
xp: i32,
xp_needed: i32,
gold: i32
}
impl Character {
pub fn new(name: String) -> Character {
let mut rng = thread_rng();
let hp: i32 = rng.gen_range(12, 75);
let gold: i32 = rng.gen_range(10, 50);
Character { name: name, hp: hp, level: 1, xp: 0, gold: gold, xp_needed: 100 }
}
pub fn get_name(&self) -> String {
self.name
}
// ...
}
How exactly am I breaking the rules here?
At a high-level, this is against-the-grain for Rust. You cannot transfer ownership of something borrowed because you don't own it.
Um don't I? I have other functions like:
pub fn get_hp(&self) -> i32 {
self.hp
}
And that works just fine.
|
23 | self.name
| ^^^^ cannot move out of borrowed content
error: aborting due to previous error
What's going on? What is the appropriate approach to return the character name? Why does the get_hp method work but not get_name?
The difference between get_hp and get_name is that get_hp returns a i32. i32 is a Copy type. Copy types can be copied by simply copying bits and are never moved out. On the other hand String is not Copy, it manages some memory which must either be transferred (moved out) or Cloned.
For getters like this, it is more idiomatic to return references instead of cloning. And for Strings, it should specifically be &str.
pub fn get_name(&self) -> &str {
&self.name
}
Related
I'm making a maze algorithm using rust and wasm and I have two structs. A maze, and maze has an Vec of a Block struct.
Like this:
pub struct Maze {
pub cols: usize,
pub rows: usize,
pub blocks: Vec<Block>,
pub stack: Vec<usize>,
}
impl Maze {
pub fn new(cols: usize, rows: usize) -> Maze {
let mut maze = Maze {
cols,
rows,
blocks: vec![],
};
for y in 0..rows {
for x in 0..cols {
maze.blocks.push(Block::new(x, y))
}
}
maze
}
And the struct Block has an attribute called visited.
I want in a struct function of Maze change this value
// in Maze struct impl
pub fn run(&mut self) {
let current_index = self.get_current_index();
let mut current_block = &mut &self.blocks[current_index];
// .....
*current_block.visited = true;
In the last line occur an error:
error[E0614]: type `bool` cannot be dereferenced
--> src/maze.rs:119:17
|
119 | *current_block.visited = true;
| ^^^^^^^^^^^^^^^^^^^^^^
How can I do to change this value?
This is my implementation of Block
pub struct Block {
pub x: usize,
pub y: usize,
pub visited: bool,
}
impl Block {
pub fn new(x: usize, y: usize) -> Block {
Block {
x,
y,
visited: false,
}
}
How can I do to change the visited value from Maze.run?
There are two problems, one which is the error you see and one which you will encounter next. The problem with
*current_block.visited = true;
is that the precedence of * is lower than ., so you've written code equivalent to)
*(current_block.visited) = true;
which does not compile because the type of the visited field is bool, which indeed cannot be dereferenced. You could write
(*current_block).visited = true;
and that would work, but it's also unnecessary, because in Rust the . operator looks through references, so you only need
current_block.visited = true;
to assign to the visited field of an &mut Block.
The second problem is that you have an extra & here:
let mut current_block = &mut &self.blocks[current_index];
This means current_block is of type &mut &Block. You can never mutate through an & reference, so you need to remove the &, and it is not needed anyway:
let mut current_block = &mut self.blocks[current_index];
I have a struct Foo:
struct Foo {
v: String,
// Other data not important for the question
}
I want to handle a data stream and save the result into Vec<Foo> and also create an index for this Vec<Foo> on the field Foo::v.
I want to use a HashMap<&str, usize> for the index, where the keys will be &Foo::v and the value is the position in the Vec<Foo>, but I'm open to other suggestions.
I want to do the data stream handling as fast as possible, which requires not doing obvious things twice.
For example, I want to:
allocate a String only once per one data stream reading
not search the index twice, once to check that the key does not exist, once for inserting new key.
not increase the run time by using Rc or RefCell.
The borrow checker does not allow this code:
let mut l = Vec::<Foo>::new();
{
let mut hash = HashMap::<&str, usize>::new();
//here is loop in real code, like:
//let mut s: String;
//while get_s(&mut s) {
let s = "aaa".to_string();
let idx: usize = match hash.entry(&s) { //a
Occupied(ent) => {
*ent.get()
}
Vacant(ent) => {
l.push(Foo { v: s }); //b
ent.insert(l.len() - 1);
l.len() - 1
}
};
// do something with idx
}
There are multiple problems:
hash.entry borrows the key so s must have a "bigger" lifetime than hash
I want to move s at line (b), while I have a read-only reference at line (a)
So how should I implement this simple algorithm without an extra call to String::clone or calling HashMap::get after calling HashMap::insert?
In general, what you are trying to accomplish is unsafe and Rust is correctly preventing you from doing something you shouldn't. For a simple example why, consider a Vec<u8>. If the vector has one item and a capacity of one, adding another value to the vector will cause a re-allocation and copying of all the values in the vector, invalidating any references into the vector. This would cause all of your keys in your index to point to arbitrary memory addresses, thus leading to unsafe behavior. The compiler prevents that.
In this case, there's two extra pieces of information that the compiler is unaware of but the programmer isn't:
There's an extra indirection — String is heap-allocated, so moving the pointer to that heap allocation isn't really a problem.
The String will never be changed. If it were, then it might reallocate, invalidating the referred-to address. Using a Box<[str]> instead of a String would be a way to enforce this via the type system.
In cases like this, it is OK to use unsafe code, so long as you properly document why it's not unsafe.
use std::collections::HashMap;
#[derive(Debug)]
struct Player {
name: String,
}
fn main() {
let names = ["alice", "bob", "clarice", "danny", "eustice", "frank"];
let mut players = Vec::new();
let mut index = HashMap::new();
for &name in &names {
let player = Player { name: name.into() };
let idx = players.len();
// I copied this code from Stack Overflow without reading the prose
// that describes why this unsafe block is actually safe
let stable_name: &str = unsafe { &*(player.name.as_str() as *const str) };
players.push(player);
index.insert(idx, stable_name);
}
for (k, v) in &index {
println!("{:?} -> {:?}", k, v);
}
for v in &players {
println!("{:?}", v);
}
}
However, my guess is that you don't want this code in your main method but want to return it from some function. That will be a problem, as you will quickly run into Why can't I store a value and a reference to that value in the same struct?.
Honestly, there's styles of code that don't fit well within Rust's limitations. If you run into these, you could:
decide that Rust isn't a good fit for you or your problem.
use unsafe code, preferably thoroughly tested and only exposing a safe API.
investigate alternate representations.
For example, I'd probably rewrite the code to have the index be the primary owner of the key:
use std::collections::BTreeMap;
#[derive(Debug)]
struct Player<'a> {
name: &'a str,
data: &'a PlayerData,
}
#[derive(Debug)]
struct PlayerData {
hit_points: u8,
}
#[derive(Debug)]
struct Players(BTreeMap<String, PlayerData>);
impl Players {
fn new<I>(iter: I) -> Self
where
I: IntoIterator,
I::Item: Into<String>,
{
let players = iter
.into_iter()
.map(|name| (name.into(), PlayerData { hit_points: 100 }))
.collect();
Players(players)
}
fn get<'a>(&'a self, name: &'a str) -> Option<Player<'a>> {
self.0.get(name).map(|data| Player { name, data })
}
}
fn main() {
let names = ["alice", "bob", "clarice", "danny", "eustice", "frank"];
let players = Players::new(names.iter().copied());
for (k, v) in &players.0 {
println!("{:?} -> {:?}", k, v);
}
println!("{:?}", players.get("eustice"));
}
Alternatively, as shown in What's the idiomatic way to make a lookup table which uses field of the item as the key?, you could wrap your type and store it in a set container instead:
use std::collections::BTreeSet;
#[derive(Debug, PartialEq, Eq)]
struct Player {
name: String,
hit_points: u8,
}
#[derive(Debug, Eq)]
struct PlayerByName(Player);
impl PlayerByName {
fn key(&self) -> &str {
&self.0.name
}
}
impl PartialOrd for PlayerByName {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for PlayerByName {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.key().cmp(&other.key())
}
}
impl PartialEq for PlayerByName {
fn eq(&self, other: &Self) -> bool {
self.key() == other.key()
}
}
impl std::borrow::Borrow<str> for PlayerByName {
fn borrow(&self) -> &str {
self.key()
}
}
#[derive(Debug)]
struct Players(BTreeSet<PlayerByName>);
impl Players {
fn new<I>(iter: I) -> Self
where
I: IntoIterator,
I::Item: Into<String>,
{
let players = iter
.into_iter()
.map(|name| {
PlayerByName(Player {
name: name.into(),
hit_points: 100,
})
})
.collect();
Players(players)
}
fn get(&self, name: &str) -> Option<&Player> {
self.0.get(name).map(|pbn| &pbn.0)
}
}
fn main() {
let names = ["alice", "bob", "clarice", "danny", "eustice", "frank"];
let players = Players::new(names.iter().copied());
for player in &players.0 {
println!("{:?}", player.0);
}
println!("{:?}", players.get("eustice"));
}
not increase the run time by using Rc or RefCell
Guessing about performance characteristics without performing profiling is never a good idea. I honestly don't believe that there'd be a noticeable performance loss from incrementing an integer when a value is cloned or dropped. If the problem required both an index and a vector, then I would reach for some kind of shared ownership.
not increase the run time by using Rc or RefCell.
#Shepmaster already demonstrated accomplishing this using unsafe, once you have I would encourage you to check how much Rc actually would cost you. Here is a full version with Rc:
use std::{
collections::{hash_map::Entry, HashMap},
rc::Rc,
};
#[derive(Debug)]
struct Foo {
v: Rc<str>,
}
#[derive(Debug)]
struct Collection {
vec: Vec<Foo>,
index: HashMap<Rc<str>, usize>,
}
impl Foo {
fn new(s: &str) -> Foo {
Foo {
v: s.into(),
}
}
}
impl Collection {
fn new() -> Collection {
Collection {
vec: Vec::new(),
index: HashMap::new(),
}
}
fn insert(&mut self, foo: Foo) {
match self.index.entry(foo.v.clone()) {
Entry::Occupied(o) => panic!(
"Duplicate entry for: {}, {:?} inserted before {:?}",
foo.v,
o.get(),
foo
),
Entry::Vacant(v) => v.insert(self.vec.len()),
};
self.vec.push(foo)
}
}
fn main() {
let mut collection = Collection::new();
for foo in vec![Foo::new("Hello"), Foo::new("World"), Foo::new("Go!")] {
collection.insert(foo)
}
println!("{:?}", collection);
}
The error is:
error: `s` does not live long enough
--> <anon>:27:5
|
16 | let idx: usize = match hash.entry(&s) { //a
| - borrow occurs here
...
27 | }
| ^ `s` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
The note: at the end is where the answer is.
s must outlive hash because you are using &s as a key in the HashMap. This reference will become invalid when s is dropped. But, as the note says, hash will be dropped after s. A quick fix is to swap the order of their declarations:
let s = "aaa".to_string();
let mut hash = HashMap::<&str, usize>::new();
But now you have another problem:
error[E0505]: cannot move out of `s` because it is borrowed
--> <anon>:22:33
|
17 | let idx: usize = match hash.entry(&s) { //a
| - borrow of `s` occurs here
...
22 | l.push(Foo { v: s }); //b
| ^ move out of `s` occurs here
This one is more obvious. s is borrowed by the Entry, which will live to the end of the block. Cloning s will fix that:
l.push(Foo { v: s.clone() }); //b
I only want to allocate s only once, not cloning it
But the type of Foo.v is String, so it will own its own copy of the str anyway. Just that type means you have to copy the s.
You can replace it with a &str instead which will allow it to stay as a reference into s:
struct Foo<'a> {
v: &'a str,
}
pub fn main() {
// s now lives longer than l
let s = "aaa".to_string();
let mut l = Vec::<Foo>::new();
{
let mut hash = HashMap::<&str, usize>::new();
let idx: usize = match hash.entry(&s) {
Occupied(ent) => {
*ent.get()
}
Vacant(ent) => {
l.push(Foo { v: &s });
ent.insert(l.len() - 1);
l.len() - 1
}
};
}
}
Note that, previously I had to move the declaration of s to before hash, so that it would outlive it. But now, l holds a reference to s, so it has to be declared even earlier, so that it outlives l.
It seems that if you borrow a reference to a struct field, the whole struct is considered borrowed. I've managed to isolate and example of what I want to do. I just want to get a "read-only" reference to a field in B to obtain some data and then modify another field of B. Is there a idiomatic Rust way to do this?
struct A {
i: i32,
}
struct B {
j: i32,
a: Box<A>,
}
impl B {
fn get<'a>(&'a mut self) -> &'a A {
&*self.a
}
fn set(&mut self, j: i32) {
self.j = j
}
}
fn foo(a: &A) -> i32 {
a.i + 1
}
fn main() {
let a = Box::new(A { i: 47 });
let mut b = B { a: a, j: 1 };
let a_ref = b.get();
b.set(foo(a_ref));
}
error[E0499]: cannot borrow `b` as mutable more than once at a time
--> src/main.rs:27:5
|
26 | let a_ref = b.get();
| - first mutable borrow occurs here
27 | b.set(foo(a_ref));
| ^ second mutable borrow occurs here
28 | }
| - first borrow ends here
It's a feature of the language. From the compiler point of view, there is no way for it to know that it's safe to call your set() function while a is borrowed via get().
Your get() function borrows b mutably, and returns a reference, thus b will remain borrowed until this reference goes out of scope.
You have several way of handling this:
Separate your two fields into two different structs
Move the code which needs to access both attribute inside a method of B
Make your attributes public, you will thus be able to directly get references to them
Compute the new value before setting it, like this:
fn main() {
let a = Box::new(A { i: 47 });
let mut b = B { a: a, j: 1 };
let newval = {
let a_ref = b.get();
foo(a_ref)
};
b.set(newval);
}
Expanding a bit on Levans' answer
Move the code which needs to access both attribute inside a method of B
That might look like this at a first pass:
impl B {
fn do_thing(&mut self) {
self.j = self.a.foo()
}
}
However, this hard-codes the call to foo. You could also accept a closure to allow this to be more flexible:
impl B {
fn update_j_with_a<F>(&mut self, f: F)
where
F: FnOnce(&mut A) -> i32,
{
self.j = f(&mut self.a)
}
}
// ...
b.update_j_with_a(|a| a.foo())
Separate your two fields into two different structs
This is also applicable when you have borrowed two disjoint subsets of attributes. For example:
struct A {
description: String,
name: String,
age: u8,
money: i32,
}
impl A {
fn update_description(&mut self) {
let description = &mut self.description;
*description = self.build_description()
// cannot borrow `*self` as immutable because `self.description` is also borrowed as mutable
}
fn build_description(&self) -> String {
format!(
"{} is {} years old and has {} money",
self.name,
self.age,
self.money
)
}
}
fn main() {}
Can be changed into
struct A {
description: String,
info: Info,
}
struct Info {
name: String,
age: u8,
money: i32,
}
impl A {
fn update_description(&mut self) {
let description = &mut self.description;
*description = self.info.build_description()
}
}
impl Info {
fn build_description(&self) -> String {
format!(
"{} is {} years old and has {} money",
self.name,
self.age,
self.money
)
}
}
fn main() {}
You can combine these two steps (and I'd say that it's better practice) and move the method onto the inner struct.
This is a simplified version of a piece of code I am trying to implement:
struct FirstStruct
{
a: i8,
}
impl FirstStruct
{
fn get(&self) -> Option<&str>
{
Some("aaa")
}
}
pub struct SecondStruct<'a>
{
pub name: Option<&'a str>,
}
impl<'a> SecondStruct<'a>
{
fn extract_string(obj: &/*'a*/ FirstStruct) -> Option<&'a str>
{
obj.get() //this is where the error happen
}
pub fn from_string() -> SecondStruct<'a>
{
let obj = FirstStruct{a: 1};
SecondStruct{
name: SecondStruct::extract_string(&obj),
}
}
}
fn main()
{
let g_def_res = SecondStruct::from_string();
}
This code throws the following error :
test2.rs:23:13: 23:18 error: cannot infer an appropriate lifetime for autoref due to conflicting requirements
test2.rs:23 obj.get() //this is where the error happen
^~~~~
test2.rs:21:5: 24:6 help: consider using an explicit lifetime parameter as shown: fn extract_string(obj: &'a FirstStruct) -> Option<&'a str>
test2.rs:21 fn extract_string(obj: &FirstStruct) -> Option<&'a str>
test2.rs:22 {
test2.rs:23 obj.get() //this is where the error happen
test2.rs:24 }
error: aborting due to previous error
Applying the proposed solution throw this error :
test2.rs:30:55: 30:58 error: `obj` does not live long enough
test2.rs:30 name: SecondStruct::extract_string(&obj),
^~~
test2.rs:27:5: 32:6 note: reference must be valid for the lifetime 'a as defined on the block at 27:4...
test2.rs:27 {
test2.rs:28 let obj = FirstStruct{a: 1};
test2.rs:29 SecondStruct{
test2.rs:30 name: SecondStruct::extract_string(&obj),
test2.rs:31 }
test2.rs:32 }
test2.rs:28:37: 32:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 28:36
test2.rs:28 let obj = FirstStruct{a: 1};
test2.rs:29 SecondStruct{
test2.rs:30 name: SecondStruct::extract_string(&obj),
test2.rs:31 }
test2.rs:32 }
error: aborting due to previous error
To summarise:
How to say that the return value of FirstStruct::get must have the lifetime of either [the return value of SecondStruct::from_str | the struct lifetime 'a]? I think both refer to same thing?
pub fn from_string() -> SecondStruct<'a> {
let obj = FirstStruct { a: 1 };
SecondStruct {
name: SecondStruct::extract_string(&obj),
}
}
This code says "I will return a SecondStruct with the lifetime 'a". The caller of the code gets to determine what the length of the lifetime 'a is. This is almost never what you want!
// Lifetime elision means the method is equivalent to this
// fn get<'a>(&'a self) -> Option<&'a str>
fn get(&self) -> Option<&str> {
Some("aaa")
}
This code uses says that the string returned will live as long as self lives.
Put these two concepts together, and you can understand your error. The variable obj is only defined to live as long as the function call is active. However, you are trying to return a reference to the inner-workings of the struct beyond the call! Actually, you are trying to return it for any arbitrary lifetime the caller decides! This is Rust preventing you from shooting yourself in the foot, hooray for Rust!
So how do you fix your problem? For the provided example code, the easiest thing is to just use the 'static lifetime:
struct FirstStruct { a: i8 }
impl FirstStruct {
fn get(&self) -> Option<&'static str> { Some("aaa") }
}
pub struct SecondStruct<'a> { name: Option<&'a str> }
impl<'a> SecondStruct<'a> {
fn extract_string(obj: &FirstStruct) -> Option<&'static str> { obj.get() }
pub fn from_string() -> SecondStruct<'static> {
let obj = FirstStruct { a: 1 };
SecondStruct { name: SecondStruct::extract_string(&obj) }
}
}
fn main() {
let g_def_res = SecondStruct::from_string();
}
But that's probably not what you really want. The next thing to try would be to embed FirstStruct inside SecondStruct, and simply delegate to it. Another option would be to move from &str to String - String owns the string data, and so you can transfer ownership from First to Second.
Whatever you do, you have to ensure that the source of the string data outlives the function call to from_string.
Either the return value of FirstStruct::get has been allocated on the stack or it has been allocated on the heap.
It's trickier than that. The return value is always on the stack. That is, the Option<&str> takes up space on the stack. The &str may contain a pointer to something that is allocated either on the stack or heap, it's not known by this code. All you know is that the pointed-at value is guaranteed to live for the lifetime of that specific FirstStruct item.
You don't own the string, so you can't transfer ownership around.
I can't move FirstStruct because it is from another library (rustc-serialize
I'm not sure what you mean. If you have an object, then you can embed it into your object. The fact that it comes from another crate doesn't come into play. If you have a reference to something, then you can still capture the reference, but then your object has to live for a shorter period than the reference (so that it never becomes invalid).
Unwrapping Option, updating to a string and rewrapping in Option is a lot of boilerplate.
Have you seen Option::map? It makes this kind of thing very succinct. Combined with From, you can write a very short thing to convert an Option<&str> to Option<String>:
// fn is just to establish some types, you'd just use the `.map` call in real code
fn foo(a: Option<&str>) -> Option<String> {
a.map(From::from)
}
I'm running into this issue. My code looks like this:
struct MyStruct {
name:String
}
impl MyStruct {
fn foo(&mut self) {
self.name = "Bob";
self.bar(self, "Foo");
}
fn bar(&mut self, my_struct: MyStruct, last_name: String) {
self.name = format!("{} {}", my_struct.name, last_name)
}
}
However, I'm getting this error error: mismatched types: expected 'MyStruct', found '&mut MyStruct' (expected struct MyStruct, found &-ptr) in my foo method. I understand that Rust has not yet reached its 1.0 release but I'd like to understand pointers in Rust.
What am I doing wrong and what are some other ways to fix it?
What I've tried:
let f = *self;
self.bar(f, "Foo"); // works using the "raw pointer"
self.bar(*self, "Foo"); // doesn't work.. Error message: "borrow of `*self` occurs here"
rust version: rustc 0.12.0-pre-nightly (09abbbdaf 2014-09-11 00:05:41 +0000)
First of all, literals like "Foo" are not Strings, they are &'static strs. The difference is, String is an actual allocated buffer containing string contents and &str is just a view into existing buffer. &'static strs are, therefore, views into some statically allocated data. You can't pass &str as a String, so your example should look something like this:
struct MyStruct {
name:String
}
impl MyStruct {
fn foo(&mut self) {
self.name = "Bob".to_string();
self.bar(self, "Foo");
}
fn bar(&mut self, my_struct: MyStruct, last_name: &str) {
self.name = format!("{} {}", my_struct.name, last_name)
}
}
However, this doesn't work, as you have already noticed, and won't even after the String -> &str change:
self.bar(self, "Foo")
Neither will this:
self.bar(*self, "Foo")
nor this:
let f = *self; // this is not a "raw pointer", BTW, this is just a dereference
self.bar(f, "Foo")
The first variant won't work simply because the types do not match: self is &mut MyStruct, and bar() expects plain MyStruct as the first argument.
The second and the third variants are basically equivalent and could in fact work if MyStruct was a Copy type (if it implemented Copy trait). It isn't, however, because it contains String, which is not a Copy type since it has an associated destructor. Because of this the compiler does not implement Copy for MyStruct, and values of such types can only be moved around, not copied.
But you can't move a value out of &mut reference because a reference is a non-owning view of data, so *self just won't compile.
Moreover, there is a further obstacle. Because you want to pass self into bar() somehow, you can't do it using references, which would be the best choice otherwise. That is, this won't work:
fn bar(&mut self, my_struct: &MyStruct, last_name: &str) {
self.name = format!("{} {}", my_struct.name, last_name);
}
self.bar(self, "Foo"); // self as an argument is auto-reborrowed from &mut to &
This happens because Rust does not allow having &mut reference into some data at the same time with any other reference to the same data, and this is exactly what would happen here: self.bar(self, "Foo") method call requires &mut MyStruct as its target but also &MyStruct as its argument, and because self is passed as both of them, the compiler would reject it.
Hence if you want to keep the code as close as possible to your original intent, your best bet would be using Clone. Derive Clone for your structure:
#[deriving(Clone)]
struct MyStruct {
name: String
}
Then you can use clone() method to obtain a copy of your structure:
impl MyStruct {
fn foo(&mut self) {
self.name = "Bob".to_string();
let c = self.clone();
self.bar(c, "Foo");
}
fn bar(&mut self, my_struct: MyStruct, last_name: &str) {
self.name = format!("{} {}", my_struct.name, last_name)
}
}
However, it is possible that your code needs restructuring. Often such things could be expressed more clearly, for example, by moving bar() call up to foo() caller.
I highly recommend reading the official Rust guide which explains such concepts as ownership, borrowing and references. After that the reason why your code does not work should be more clear.
You have two problems in your code.
The first is a minor problem with your strings. When you type "Bob", it has type &'static str, while you want String in at least some of the places in your code. This is easily fixed by replacing "Bob" with "Bob".to_string().
The second problem is that, you are essentially trying to give the same value to the function twice. You can do that in rust, but you need to be very careful about how you do it.
The easiest way to fix, would be to clone the object, thus giving two different (but equal) objects. Your example in this case would be:
#[deriving(Clone)]
struct MyStruct {
name:String
}
impl MyStruct {
fn foo(&mut self) {
self.name = "Bob".to_string();
let cloned = self.clone();
self.bar(clone, "Foo".to_string());
}
fn bar(&mut self, my_struct: MyStruct, last_name: String) {
self.name = format!("{} {}", my_struct.name, last_name)
}
}