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.
Related
This question already has an answer here:
What is the rationale behind allowing variable shadowing in Rust? [closed]
(1 answer)
Closed 2 years ago.
First time I am encountering a typed language allowing to declare a variable name twice in the same scope. Wouldn't there be a chance to override an existing variable by mistake? What advantage does it bring?
There is a chapter in the book about this.
Shadowing is different from marking a variable as mut, because we’ll get a compile-time error if we accidentally try to reassign to this variable without using the let keyword. By using let, we can perform a few transformations on a value but have the variable be immutable after those transformations have been completed.
The other difference between mut and shadowing is that because we’re effectively creating a new variable when we use the let keyword again, we can change the type of the value but reuse the same name. For example, say our program asks a user to show how many spaces they want between some text by inputting space characters, but we really want to store that input as a number
let spaces = " "; // String
let spaces = spaces.len(); // number
In short, it allows you to "modify" a value, in a way that is technically immutable. Rust ensures that you cannot use the shadowed variable, so it's perfectly typesafe.
I'm no Rust expert, but from a language design perspective it's an interesting thing to encourage. But I think the point is to discourage the use of mutable values whenever possible by allowing you to immutably override a name with a new type and value.
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:
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.
Vec provides a sort method (through Deref implementation), but LinkedList does not. Is there a generic algorithm somewhere in the Rust standard library that allows sorting of LinkedLists?
I don't think there is a built-in way to do it. However, you can move the list contents into a Vec, sort it and turn it back into a linked list:
let mut vec: Vec<_> = list.into_iter().collect();
vec.sort();
let list: LinkedList<_> = vec.into_iter().collect();
This idea is not even remotely as bad as it may seem - see here. While relatively fast algorithms for sorting a linked list do exist, they won't give you as much of cache performance as flat array sorting may do.
See this question, its quite similar but not language spesific.
A while ago I investigated this topic (using C, but applies to Rust too).
Besides converting to a vector & sorting, then converting back to a linked list. Merge-sort is typically the best method to sort a linked list.
The same method can be used both for double and single linked lists (there is no advantage to having links in both directions).
Here is an example, originally from this answer, which I ported to C.
This is a nice example of merge-sort, however after some further investigation I found Mono's eglib mergesort to be more efficient, especially when the list is already partially sorted.
Here is a portable version of it.
It shouldn't be too difficult to port this from C to Rust.
This question already has answers here:
Is it possible to control the size of an array using the type parameter of a generic?
(2 answers)
Closed 2 years ago.
Does Rust language support constant values in generic code similar to c++ way? Seems that the language overview doesn't advertise it. Parameterizing types with constants in C++ allows to create objects with preallocated buffers of different size depending on client's needs (types like stlsoft::auto_buffer).
If not, then what is the best practices to implement similar designs in Rust?
No, this is not supported in a type-safe way. We would need type-level numeric literals, like GHC recently added, for that.
However, you can use Rust macros. With a macro you can create "templates" that are parameterized over arbitrary expressions, including constants, which would allow you to do what you want here. Note that you may find bugs and limitations in the macro system if you try this at the moment.