How to transfer ownership during iteration? - vector

I have this working code:
let foo_ips = vec![Ipv4Addr::new(127,0,0,1),
Ipv4Addr::new(127,0,0,2),
Ipv4Addr::new(127,0,0,3)];
let foos: Vec<Foo> = foo_ips.iter().map(|x| {Foo::new(*x)}).collect();
I believe that this is using a copy constructor to create new Ipv4Addrs to pass to Foo::new().
Am I correct?
If so, how do I take the ips out of foo_ips to pass ownership of each to Foo::new()?

into_iter(), instead of iter(), will consume the vector.
Note that Ipv4Addr is so small (32 bits) that it is Copy (nothing to be gained if we move instead of copying).
use std::net::Ipv4Addr;
#[derive(Debug)]
struct Foo(Ipv4Addr);
impl Foo {
fn new(addr: Ipv4Addr) -> Self {
Foo(addr)
}
}
fn main() {
println!("size of Ipv4Addr: {}", std::mem::size_of::<Ipv4Addr>());
let foo_ips = vec![
Ipv4Addr::new(127, 0, 0, 1),
Ipv4Addr::new(127, 0, 0, 2),
Ipv4Addr::new(127, 0, 0, 3),
];
let engines: Vec<Foo> = foo_ips.iter().map(|x| Foo::new(*x)).collect();
println!("engines: {:?}", engines);
println!("foo_ips: {:?}", foo_ips); // still available
let engines: Vec<Foo> =
foo_ips.into_iter().map(|x| Foo::new(x)).collect();
println!("engines: {:?}", engines);
// println!("foo_ips: {:?}", foo_ips); // consumed!
}

Related

Fill a vector of struct elements by iteration rather than using .push() one by one

I am trying to find an elegant way to fill a vector of struct elements with a loop or logic instead of writing one .push() for every element I create.
The struct element is a question with many more fields than in the following example and the instances need to be mutable because they are modified by user input :
struct Question {
id: usize,
question: String,
}
fn main() {
//A large and growing list of questions
let mut q0 = Question {
id: 0,
question: String::from("A field I fill in manually"),
};
// .
// .
// .
let mut q100 = Question {
id: 100,
question: String::from("Another field, each one is different"),
};
let total_questions: usize = 100;
let mut w: Vec<String> = Vec::new();
for a in 0..total_questions {
let s = format!("q{}", a);
w.push(s);
}
//w contains ["q0", "q1", ..., "q100"] but is of type std::string::String
let mut v: Vec<&mut Question> = Vec::new();
//Expects type struct `main::Question`
//I would like to avoid :
v.push(&mut q0);
v.push(&mut q1);
// .
// .
// .
v.push(&mut q100);
}
I am not sure that in my example the w: Vec<String> is of any use.
I have looked into .collect() but could not understand how to utilize it in my case.
I'd be happy to be pointed towards a similar question if this is a duplicate I have not found one.
Edit : I have changed the structs string content as it was misleading. They each contain Strings that are unique and cannot be generated. I also realized that Stack Overflow automatically included this in a some_fn() function when we are actually inside main()
The problem is because you don't have any data structure that contains the Questions -- you just have 100+ independent local variables -- it's not possible to iterate over them to fill the Vec. You can fix this by putting all the Questions in a Vec<Question> as you create them. Here's an example:
let mut v: Vec<Question> = vec![
Question {
id: 0,
question: String::from("Q0"),
},
// ...
Question {
id: 100,
question: String::from("Q100"),
},
];
In fact, once you do this you probably don't need the Vec<&mut Question> at all, since you can mutate the questions directly by indexing v. However, if you do need the vector of references for some reason, you can create it by collecting an iterator:
let v_refs: Vec<&mut Question> = v.iter_mut().collect();
If you can generate your Question object with a function you can use an iterator. Here is an example which just generates numbered Question objects out of a numeric range:
struct Question {
id: usize,
question: String,
}
fn main() {
let v: Vec<Question> = (0..10)
.map(|x| Question {
id: x,
question: "Q".to_string() + &x.to_string(),
})
.collect();
for x in &v {
println!("{}: {}", x.id, x.question);
}
}
Here is an example where you get the strings from an array of strings:
struct Question<'a> {
id: usize,
question: &'a str,
}
const QUESTIONS: [&str; 3] = ["A", "B", "C"];
fn main() {
let v: Vec<Question> = (0..questions.len())
.map(|x| Question {
id: x,
question: questions[x],
})
.collect();
for x in &v {
println!("{}: {}", x.id, x.question);
}
}

Raw Pointers not producing desired effects

#![feature(ptr_internals)]
use core::ptr::Unique;
struct PtrWrapper {
id: usize,
self_reference: Unique<Self>
}
impl PtrWrapper {
fn new() -> Self {
let dummy = unsafe {Unique::new_unchecked(std::ptr::null_mut::<PtrWrapper>())};
let mut ret = Self {id:0, self_reference: dummy };
let new_ptr = &mut ret as *mut Self;
debug_print(new_ptr);
ret.self_reference = Unique::new(new_ptr).unwrap();
debug_print(ret.self_reference.as_ptr());
ret
}
fn get_id(&self) -> usize {
self.id.clone()
}
}
fn main() {
println!("START");
let mut wrapper = PtrWrapper::new();
wrapper.id = 10;
let ptr = wrapper.self_reference.as_ptr();
unsafe {
(*ptr).id += 30;
println!("The next print isn't 40? Garbage bytes");
debug_print(ptr);
let tmp = &mut wrapper as *mut PtrWrapper;
(*tmp).id += 500;
println!("The next print isn't 540?");
debug_print(tmp);
}
println!("Below debug_print is proof of undefined behavior! Garbage bytes\n");
debug_print(wrapper.self_reference.as_ptr());
debug_print(&mut wrapper as *mut PtrWrapper);
debug_print_move(wrapper);
println!("Why is the assertion below false?");
assert_eq!(unsafe{(*ptr).id}, 540);
}
fn debug_print_move(mut wrapper: PtrWrapper) {
debug_print(&mut wrapper as *mut PtrWrapper);
}
fn debug_print(ptr: *mut PtrWrapper) {
println!("Address: {:p}", ptr);
println!("ID: {}\n", unsafe {(*ptr).get_id()});
}
The above code should compile fine in rust playground with a nightly selected version. Pay attention to the console outputs.
My question is: Why are the intermittent results not equal to the value I expect them to equal? In the case below, there is no multiple access simultaneously (single threaded), so there aren't any data races. There are, however, implicitly multiple mutable version of the object existing on the stack.
As expected, the memory location of the pointer changes with the tmp variable as well as when the entire object is moved into debug_print_move. It appears that using the tmp pointer works as expected (i.e., adds 500), however, the pointers which are obtained from the Unique<PtrWrapper> object seems to point to irrelevant locations in memory.
As Stargateur recommended, in order to solve this problem we need to Pin the object which needs to be self-referential. I ended up using:
pin-api = "0.2.1"
In cargo.toml instead of std::pin::pin. Next, I set this up the struct and its implementation:
#![feature(ptr_internals, pin_into_inner, optin_builtin_traits)]
// not available on rust-playground
extern crate pin_api;
use pin_api::{boxed::PinBox, marker::Unpin, mem::Pin};
///test
pub struct PtrWrapper<T>
where
T: std::fmt::Debug,
{
///tmp
pub obj: T,
/// pinned object
pub self_reference: *mut Self,
}
impl<T> !Unpin for PtrWrapper<T> where T: std::fmt::Debug {}
impl<T> PtrWrapper<T>
where
T: std::fmt::Debug,
{
///test
pub fn new(obj: T) -> Self {
Self {
obj,
self_reference: std::ptr::null_mut(),
}
}
///test
pub fn init(mut self: Pin<PtrWrapper<T>>) {
let mut this: &mut PtrWrapper<T> = unsafe { Pin::get_mut(&mut self) };
this.self_reference = this as *mut Self;
}
/// Debug print
pub fn print_obj(&self) {
println!("Obj value: {:#?}", self.obj);
}
}
Finally, the test function:
fn main2() {
unsafe {
println!("START");
let mut wrapper = PinBox::new(PtrWrapper::new(10));
wrapper.as_pin().init();
let m = wrapper.as_pin().self_reference;
(*m).obj += 30;
println!("The next print is 40");
debug_print(m);
let tmp = wrapper.as_pin().self_reference;
(*tmp).obj += 500;
println!("The next print is 540?");
debug_print(tmp);
debug_print(wrapper.self_reference);
let cpy = PinBox::get_mut(&mut wrapper);
debug_print_move(cpy);
std::mem::drop(wrapper);
println!("Works!");
assert_eq!(unsafe { (*m).obj }, 540);
}
}
fn debug_print_move<T>(mut wrapper: &mut PtrWrapper<T>)
where
T: std::fmt::Debug,
{
debug_print(&mut *wrapper as *mut PtrWrapper<T>);
}
fn debug_print<T>(ptr: *mut PtrWrapper<T>)
where
T: std::fmt::Debug,
{
println!("Address: {:p}", ptr);
unsafe { (*ptr).print_obj() };
}
On a side note, pin-api does not exist on rust playground. You could still use std::pin::Pin, however it would require further customization.

What is an efficient way to reset all values of a Vec<T> without resizing it?

I can use resize, but it seems like overkill because I do not need to resize the vector, just modify its values. Using a new variable is not an option, since this vector is actually a field in a struct.
I guess that resize is efficient, and probably the answer to my question, but its name does not carry the meaning of resetting the values without modifying the size.
In C, I would use memset (in opposition to realloc).
Illustration of my question:
let my_vec_size = 42;
let mut my_vec = Vec::new(); // 'my_vec' will always have a size of 42
my_vec.resize(my_vec_size, false); // Set the size to 42, and all values to false
// [ ... ] piece of code where the values in 'my_vec' will be modified, checked, etc ...
// now I need to reuse my_vec.
// Possibility A -> use resize again
my_vec.resize(my_vec_size, false);
// Possibility B -> iterate on the vector to modify its values (long and laborious)
for item in my_vec.iter_mut() {
*item = false;
}
// Possibility C ?
The most efficient way in general is to reset the values themselves (aka B):
for item in &mut my_vec { *item = false; }
For booleans it is not immediately obvious, however for a String it is important to preserve the allocated buffer of each element:
for item in &mut my_vec { item.clear(); }
If discarding and recreating the elements of the Vec is cheap, such as the case of the boolean or if the elements will be overwritten anyway, then a combination of clear and resize is easier:
my_vec.clear();
my_vec.resize(my_vec_size, false);
resize by itself will not work to "reset" values:
const LEN: usize = 3;
fn main() {
let mut values = vec![false; LEN];
values[0] = true;
values.resize(LEN, false);
println!("{:?}", values); // [true, false, false]
}
Just use a for loop:
for v in &mut values {
*v = false;
}
println!("{:?}", values); // [false, false, false]
If that sight offends you, write an extension trait:
trait ResetExt<T: Copy> {
fn reset(&mut self, val: T);
}
impl<T: Copy> ResetExt<T> for [T] {
fn reset(&mut self, value: T) {
for v in self {
*v = value;
}
}
}
values.reset(false);
println!("{:?}", values); // [false, false, false]
The trait idea can be extended so that each value knows how to reset itself, if that makes sense for your situation:
trait ResetExt {
fn reset(&mut self);
}
impl<T: ResetExt> ResetExt for [T] {
fn reset(&mut self) {
for v in self {
v.reset();
}
}
}
impl ResetExt for bool {
fn reset(&mut self) {
*self = false;
}
}
impl ResetExt for String {
fn reset(&mut self) {
self.clear();
}
}
values.reset();
println!("{:?}", values); // [false, false, false]
In C, I would use memset
std::ptr::write_bytes uses memset internally, so you can (almost) precisely translate this code. An example from the Rust documentation:
let mut vec = vec![0u32; 4];
unsafe {
let vec_ptr = vec.as_mut_ptr();
ptr::write_bytes(vec_ptr, 0xfe, 2);
}
assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);

How can I create a stack-allocated vector-like container?

How would you go about creating a stack-allocated vector-like container with some fixed upper limit on the number of elements it can contain? You can see my attempt at this below, but it doesn't compile:
// The following is at crate level
#![feature(unsafe_destructor)]
use std::mem;
use std::ptr;
use std::slice::Iter;
pub struct StackVec<T> {
buf: [T; 10],
len: usize,
}
impl<T> StackVec<T> {
pub fn new() -> StackVec<T> {
StackVec {
buf: unsafe { mem::uninitialized() },
len: 0,
}
}
pub fn iter(&self) -> Iter<T> {
(&self.buf[..self.len]).iter()
}
pub fn push(&mut self, value: T) {
unsafe { ptr::write(self.buf.get_mut(self.len).unwrap(), value); }
self.len += 1;
}
pub fn pop(&mut self) -> Option<T> {
if self.len == 0 {
None
} else {
unsafe {
self.len -= 1;
Some(ptr::read(self.buf.get(self.len).unwrap()))
}
}
}
}
#[unsafe_destructor]
impl<T> Drop for StackVec<T>
where T: Drop
{
fn drop(&mut self) {
for elem in self.iter() {
unsafe { ptr::read(elem); }
}
unsafe { mem::forget(self.buf); } // ERROR: [1]
}
}
This is the compile-time error I get:
[1] error: cannot move out of type stackvec::StackVec<T>, which defines the Drop trait
I've written an implementation, and I'll go over the highlights.
Full code is available at crates.io/arrayvec (API doc)
Use a trait (called Array) to abstract over different array sizes. It needs to provide raw pointers so that we can use the array as backing storage.
/// Trait for fixed size arrays.
pub unsafe trait Array {
/// The array's element type
type Item;
unsafe fn new() -> Self;
fn as_ptr(&self) -> *const Self::Item;
fn as_mut_ptr(&mut self) -> *mut Self::Item;
fn capacity() -> usize;
}
In contemporary rust style, we can only implement this trait for specific array sizes. I cover some small sizes with a macro:
macro_rules! fix_array_impl {
($len:expr ) => (
unsafe impl<T> Array for [T; $len] {
type Item = T;
/// Note: Returning an uninitialized value here only works
/// if we can be sure the data is never used. The nullable pointer
/// inside enum optimization conflicts with this this for example,
/// so we need to be extra careful. See `Flag` enum.
unsafe fn new() -> [T; $len] { mem::uninitialized() }
fn as_ptr(&self) -> *const T { self as *const _ as *const _ }
fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _}
fn capacity() -> usize { $len }
}
)
}
macro_rules! fix_array_impl_recursive {
() => ();
($len:expr, $($more:expr,)*) => (
fix_array_impl!($len);
fix_array_impl_recursive!($($more,)*);
);
}
fix_array_impl_recursive!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 40, 48, 56, 64, 72, 96, 128, 160, 192, 224,);
We need to suppress the default drop of the embedded array. You can do this by in theory using Option<Array> and using ptr::write to overwrite it with None at the last moment in Drop.
We must however use our own enum, similar to Option for one reason: We need to avoid non-nullable pointer optimization that applies to enums that have the same representation as Option. Then in Drop we do the crucial inhibition of the inner array's default destructor: we forcibly overwrite our enum. Only after destructing all the elements, of course.
/// Make sure the non-nullable pointer optimization does not occur!
#[repr(u8)]
enum Flag<T> {
Dropped,
Alive(T),
}
/// A vector with a fixed capacity.
pub struct ArrayVec<A: Array> {
len: u8,
xs: Flag<A>,
}
impl<A: Array> Drop for ArrayVec<A> {
fn drop(&mut self) {
// clear all elements, then inhibit drop of inner array
while let Some(_) = self.pop() { }
unsafe {
ptr::write(&mut self.xs, Flag::Dropped);
}
}
}
We implement Deref<Target=[T]> and DerefMut and get tons of slice methods for free. This is a great feature of Rust!
impl<A: Array> Deref for ArrayVec<A> {
type Target = [A::Item];
fn deref(&self) -> &[A::Item] {
unsafe {
slice::from_raw_parts(self.inner_ref().as_ptr(), self.len())
}
}
}
The ArrayVec type has an invariant, that the Flag<A> is always Flag::Alive(A) when the value is alive. We should be able to optimize with this in mind. (A FIXME is marked there.)
fn inner_mut(&mut self) -> &mut A {
// FIXME: Optimize this, we know it's always present.
match self.xs {
Flag::Alive(ref mut xs) => xs,
_ => unreachable!(),
}
}
Thank you kmky for asking question! Exploring this answer led to the creation of arrayvec linked above, and uncovered some of the points that were very important to have it be a safe rust data structure.
My guess is that the compiler doesn't know which elements of the array are "free" and which need a destructor to run when the array is dropped.
Try storing Option<T>, which has a .take() method that will allow you to move an element out of the array.

Show u8 slice in hex representation

I need to convert &[u8] to a hex representation. For example [ A9, 45, FF, 00 ... ].
The trait std::fmt::UpperHex is not implemented for slices (so I can't use std::fmt::format). Rust has the serialize::hex::ToHex trait, which converts &[u8] to a hex String, but I need a representation with separate bytes.
I can implement trait UpperHex for &[u8] myself, but I'm not sure how canonical this would be. What is the most canonical way to do this?
Rust 1.26.0 and up
The :x? "debug with hexadecimal integers" formatter can be used:
let data = b"hello";
// lower case
println!("{:x?}", data);
// upper case
println!("{:X?}", data);
let data = [0x0, 0x1, 0xe, 0xf, 0xff];
// print the leading zero
println!("{:02X?}", data);
// It can be combined with the pretty modifier as well
println!("{:#04X?}", data);
Output:
[68, 65, 6c, 6c, 6f]
[68, 65, 6C, 6C, 6F]
[00, 01, 0E, 0F, FF]
[
0x00,
0x01,
0x0E,
0x0F,
0xFF,
]
If you need more control or need to support older versions of Rust, keep reading.
Rust 1.0 and up
use std::fmt::Write;
fn main() {
let mut s = String::new();
for &byte in "Hello".as_bytes() {
write!(&mut s, "{:X} ", byte).expect("Unable to write");
}
println!("{}", s);
}
This can be fancied up by implementing one of the formatting traits (fmt::Debug, fmt::Display, fmt::LowerHex, fmt::UpperHex, etc.) on a wrapper struct and having a little constructor:
use std::fmt;
struct HexSlice<'a>(&'a [u8]);
impl<'a> HexSlice<'a> {
fn new<T>(data: &'a T) -> HexSlice<'a>
where
T: ?Sized + AsRef<[u8]> + 'a,
{
HexSlice(data.as_ref())
}
}
// You can choose to implement multiple traits, like Lower and UpperHex
impl fmt::Display for HexSlice<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.0 {
// Decide if you want to pad the value or have spaces inbetween, etc.
write!(f, "{:X} ", byte)?;
}
Ok(())
}
}
fn main() {
// To get a `String`
let s = format!("{}", HexSlice::new("Hello"));
// Or print it directly
println!("{}", HexSlice::new("world"));
// Works with
HexSlice::new("Hello"); // string slices (&str)
HexSlice::new(b"Hello"); // byte slices (&[u8])
HexSlice::new(&"World".to_string()); // References to String
HexSlice::new(&vec![0x00, 0x01]); // References to Vec<u8>
}
You can be even fancier and create an extension trait:
trait HexDisplayExt {
fn hex_display(&self) -> HexSlice<'_>;
}
impl<T> HexDisplayExt for T
where
T: ?Sized + AsRef<[u8]>,
{
fn hex_display(&self) -> HexSlice<'_> {
HexSlice::new(self)
}
}
fn main() {
println!("{}", "world".hex_display());
}
use hex::encode:
let a: [u8;4] = [1, 3, 3, 7];
assert_eq!(hex::encode(&a), "01030307");
[dependencies]
hex = "0.4"
Since the accepted answer doesn't work on Rust 1.0 stable, here's my attempt. Should be allocationless and thus reasonably fast. This is basically a formatter for [u8], but because of the coherence rules, we must wrap [u8] to a self-defined type ByteBuf(&[u8]) to use it:
struct ByteBuf<'a>(&'a [u8]);
impl<'a> std::fmt::LowerHex for ByteBuf<'a> {
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
for byte in self.0 {
try!( fmtr.write_fmt(format_args!("{:02x}", byte)));
}
Ok(())
}
}
Usage:
let buff = [0_u8; 24];
println!("{:x}", ByteBuf(&buff));
There's a crate for this: hex-slice.
For example:
extern crate hex_slice;
use hex_slice::AsHex;
fn main() {
let foo = vec![0u32, 1, 2 ,3];
println!("{:02x}", foo.as_hex());
}
I'm doing it this way:
let bytes : Vec<u8> = "привет".to_string().as_bytes().to_vec();
let hex : String = bytes.iter()
.map(|b| format!("{:02x}", b).to_string())
.collect::<Vec<String>>()
.join(" ");

Resources