How to create a minimum BinaryHeap? [duplicate] - rust

This question already has answers here:
How do I create a BinaryHeap that pops the smallest value, not the largest?
(2 answers)
Closed 3 years ago.
I'm trying to solve leetcode problem 703, largest_element_in_a_stream in Rust.
I want to use the BinaryHeap to solve this problem, but the BinaryHeap in Rust is the maximum heap by default. I don't know how to transform it to a maximum heap.
I found answers in similar questions:
How do I create a BinaryHeap that pops the smallest value, not the largest?
How can I implement a min-heap of f64 with Rust's BinaryHeap?
But the answer in the two questions uses some special struct and overloads the Ord trait, I want to solve it for primitives such as i32.
How can I solve it?

Assuming you actually want a min-heap, you could just negate each value you put it in the heap & negate each you take out.
Note: As #Shepmaster alludes to, there is a single i32 negative value which does not have a corresponding positive one (to balance 0, which is its own negative). If you need to handle this value, this technique will not work, at least not without a bit of finessing.

Related

Is there macro to create HashSet in Rust [duplicate]

This question already has answers here:
How do I create a HashMap literal?
(9 answers)
Closed 3 months ago.
In Rust, we can create a Vector with macro vec![].
let numbers = vec![1, 2, 3];
Is there any similar macro that allow us to create a HashSet?
From the doc https://doc.rust-lang.org/std/collections/struct.HashSet.html, I notice that we have HashSet::from:
let viking_names = HashSet::from(["Einar", "Olaf", "Harald"]);
However, that requires us to create an array first, which seems a bit wasteful.
The standard library doesn't have a macro for this. This crate does provide one though.
As for the wastefulness, creating an array of string literals is pretty cheap, and is almost certainly optimized away.
If you fear the overhead of constructing the HashSet at runtime, or want this to be a static, the phf crates might help you.

In Rust, what is !Unpin [duplicate]

This question already has answers here:
What does the exclamation point mean in a trait implementation?
(3 answers)
Closed 9 months ago.
I am unable to locate the documentation for !Unpin referred to here in the docs.
More generally, the ! operator seem to lack corresponding documentation regarding traits. Specifically, it seems to represent Not as in Not Unpin or perhaps Not Unpinable in this case. I suppose it is different from Pin in some way otherwise it would be redundant. Currently, searching for the documentation is challenging since ! occurs so frequently otherwise.
It would be good if the operator behavior of ! on traits could be included in Appendix B: Operators and Symbols of the docs.
Unpin is one of several auto-traits, which are implemented automatically for any type that's compatible with it. And in the case of Unpin, that's, well, basically all of the types.
Auto-traits (and only auto-traits) can have negative implementations written by preceding the trait name with a !.
// By default, A implements Unpin
struct A {}
// But wait! Don't do that! I know something you don't, compiler.
impl !Unpin for A {}
Unpin, specifically, indicates to Rust that it is safe to move values of the implementing type T out of a Pin. Normally, Pin indicates that the thing inside shall not be moved. Unpin is the sort of opposite of that, which says "I know we just pinned this value, but I, as the writer of this type, know it's safe to move it anyway".
Generally, anything in Safe Rust is Unpin. The only time you'd want to mark something as !Unpin is if it's interfacing with something in another language like C. If you have a datatype that you're storing pointers to in C, for instance, then the C code may be written on the assumption that the data never changes addresses. In that case, you'd want to negate the Unpin implementation.

How does String::from("") & "".to_string() differ in Rust? [duplicate]

This question already has answers here:
How to create a String directly?
(3 answers)
What is the difference between these 3 ways of declaring a string in Rust?
(1 answer)
Closed 2 years ago.
How does String::from("") & "".to_string() differ in Rust?
Is there any difference in stack and heap allocation in both cases?
How does String::from("") & "".to_string() differ in Rust?
They're part of different protocols (traits): std::convert::From and alloc::string::ToString[0].
However, when it comes to &str/String they do the same thing (as does "".to_owned()).
Is there any difference in stack and heap allocation in both cases?
As joelb's link indicates, before Rust 1.9 "".to_string() was markedly slower than the alternatives as it went through the entire string formatting machinery. That's no longer the case.
[0] `ToString` is also automatically implemented if the structure implements `Display`[1]
[1] functionally s.to_string() is equivalent to format!("{}", s), it's usually recommended to not implement ToString directly, unless bypassing the formatting machinery can provide significant performance improvements (which is why str/String do it)

Rust backpointers [duplicate]

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.

What's the practical use of Option in rust? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Consider this example
fn main() {
let mut i: Option<i32> = None;
//after some processing it got some value of 55
i = Some(55);
println!("value is {:?}", i.unwrap());
}
In go, nil represents the zero-value of that type.
However in rust, it represents absence of a value. How is absence of a value useful in practice?
When a variable with a type is declared, it must have some value either initialized or un-initialized. Why will one declare it to have it absent?
Also please explain, at what point the memory is allocated for i during the initial declaration or when i gets some value?
I might be asking a stupid question, but want to get my head around the need of this concept.
How is absence of a value useful in practice?
A simple example is a function that looks for the first matching element in a collection. It may find it, and return it, or not find any.
The docs give a few more cases:
Initial values
Return values for functions that are not defined over their entire input range (partial functions)
Return value for otherwise reporting simple errors, where None is returned on error
Optional struct fields
Struct fields that can be loaned or "taken"
Optional function arguments
Nullable pointers
Swapping things out of difficult situations
Now, you may ask: why don't we use one of the values to mark an empty one? For two reasons:
There are cases where you do not have a valid "zero-value" or a valid "invalid" value. In this case, you have to use some flag somewhere else to store the fact that something is invalid.
In general, it is simpler to use the same solution everywhere than having to mark and document which is the "none" value.
Why will one declare it to have it absent?
This is different than initialized/uninitialized values. Option is simply a type that contains either "nothing" (None) or a "value" of some type (Some(value))
You can conceptually see it as a struct with a flag and some space for the value itself.
Also please explain, at what point the memory is allocated for i during the initial declaration or when i gets some value?
That depends on the implementation. One could decide to implement Option using a pointer to the value, which means it could delay allocating.
However, the most likely implementation is avoiding pointers and keeping the value plus an extra flag. Note that, for some types, you can also optimize further and avoid the flag altogether. For instance, if you have an Option of a pointer, you can simply use the zero value for None. In fact, Rust does such a thing for types like Option<Box<T>>.

Resources