How to call to_socket_addrs on a collection of addresses? - collections

How do I call to_socket_addrs() on an array or vector in Rust? The following code does not compile:
extern crate ws;
use std::net::ToSocketAddrs;
fn main() {
let addrs = ["127.0.0.1:8889", "127.0.0.1:0"]
.iter()
.flat_map(|a| a.to_socket_addrs());
ws::listen(addrs, |out| move |msg| out.send(msg));
}
error[E0277]: the trait bound `std::iter::FlatMap<std::slice::Iter<'_, &str>, std::result::Result<std::vec::IntoIter<std::net::SocketAddr>, std::io::Error>, [closure#src/main.rs:7:19: 7:42]>: std::net::ToSocketAddrs` is not satisfied
--> src/main.rs:8:5
|
8 | ws::listen(addrs, |out| move |msg| out.send(msg));
| ^^^^^^^^^^ the trait `std::net::ToSocketAddrs` is not implemented for `std::iter::FlatMap<std::slice::Iter<'_, &str>, std::result::Result<std::vec::IntoIter<std::net::SocketAddr>, std::io::Error>, [closure#src/main.rs:7:19: 7:42]>`
|
= note: required by `ws::listen`
It took me two hours to understand the error because "trait X is not implemented for std::iter::FlatMap" reads like the problem is caused by flat_map, instead of the demands of ws::listen.

to_socket_addrs returns a Result containing an iterator. Result itself implements IntoIterator, so flat_map flattens the result, but not the inner iterator, you need to do that in an extra step:
use std::net::ToSocketAddrs;
fn main() {
let addrs = ["127.0.0.1:8889", "127.0.0.1:0"]
.iter()
.flat_map(|a| a.to_socket_addrs())
.flatten()
.collect::<Vec<_>>();
println!("addrs = {:?}!", addrs);
}

Related

Add value to a HashSet in Rust and add a reference to it to another datastructure

I'm trying to return a Vector from a function. This happens in a loop and I need the values to exist outside of the loop. Since I perform the return multiple times and I only need the unique values, I thought I use a HashSet for this, in which I insert and then try to get a reference to the value in the next line.
I need a reference to the value in multiple other datastructures and don't want to duplicate the actual values. The values don't need to be mutable.
What I tried
use std::collections::HashSet;
fn main() {
let mut vec: Vec<&str> = Vec::new();
let mut books = HashSet::new();
for i in 0..5 {
// This could be a function call, which returns a vector of objects, which should all be
// stored centrally and uniquely in a HashSet
books.insert("A Dance With Dragons".to_string());
let mut reference: &str = books.get("A Dance With Dragons").unwrap();
// This would be done for multiple "refering" datastructures
vec.push(reference);
}
}
What I was expecting
Getting a pointer to the String in the HashSet for future use.
What actually happens
error[E0502]: cannot borrow `books` as mutable because it is also borrowed as immutable
--> src/main.rs:10:9
|
10 | books.insert("A Dance With Dragons".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
11 |
12 | let mut reference: &str = books.get("A Dance With Dragons").unwrap();
| --------------------------------- immutable borrow occurs here
13 | // This would be done for multiple "refering" datastructures
14 | vec.push(reference);
| ------------------- immutable borrow later used here
For more information about this error, try `rustc --explain E0502`.
warning: `set_test` (bin "set_test") generated 2 warnings
error: could not compile `set_test` due to previous error; 2 warnings emitted
I think I'm missing a very obvious solution to this...
Thanks in advance for helping.
You can't do this
use std::collections::HashSet;
fn main() {
let mut v: Vec<&str> = Vec::new();
let mut books = HashSet::new();
for i in 0..5 {
// this needs to borrow mutably
books.insert("A Dance With Dragons".to_string());
// this reference has to live as long as v
// so on the second iteration books is still borrowed
// which means you can't borrow it mutably any more.
let reference: &str = books.get("A Dance With Dragons").unwrap();
v.push(reference);
}
// v only goes out of scope here
}
You might find success in separating mutation and referencing like this:
fn main() {
let mut books = HashSet::new();
for i in 0..5 {
books.insert("A Dance With Dragons".to_string());
}
let v: Vec<&str> = books.iter().collect();
}
Or by using a Rc like pigeonhgands suggests.
fn main() {
let mut v: Vec<Rc<str>> = Vec::new();
let mut books = HashSet::new();
for i in 0..5 {
books.insert(Rc::new("A Dance With Dragons".to_string()));
// note: this clone is cheap cause it only clones the `Rc` not the whole String.
let reference = books.get("A Dance With Dragons").unwrap().clone();
v.push(reference);
}
}
The issue is that's the value in "book" could be removed and you try to save reference in a vector. It is a risk of null pointer.
You need to build book in imutable way, like this
use std::collections::HashSet;
fn main() {
let mut vec: Vec<&str> = Vec::new();
let books: HashSet<String> = vec!(
"A Dance With Dragons".to_string(),
"A Dance With Dragons".to_string()).into_iter().collect();
let reference: &str = books.get("A Dance With Dragons").unwrap();
vec.push(reference);
}

How to pass a vector as a parameter in rust

I am trying to write a function that prints a vector. I am having some trouble in understanding how to pass a vector as a parameter. This is what I have so far:
fn vecprinter(v1: &mut Vec<u32>) -> Vec<u32> {
v1
}
fn main(){
let mut v1=vec![1,10,11,12,13];
println!("{:?}", vecprinter(v1));
}
However I am getting this error:
error[E0308]: mismatched types
--> main.rs:3:1
|
1 | fn vecprinter(v1: &mut Vec<u32>) -> Vec<u32> {
| -------- expected `std::vec::Vec<u32>` because of return type
2 |
3 | v1
| ^^
| |
| expected struct `std::vec::Vec`, found mutable reference
| help: try using a conversion method: `v1.to_vec()`
|
= note: expected struct `std::vec::Vec<u32>`
found mutable reference `&mut std::vec::Vec<u32>`
error[E0308]: mismatched types
--> main.rs:10:31
|
10 | println!("{:?}", vecprinter(v1));
| ^^
| |
| expected mutable reference, found struct `std::vec::Vec`
| help: consider mutably borrowing here: `&mut v1`
|
= note: expected mutable reference `&mut std::vec::Vec<u32>`
found struct `std::vec::Vec<{integer}>`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.
compiler exit status 1
What am I doing wrong?
You have two issues here.
Firs your vecprinter method takes a &mut Vec<u32 as a parameter, but you are passing it a Vec<u32> in your call to println!. To resolve this pass a mutable reference t to the vec instead:
println!("{:?}", vecprinter(&mut v1));
The second issue is with the return types of the vecprinter method. You are taking in a &mut Vec<u32> and expecting to return a Vec<u32>; however, when you return the value of v1 you are returning a &mut Vec<u32> rather than the expected Vec<u32>. Depending on your requirements you have two options.
Change the return type of the vecprinter method and pass a mutable reference:
fn vecprinter(v1: &mut Vec<u32>) -> &mut Vec<u32> {
v1
}
fn main(){
let mut v1=vec![1,10,11,12,13];
println!("{:?}", vecprinter(&mut v1));
}
or change the parameter value to take the vector rather than a reference:
fn vecprinter(v1: Vec<u32>) -> Vec<u32> {
v1
}
fn main(){
let mut v1=vec![1,10,11,12,13];
println!("{:?}", vecprinter(v1));
}
You wrote in your question:
I am trying to write a function that prints a vector.
But the function you wrote (no matter if it works or not) is not writing anything: it returns the given vector.
A function which would print something would look like this:
fn print_something(to_print: /*Some type*/) /*No return type*/ {
println!(/*...*/);
}
As you want to print a vector of u32, the prototype could be:
fn print_something(to_print: Vec<u32>) { /*...*/ }
But if you do that, the argument will be moved into the function and will become unusable outside of it. In order to improve this, you can pass the argument as a reference:
fn print_something(to_print: &Vec<u32>) { /*...*/ }
To handle more general cases (&Vec<u32> + &[u32]), you can still improve it like this:
fn print_something(to_print: &[u32]) { /*...*/ }
Now when you call this function, you have to add an ampersamp & to the given argument (unless it's already a reference):
print_something(&my_vector);
Finally, by gluing everything together, you have this:
fn print_vec(v: &[u32]) {
println!("{:?}", v);
}
fn main() {
let v = vec![1, 10, 11, 12, 13];
print_vec(&v);
// Because we changed "&Vec<u32>" to "&[u32]", the following is also
// possible:
let arr = &[1, 10, 11, 12, 13];
print_vec(arr);
}

Recursive generator in Rust

I am trying to port this python prime number generator to rust using rust generators and this generator-to-iterator wrapper.
My problem is that the original implementation is recursive, and I didn't manage to get passed the following error:
error[E0720]: opaque type expands to a recursive type
--> src/main.rs:27:29
|
27 | fn recursive_generator() -> impl Iterator<Item = u64> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expands to a recursive type
|
= note: expanded type is `GeneratorToIterator<[generator#src/main.rs:28:25:
48:6 {u64, (), impl std::iter::Iterator}]>`
Below is the implementation of the recursive generator producing this error:
fn recursive_generator() -> impl Iterator<Item = u64> {
GeneratorToIterator(move || {
// Yield a few values
yield 1;
yield 2;
yield 3;
// Initialize the inner generator
let mut inner_value: u64 = 0;
let mut inner_generator = recursive_generator();
// Get the first value of the inner generator
match inner_generator.next(){
Some(x) => inner_value += x,
None => {},
}
// Yield some other values
yield 4;
yield 5;
yield 6;
})
}
The full implementation (with the GeneratorToIterator definition) can be found here.
I found this related question but I did not manage to compile their gen_to_iter function.
EDIT: Thanks to #bluss answer, I've finally been able to implement a working version of the prime number generator in rust.
The error explanation E0720 mentions that an impl Trait type must expand to one that doesn't contain other impl Trait types, but here the type is of course recursive, since that's the point.
This can be worked around by using boxed trait objects instead - Box<Iterator<Item=u64>> works well here and avoids the problem.
Either adjust recursive_generator to return Box<Iterator<Item=u64>>, or change the line of the recursive call to use the boxed iterator just for that recursive case.

Running asynchronous mutable operations with Rust futures

I'm building a service in Rust using tokio-rs and was happy with this tech stack so far. I'm now trying to chain up async operations that includes writes and having a hard time with the borrow checker.
My simplified minimal code sample is this:
extern crate futures; // 0.1.21
use futures::Future;
use std::{cell::RefCell, rc::Rc};
trait RequestProcessor {
fn prepare(&self) -> Box<Future<Item = (), Error = ()>>;
fn process(&mut self, request: String) -> Box<Future<Item = (), Error = ()>>;
}
struct Service {
processor: Rc<RefCell<RequestProcessor>>,
}
impl Service {
fn serve(&mut self, request: String) -> Box<Future<Item = (), Error = ()>> {
let processor_clone = self.processor.clone();
let result_fut = self
.processor
.borrow()
.prepare()
.and_then(move |_| processor_clone.borrow_mut().process(request));
Box::new(result_fut)
}
}
fn main() {}
As a short summary, after an async preparation step I'm trying to run another async operation that writes a field of self. Without mutability this works easily with a plain Rc member, but mutability breaks it, producing the following error:
error[E0597]: `processor_clone` does not live long enough
--> src/main.rs:22:32
|
22 | .and_then(move |_| processor_clone.borrow_mut().process(request));
| ^^^^^^^^^^^^^^^ - `processor_clone` dropped here while still borrowed
| |
| borrowed value does not live long enough
|
= note: values in a scope are dropped in the opposite order they are created
I'd expect this should work, I don't see where the mutable reference is still borrowed. I think process() should release the processor's &mut self after the future is returned, so the compile error shouldn't occur.
Could you please explain the underlying reasons? How should this example be changed to be accepted by the compiler?
Sometimes, it's easier to see lifetime errors if you split values up onto multiple lines. Let's try that with the closure in question:
.and_then(move |_| {
let c = processor_clone;
let mut d = c.borrow_mut();
let e = d.process(request);
e
});
If you compile this... it works. If we try recombining the lines, we can get this to fail:
.and_then(move |_| {
let c = processor_clone;
c.borrow_mut().process(request)
});
And this to work:
.and_then(move |_| {
let c = processor_clone;
return c.borrow_mut().process(request);
});
The only difference is the explicit return and the semicolon. This is very similar to When returning the outcome of consuming a StdinLock, why was the borrow to stdin retained?, so let's try the suggestion of one of the answers to enable non-lexical lifetimes. This allows your original code to compile as well.
TL;DR: It's a weakness in Rust's current borrow checker implementation and will be magically fixed at some point. In the meantime, I suggest writing it as two lines:
.and_then(move |_| {
let mut c = processor_clone.borrow_mut();
c.process(request)
});

Print Vec using a placeholder [duplicate]

I tried the following code:
fn main() {
let v2 = vec![1; 10];
println!("{}", v2);
}
But the compiler complains:
error[E0277]: `std::vec::Vec<{integer}>` doesn't implement `std::fmt::Display`
--> src/main.rs:3:20
|
3 | println!("{}", v2);
| ^^ `std::vec::Vec<{integer}>` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `std::vec::Vec<{integer}>`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: required by `std::fmt::Display::fmt`
Does anyone implement this trait for Vec<T>?
let v2 = vec![1; 10];
println!("{:?}", v2);
{} is for strings and other values which can be displayed directly to the user. There's no single way to show a vector to a user.
The {:?} formatter can be used to debug it, and it will look like:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Display is the trait that provides the method behind {}, and Debug is for {:?}
Does anyone implement this trait for Vec<T> ?
No.
And surprisingly, this is a demonstrably correct answer; which is rare since proving the absence of things is usually hard or impossible. So how can we be so certain?
Rust has very strict coherence rules, the impl Trait for Struct can only be done:
either in the same crate as Trait
or in the same crate as Struct
and nowhere else; let's try it:
impl<T> std::fmt::Display for Vec<T> {
fn fmt(&self, _: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
Ok(())
}
}
yields:
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src/main.rs:1:1
|
1 | impl<T> std::fmt::Display for Vec<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
Furthermore, to use a trait, it needs to be in scope (and therefore, you need to be linked to its crate), which means that:
you are linked both with the crate of Display and the crate of Vec
neither implement Display for Vec
and therefore leads us to conclude that no one implements Display for Vec.
As a work around, as indicated by Manishearth, you can use the Debug trait, which is invokable via "{:?}" as a format specifier.
If you know the type of the elements that the vector contains, you could make a struct that takes vector as an argument and implement Display for that struct.
use std::fmt::{Display, Formatter, Error};
struct NumVec(Vec<u32>);
impl Display for NumVec {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let mut comma_separated = String::new();
for num in &self.0[0..self.0.len() - 1] {
comma_separated.push_str(&num.to_string());
comma_separated.push_str(", ");
}
comma_separated.push_str(&self.0[self.0.len() - 1].to_string());
write!(f, "{}", comma_separated)
}
}
fn main() {
let numbers = NumVec(vec![1; 10]);
println!("{}", numbers);
}
Here is a one-liner which should also work for you:
println!("[{}]", v2.iter().fold(String::new(), |acc, &num| acc + &num.to_string() + ", "));
Here is
a runnable example.
In my own case, I was receiving a Vec<&str> from a function call. I did not want to change the function signature to a custom type (for which I could implement the Display trait).
For my one-of case, I was able to turn the display of my Vec into a one-liner which I used with println!() directly as follows:
println!("{}", myStrVec.iter().fold(String::new(), |acc, &arg| acc + arg));
(The lambda can be adapted for use with different data types, or for more concise Display trait implementations.)
Starting with Rust 1.58, there is a slightly more concise way to print a vector (or any other variable). This lets you put the variable you want to print inside the curly braces, instead of needing to put it at the end. For the debug formatting needed to print a vector, you add :? in the braces, like this:
fn main() {
let v2 = vec![1; 10];
println!("{v2:?}");
}
Sometimes you don't want to use something like the accepted answer
let v2 = vec![1; 10];
println!("{:?}", v2);
because you want each element to be displayed using its Display trait, not its Debug trait; however, as noted, you can't implement Display on Vec because of Rust's coherence rules. Instead of implementing a wrapper struct with the Display trait, you can implement a more general solution with a function like this:
use std::fmt;
pub fn iterable_to_str<I, D>(iterable: I) -> String
where
I: IntoIterator<Item = D>,
D: fmt::Display,
{
let mut iterator = iterable.into_iter();
let head = match iterator.next() {
None => return String::from("[]"),
Some(x) => format!("[{}", x),
};
let body = iterator.fold(head, |a, v| format!("{}, {}", a, v));
format!("{}]", body)
}
which doesn't require wrapping your vector in a struct. As long as it implements IntoIterator and the element type implements Display, you can then call:
println!("{}", iterable_to_str(it));
Is there any reason not to write the vector's content item by item w/o former collecting? *)
use std::fmt::{Display, Formatter, Error};
struct NumVec(Vec<u32>);
impl Display for NumVec {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let v = &self.0;
if v.len() == 0 {
return Ok(());
}
for num in &v[0..v.len() - 1] {
if let Err(e) = write!(f, "{}, ", &num.to_string()) {
return Err(e);
}
}
write!(f, "{}", &v[v.len() - 1])
}
}
fn main() {
let numbers = NumVec(vec![1; 10]);
println!("{}", numbers);
}
*) No there isn't.
Because we want to display something, the Display trait is implemented for sure. So this is correct Rust because: the Doc says about the ToString trait:
"This trait is automatically implemented for any type which implements the Display trait. As such, ToString shouldn’t be implemented directly: Display should be implemented instead, and you get the ToString implementation for free."
In particular on microcontrollers where space is limited I definitely would go with this solution and write immediately.

Resources