I am trying to hide the type information of the impl Foo and store this information for later use. Is this even possible?
#![feature(universal_impl_trait)]
use std::any::Any;
use std::marker::PhantomData;
trait Foo {
type Item;
fn get(&self) -> Self::Item;
}
#[derive(Clone, Debug)]
struct Bar<T: Clone>(T);
impl<T: Clone> Bar<T> {
fn new(t: T) -> Self {
Bar(t)
}
}
impl<T: 'static + Clone> Foo for Bar<T> {
type Item = T;
fn get(&self) -> Self::Item {
self.0.clone()
}
}
#[derive(Clone, Debug)]
struct Baz<T: Clone, F: Clone>(T, F);
impl<T: Clone, F: Clone> Baz<T, F> {
fn new(t: T, f: F) -> Self {
Baz(t, f)
}
}
impl<T: 'static + Clone, F: 'static + Clone> Foo for Baz<T, F> {
type Item = (T, F);
fn get(&self) -> Self::Item {
(self.0.clone(), self.1.clone())
}
}
trait Get {
type Item;
fn idx(&self) -> usize;
}
struct GetBar<T> {
id: usize,
_t: PhantomData<T>,
}
impl<T> Get for GetBar<T> {
type Item = T;
fn idx(&self) -> usize {
self.id
}
}
impl<T> GetBar<T> {
fn new(id: usize) -> Self {
Self {
id,
_t: PhantomData,
}
}
}
struct GetBaz<T, F> {
id: usize,
_t: PhantomData<T>,
_f: PhantomData<F>,
}
impl<T, F> Get for GetBaz<T, F> {
type Item = T;
fn idx(&self) -> usize {
self.id
}
}
impl<T, F> GetBaz<T, F> {
fn new(id: usize) -> Self {
GetBaz {
id,
_t: PhantomData,
_f: PhantomData,
}
}
}
struct Qux {
v: Vec<Box<Any>>,
}
impl Qux {
fn new() -> Self {
Qux { v: vec![] }
}
fn add_bar<T: 'static + Clone>(&mut self, a: T) -> GetBar<T> {
self.v.push(Box::new(Bar::new(a)) as Box<Any>);
GetBar::new(self.v.len())
}
fn add_baz<T: 'static + Clone, F: 'static + Clone>(&mut self, a: T, b: F) -> GetBaz<T, F> {
self.v.push(Box::new(Baz::new(a, b)) as Box<Any>);
GetBaz::new(self.v.len())
}
fn get<T: 'static + Clone, F: 'static + Clone>(&self, val: &'static impl Get) -> Option<T> {
let node = &self.v[val.idx()];
if let Some(foo) = node.downcast_ref::<Bar<T>>() {
Some(foo.get())
} else if let Some(foo) = node.downcast_ref::<Baz<T, F>>() {
Some(foo.get().0)
} else {
None
}
}
}
fn main() {
let mut qux = Qux::new();
let a = qux.add_bar(1_i32);
let b = qux.add_bar("1");
let c = qux.add_baz(Bar::new('A'), Bar::new('B'));
assert_eq!(qux.get(&a).unwrap(), 1);
assert_eq!(qux.get(&b).unwrap(), "i");
assert_eq!(qux.get(&c).unwrap(), Bar::new('A'));
}
error[E0283]: type annotations required: cannot resolve `_: std::clone::Clone`
--> src/main.rs:121:20
|
121 | assert_eq!(qux.get(&a).unwrap(), 1);
| ^^^
Sorry for the long example but this is the best I can do.
I'm trying to reconcile the Rust static type system with dynamically dispatched trait objects. However, in many occasions I am unable to provide type annotations. What is the best way to achieve this? How can I dynamically supply type information to the trait object system?
What about qux.add_baz(GetBar::<&str>::new(1), GetBaz::<i32, i32>::new(3)); and use that type information to recursively get from qux?
Sorry for the contrived example; the real code is available on GitHub.
Related
I just want to find three largest numbers of an Vec<i32> sorted in ascending order, but I have problem with the last function. I don't know how I should do this properly.
pub struct Solution;
impl Solution {
pub fn find_three_largest_numbers(array: Vec<i32>) -> Vec<i32> {
let mut max_arr = vec![i32::MIN, i32::MIN, i32::MIN];
for number in array {
max_arr = Solution::update_array(max_arr, number);
}
max_arr
}
fn update_array(array: Vec<i32>, number: i32) -> Vec<i32> {
if array[2] < number {
Solution::assign_values(&array, 2, number);
} else if array[1] < number {
Solution::assign_values(&array, 1, number);
} else if array[0] < number {
Solution::assign_values(&array, 0, number);
}
array
}
fn assign_values(array: &Vec<i32>, index: i32, number: i32) {
for i in 0..index+1 {
if i == index {
array[i as usize] = number; // ERROR: `array` is a `&` reference, so the data it refers to cannot be borrowed as mutable
} else {
array[i as usize] = array[(i + 1) as usize]; // ERROR: `array` is a `&` reference, so the data it refers to cannot be borrowed as mutable
}
}
}
}
reference are by default immutable and since you are passing immutable vec reference which can be use to update the vec which is what rust is complaining.
To solve this you have to pass mutable reference which can be use to update the vec.
pub struct Solution;
impl Solution {
pub fn find_three_largest_numbers(array: Vec<i32>) -> Vec<i32> {
let mut max_arr = vec![i32::MIN, i32::MIN, i32::MIN];
for number in array {
max_arr = Solution::update_array(&mut max_arr, number);
}
max_arr
}
fn update_array(array: &mut Vec<i32>, number: i32) -> Vec<i32> {
if array[2] < number {
Solution::assign_values(array, 2, number);
} else if array[1] < number {
Solution::assign_values(array, 1, number);
} else if array[0] < number {
Solution::assign_values(array, 0, number);
}
array.to_vec()
}
fn assign_values(array: &mut Vec<i32>, index: i32, number: i32) {
for i in 0..index + 1 {
if i == index {
array[i as usize] = number;
} else {
array[i as usize] = array[(i + 1) as usize];
}
}
}
}
fn main() {
println!(
"{:?}",
Solution::find_three_largest_numbers(vec![-1, 3, 15, 6, -40])
);
}
Playground
Note: One improvement I would like to suggest since you are passing mutable reference you don't need reassignment to max_arr or return from update_array method.
Here's a little solution I whipped up :) Hope it helps!
(P.S. I made sure not to use fancy iterators, just in case you're new to Rust :))
pub struct Solution;
impl Solution {
pub fn find_three_largest_numbers(array: Vec<i32>) -> Vec<i32> {
let mut largest = vec![];
for a in array.iter() {
if largest.len() < 3 {
largest.push(*a);
} else {
for i in 0..largest.len() {
if a > &largest[i]
&& !largest.contains(a) {
largest[i] = *a;
}
}
}
}
largest
}
}
fn main() {
println!("{:?}", Solution::find_three_largest_numbers(vec![-1, 3, 15, 6, -40]));
}
When I try the code below for the Vec<Ev> I get a [E0308]: mismatched type error.
use std::fmt::Error;
#[derive(Debug)]
struct Ev {
semt: String,
fiyat : i32,
}
impl Ev {
fn yeni (alan: &str,fiyat: i32) -> Ev {
Self {
semt: alan.to_string(),
fiyat
}
}
}
fn dizi_yap(boyut:usize) -> Result<Vec<Ev>,Error> {
let mut evler = Vec::<Ev>::with_capacity(boyut);
evler.push(Ev::yeni("melikgazi", 210));
evler.push(Ev::yeni("kocasinan", 120));
evler.push(Ev::yeni("hacılar", 410));
evler.push(Ev::yeni("bünyan", 90));
Ok(evler)
}
fn elemani_getir(&mut dizi:Vec<Ev>, sira:usize) -> Ev {
dizi[sira]
// dizi.get(sira).expect("hata")
}
fn main() {
let mut dizi = dizi_yap(1).expect("ulasmadi");
println!("eleman: {:?}",dizi[3]);
println!("eleman: {:?}",elemani_getir(dizi, 3))
}
How can I get Vec indexed item in this example?
The syntax in you function arguments is a little off. Mutable arguments can be a little confusing, as there are two different representations. Refer to this question for a more detailed explanation.
Here is the elemali_getit function corrected:
fn elemani_getir(mut dizi: &Vec<Ev>, sira: usize) -> &Ev {
&dizi[sira]
}
And you can call it like this:
println!("eleman: {:?}", elemani_getir(&dizi, 3))
Note that elemani_getir now returns a reference to Ev (&Ev). Returning Ev instead results in an error:
cannot move out of index of `std::vec::Vec<Ev>`
To get around this error, you can either return a reference to Ev as shown above, or return an exact duplicated of Ev my deriving the Clone trait:
#[derive(Debug, Clone)]
struct Ev {
semt: String,
fiyat: i32,
}
fn elemani_getir(mut dizi: &Vec<Ev>, sira: usize) -> Ev {
dizi[sira].clone()
}
I’m trying to transpile a dynamic language into Rust and closures are the most difficult part to implement.
I've tried using a Arc<Mutex<dyn FnMut>>, but it doesn't support recursion.
use std::sync::{Arc, Mutex};
type Data = Arc<DataUnpack>;
enum DataUnpack {
Number(f64),
Function(Box<Mutex<FnMut(Vec<Data>) -> Data>>),
}
fn call(f: Data, args: Vec<Data>) -> Data {
if let DataUnpack::Function(v) = &*f {
let f = &mut *v.lock().unwrap();
f(args)
} else {
panic!("TYPE ERR")
}
}
fn lambda(f: Box<FnMut(Vec<Data>) -> Data>) -> Data {
Arc::new(DataUnpack::Function(Box::new(Mutex::new(Box::leak(f)))))
}
fn main() {
let f: Arc<Mutex<Data>> = Arc::new(Mutex::new(Arc::new(DataUnpack::Number(0.0))));
*f.lock().unwrap() = {
let f = f.clone();
lambda(Box::new(move |xs| {
println!("Ha");
call(f.lock().unwrap().clone(), xs.clone())
}))
};
call(f.lock().unwrap().clone(), vec![]);
}
playground
It shows one Ha and then stops. Where am I wrong?
#![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.
I would like to return an element of a vector:
struct EntryOne {
pub name: String,
pub value: Option<String>,
}
struct TestVec {}
impl TestVec {
pub fn new() -> TestVec {
TestVec {}
}
pub fn findAll(&self) -> Vec<EntryOne> {
let mut ret = Vec::new();
ret.push(EntryOne {
name: "foo".to_string(),
value: Some("FooVal".to_string()),
});
ret.push(EntryOne {
name: "foo2".to_string(),
value: Some("FooVal2".to_string()),
});
ret.push(EntryOne {
name: "foo3".to_string(),
value: None,
});
ret.push(EntryOne {
name: "foo4".to_string(),
value: Some("FooVal4".to_string()),
});
ret
}
pub fn findOne(&self) -> Option<EntryOne> {
let mut list = &self.findAll();
if list.len() > 0 {
println!("{} elements found", list.len());
list.first()
} else {
None
}
}
}
fn main() {
let test = TestVec::new();
test.findAll();
test.findOne();
}
(playground)
I always get this error:
error[E0308]: mismatched types
--> src/main.rs:40:13
|
35 | pub fn findOne(&self) -> Option<EntryOne> {
| ---------------- expected `std::option::Option<EntryOne>` because of return type
...
40 | list.first()
| ^^^^^^^^^^^^ expected struct `EntryOne`, found &EntryOne
|
= note: expected type `std::option::Option<EntryOne>`
found type `std::option::Option<&EntryOne>`
How do I return an element?
Look at the signature for Vec::first:
fn first(&self) -> Option<&T>
Given a reference to a vector, it will return a reference to the first item if there is one, and None otherwise. That means that the vector containing the values must outlive the return value, otherwise the reference would point to undefined memory.
There are two main avenues:
If you cannot change the vector, then you will need to make a copy of your data structure. The easiest way to do this is to annotate the structure with #[derive(Clone)]. Then you can call Option::cloned on the result of first.
If you can change the vector, then you can remove the first value from it and return it. There are many ways of doing this, but the shortest code-wise is to use the drain iterator.
#[derive(Debug, Clone)]
struct EntryOne {
name: String,
value: Option<String>,
}
fn find_all() -> Vec<EntryOne> {
vec![
EntryOne {
name: "foo".to_string(),
value: Some("FooVal".to_string()),
},
EntryOne {
name: "foo2".to_string(),
value: Some("FooVal2".to_string()),
},
EntryOne {
name: "foo3".to_string(),
value: None,
},
EntryOne {
name: "foo4".to_string(),
value: Some("FooVal4".to_string()),
},
]
}
fn find_one_by_clone() -> Option<EntryOne> {
find_all().first().cloned()
}
fn find_one_by_drain() -> Option<EntryOne> {
let mut all = find_all();
let mut i = all.drain(0..1);
i.next()
}
fn main() {
println!("{:?}", find_one_by_clone());
println!("{:?}", find_one_by_drain());
}
Additional changes:
There's no need for TestVec if there's no state; just make functions.
Rust style is snake_case for method and variable names.
Use vec! to construct a vector when providing all the elements.
Derive Debug so you can print the value.
If you wanted to always get the last element, you can use pop:
fn find_one_by_pop() -> Option<EntryOne> {
find_all().pop()
}