This question already has answers here:
What are Rust's exact auto-dereferencing rules?
(4 answers)
Closed 2 months ago.
I just have started learning Rust. While going to some of its examples, I could not understand behaviour of references (Which I loosely relate with pointers).
fn main(){
let mut s = String::from("abc");
DoStuff(&mut s);
}
fn DoStuff(reff : &mut String){
reff.push_str("xyz");
(*reff).push_str("xyz");
// In the above two lines, why they perform similar actions?
// as reff and *reff are different types.
// *reff should only be able to call pust.str(). But how reff can also call it?
// reff = String::from("dsf"); --> Why this will give compile error
// if reff & (*reff) behaves somewhat similar for us
}
In the above example,
both lines
reff.push_str("xyz");
(*reff).push_str("xyz");
act similar.
As, pust_str() is a method from String. Only (*reff) should be able to call it as per my understanding. Still, reff is also able to call it.
How can I understand this unexpected behaviour?
Types that implement the Deref trait do automatic dereferencing.
Mostly so you don't have to write (*reff). all the time.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
This post was edited and submitted for review 10 months ago and failed to reopen the post:
Opinion-based Update the question so it can be answered with facts and citations by editing this post.
Improve this question
What typical scenario would traits be used for in a Rust program? I have tried to wrap my head around them, but I still don't have a clear concept as to why one would decide to use them. I understand the syntax from reading about them from here.
How would one explain them to someone as if they were 5?
From the docs:
A trait is a collection of methods defined for an unknown type: Self. They can access other methods declared in the same trait.
Traits are similar to interfaces in languages like Java, C++, etc.
It would really be helpful to go over examples, such as the ToString and the Display traits.
If you write this:
format!("x is {x}");
the code will only work (and compile) if x implements the Display interface.
Similarly, this will only work if x implements the Debug interface:
format!("{x:?}");
Leaving aside the "magic" associated with formatting strings, it should be clear x cannot be an instance of just any type. There needs to be a specific implementation that converts a given type to a string. Note that u16's implementation, for example, would be completely different from, say, IpAddr's implementation. However, both types have a common behavior. As a result, a string formatter doesn't even need to know which types implement the Display or Debug trait. It's not its concern. It only cares whether the type in question implements the given trait (and if it does not, the compiler simply won't accept that code).
One way to conceptualize traits is to think of them as 'behaviors you want available to, and to operate over, a particular chunk of state'. So, if you have some struct that contains state, and you want to do something with it, you would write a trait for it.
There are two primary usages:
You are dealing with a struct in your code, and you would like that struct to know how perform some behavior. You can call the trait-defined behavior on the struct.
You would like to pass the struct to some other code (yours or a third party) that might not know anything about the struct itself, but want to perform some set of functions on it, trusting that the struct knows what to do in those cases.
In the first case, it allows you to do things like this:
struct Article {
body: String
}
trait Saveable {
fn save(&self) -> ();
}
impl Saveable for Article {
fn save(&self) -> () {
... // All the code you need to run to save the Article object
}
}
// A function called by your UX
fn handle_article_update(article: Article) -> () {
...
article.save() // Call the save functionality
}
The second case is arguably more interesting, though. Let's say you - or more probably a third party - has a function defined like this:
fn save_object(obj: Saveable) -> () {
...
obj.save()
}
struct Person {
name: String
}
impl Saveable for Person {
fn save(&self) -> () {
... // Code needed to save a Person object, could be different from that needed for an Article object
}
}
...
// Note that we are using the same function to save both of these, despite being different underlying Structs
save_object(article)
save_object(person)
What this means is that the save_object function does not need to know anything about your custom Article struct in order to call save on it. It can simply refer to your implementation of that method in order to do so. In this way you can write custom objects that third party or generic library functions are able to act upon, because the Trait has defined a set of behaviors with a contract that the code can rely on safely.
Then the question of, 'when do you want to use a Trait' can be answered by saying: whenever you want to use behavior defined on a struct without needing to know everything about the struct - just that it has that behavior. So, in the above, you might also have an 'edit' functionality attached to Article, but not to Person. You don't want to have to change save_object to account for this, or to even care. All save_object needs to know is that the functions defined in the Saveable trait are implemented - it doesn't need to know anything else about the object to function equally well.
Another way to phrase this is to say, 'Use a trait when you want to pass an object based on what it can do, not what it is.'
This question already has answers here:
Why are explicit lifetimes needed in Rust?
(10 answers)
Closed 2 years ago.
How come Rust does not fully infer ownership of its variables? Why are annotations needed?
If that were even possible I believe it would be a terrible user experience because:
if the compiler cannot deduce ownership of an object, the error can barely be understood (like with trial-and-error approach in C++ templates link);
the ownership policy doesn't seem to be easy to grasp (that's one opinion though) and trying to understand which semantic has been chosen by a compiler may lead to unexpected behaviors (reference a Javascript weird type conversions);
more bugs during refactoring can be introduced (implied by the point above);
full program inference would definitely take a huge amount of time, if it is even a solvable problem.
However, if you struggle with a lack of polymorphism, it is usually possible to parametrize a method with an ownership kind, which might be considered a somewhat explicit alternative to inference, e.g.:
fn print_str(s: impl AsRef<str>) {
println!("{}", s.as_ref());
}
fn main() {
print_str("borrowed");
print_str("owned".to_owned());
}
This question already has answers here:
How do I synchronously return a value calculated in an asynchronous Future?
(3 answers)
Closed 2 years ago.
Rust newbie here (<7 days into learning), the second hurdle I am trying to overcome after ownership rule is async/await.
I am writing a test that calls an async function and I need to get the result from the Future without using the keyword await.
I have looked at async_test, however I can't use that because (as I understand) this requires tokio runtime and #[tokio_main] attribute in my main method - but I have my main already decorated with #[actix_rt::main]
This is my test
#[test]
pub fn test_get_item() -> Result<(), anyhow::Error> {
let c = SomeClient::new();
let result = c.get_item(123456).await?; // <- this is not allowed
assert_eq!("Hello", result.title);
assert_eq!("https://example.com", result.url.as_str());
Ok(())
}
Things I have tried and failed (mostly due to my lack of knowledge in Rust)
Use async_test on an actix web project using futures-await-test crate.
Read this thread in reddit.
Follow few examples from this rust community thread
Tried to poll() the future but it didn't lead me anywhere.
I don't understand why this has to be so complicated, maybe there is a simple function (like wait() or get_result()) somewhere for Future?
Thanks for your help.
Had to clear my head for a bit and start again, just to find actix-web has a macro I can use that allows async tests.
#[actix_rt::test]
Macros are all magic to me at this point, I hope I;ll understand them soon.
This question already has answers here:
Why can't I store a value and a reference to that value in the same struct?
(4 answers)
Shared circular references in Rust
(1 answer)
Closed 3 years ago.
I am learning Rust from a C++/Java background, and I have the following pattern
struct Node<'a> {
network_manager: NetworkManager<'a>,
}
struct NetworkManager<'a> {
base_node: &'a Node<'a>,
}
The node contains the threadpool that the NetworkManager uses to "handoff" messages once they've been processed. Because of the recursive call, it is not possible to set the base_node field in the NetworkManager immediately. In Java, I would leave it as null and have a second method that is called after the constructor called initialise(BaseNode node) that would set the base_node field (ensuring that there are no calls to the network manager before initialise is called).
What is the idiomatic way of doing this in Rust? The only way I can think of is to make base_node an Option type, but this seems suboptimal.
In general, what is the "right" way in Rust to deal with situations where A points to B and B points to A, and where (as in my case), refactoring is not possible?
From my experience, these situations are very different from other languages. In "safe, simple, everyday Rust" having backpointers/pointers within the struct is complex since it leads to non-trivial problems. (Consider what would happen if you would move Node around in memory: How would you properly update the backpointer in NetworkManager?)
What I usually resort to is simply passing base_node as a parameter to the functions that need the backpointer. This is sometimes easier said than done, but leads to code that clearly states ownership.
This question already has answers here:
Are polymorphic variables allowed?
(3 answers)
Closed 5 years ago.
I am trying to understand Rust polymorphism. From my background in OOP, I would expect the following Rust code to work:
use std::io::{stdin, Read};
fn main() {
let r: Read = stdin();
println!("ok");
}
But it doesn't:
4 | let r: Read = stdin();
| ^^^^^^^ expected trait std::io::Read, found struct `std::io::Stdin`
I know that there's a Read impl for StdIn, so how can I make this (or whatever is the correct way to do this) work, ie. use Stdin, or a File, or even a String if possible (couldn't find a implementation for that) be used where a Read is expected?
I don't think I can use generics here as I need to pass an instance of r, which can be whatever that implements Read, to another method later, but please tell me if I am wrong.
You probably want to use trait objects here. You can use traits in basically two ways:
The static dispatch way: fn foo<T: Trait>(x: T). This reads "for an arbitrary, but fixed T which implements Trait".
The dynamic dispatch way: fn foo(x: &Trait). This lifts the "but fixed" limitation from the first version by using trait objects.
If you want to have a variable which could either hold a reference to Stdin or a File or anything else that implements Read, you can't go for the static dispatch solution, as your implementing type is not fixed.
So what is the type of your variable then? Read? Sadly, it's not that easy. Trait objects are unsized and can't be used on the stack directly. Instead you can only interact with trait objects via references/pointers, like &Read, &mut Read, Box<Read> and so on. Now that we use borrowing-stuff, we might encounter more problems related to that. Luckily, you haven't been the first one encountering this issue: see this question for a detailed look at this specific use case.
To simplify a bit, in most cases it's ok to use Box<Trait>. In your case, it would look like this:
use std::io::{stdin, Read};
fn main() {
let r: Box<Read> = Box::new(stdin());
println!("ok");
}