I have a simple linked list type and an implementation of Clone for
it:
#[deriving(Show)]
enum List {
Cons(int, Box<List>),
Nil,
}
impl Clone for List {
fn clone(&self) -> List {
match *self {
Cons(val, ref rest) => Cons(val, rest.clone()),
Nil => Nil,
}
}
}
It works as expected. But if I make my own MyClone trait with
the same signature
as that of Clone, I get an error:
trait MyClone {
fn my_clone(&self) -> Self;
}
impl MyClone for List {
fn my_clone(&self) -> List {
match *self {
Cons(val, ref rest) => Cons(val, rest.my_clone()),
Nil => Nil,
}
}
}
.../src/main.rs:23:46: 23:61 error: mismatched types: expected `Box<List>`, found `List` (expected box, found enum List)
.../src/main.rs:23 Cons(val, ref rest) => Cons(val, rest.my_clone()),
It works fine if I change it to box rest.my_clone(), but I don't
understand why. The MyClone and Clone traits are the same, so it
seems to me they would accept the same implementation.
(I'm compiling with rustc 0.12.0-nightly (72841b128 2014-09-21 20:00:29 +0000).)
This is because rust also has an implementation of Clone for Box<T>. If you implement MyClone for it, it will owrk at expected.
#[deriving(Show)]
enum List {
Cons(int, Box<List>),
Nil,
}
trait MyClone {
fn my_clone(&self) -> Self;
}
impl<T: MyClone> MyClone for Box<T> {
fn my_clone(&self) -> Box<T> {
self.my_clone()
}
}
impl MyClone for List {
fn my_clone(&self) -> List {
match *self {
Cons(val, ref rest) => Cons(val, rest.my_clone()),
Nil => Nil,
}
}
}
Related
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()
}
My first Rust program compiles and runs:
use structopt::StructOpt;
use pcap::{Device,Capture};
use std::process::exit;
#[derive(StructOpt)]
struct Cli {
/// the capture device
device: String,
}
fn main() {
let devices = Device::list();
let args = Cli::from_args();
let mut optdev :Option<Device> = None;
for d in devices.unwrap() {
//println!("device: {:?}", d);
if d.name == args.device {
optdev = Some(d);
}
}
let dev = match optdev {
None => {
println!("Device {} not found.", args.device);
exit(1);
},
Some(dev) => dev,
};
let mut cap = Capture::from_device(dev).unwrap()
.promisc(true)
.snaplen(100)
.open().unwrap();
while let Ok(packet) = cap.next() {
println!("received packet! {:?}", packet);
}
}
I have some complex code which iterates through the Vec of devices, testing each one's .name property against args.device.
I'm guessing that there is a method of 'looking-up' an entry in a Vec, such that I can replace all the optdev lines with something like:
let dev = match devices.unwrap().look_up(.name == args.device) {
None => {
println!("Device {} not found.", args.device);
exit(1);
},
Some(dev) => dev,
};
What is the syntax for such a look_up()?
Or is there a more idiomatic way of doing this?
What is the syntax for such a look_up()?
Iterator::find. Since the operation is not specific to vectors (or slices), it doesn't live there, and is applicable to any iterator instead.
It'd look something like this:
let dev = match devices.unwrap().into_iter().find(|d| d.name == args.device) {
None => {
println!("Device {} not found.", args.device);
exit(1);
},
Some(dev) => dev,
};
or
let dev = if let Some(dev) = devices.unwrap().into_iter().find(|d| d.name == args.device) {
dev
} else {
println!("Device {} not found.", args.device);
exit(1);
};
(side-note: you may also want to use eprintln for, well, error reporting).
Though a somewhat cleaner error handling could be along the lines of (note: not tested so there might be semantic or syntactic mistakes):
use std::fmt;
use std:errors::Error;
#[derive(Debug)]
struct NoDevice(String);
impl fmt::Display for NoDevice {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Device {} not found", self.0)
}
}
impl Error for NoDevice {}
fn main() -> Result<(), Box<dyn Error>> {
let devices = Device::list()?;
let args = Cli::from_args();
let dev = devices.into_iter()
.find(|d| d.name == args.device)
.ok_or_else(|| NoDevice(args.device))?
let mut cap = Capture::from_device(dev)?
.promisc(true)
.snaplen(100)
.open()?;
while let Ok(packet) = cap.next() {
println!("received packet! {:?}", packet);
}
}
I have a function which returns Future. It accepts another function which accepts one argument and returns Future. Second function can be implemented as combinators chain passed into first function. It looks like this:
use bb8::{Pool, RunError};
use bb8_postgres::PostgresConnectionManager;
use tokio_postgres::{error::Error, Client, NoTls};
#[derive(Clone)]
pub struct DataManager(Pool<PostgresConnectionManager<NoTls>>);
impl DataManager {
pub fn new(pool: Pool<PostgresConnectionManager<NoTls>>) -> Self {
Self(pool)
}
pub fn create_user(
&self,
reg_req: UserRequest,
) -> impl Future<Item = User, Error = RunError<Error>> {
let sql = "long and awesome sql";
let query = move |mut conn: Client| { // function which accepts one argument and returns Future
conn.prepare(sql).then(move |r| match r {
Ok(select) => {
let f = conn
.query(&select, &[®_req.email, ®_req.password])
.collect()
.map(|mut rows| {
let row = rows.remove(0);
row.into()
})
.then(move |r| match r {
Ok(v) => Ok((v, conn)),
Err(e) => Err((e, conn)),
});
Either::A(f)
}
Err(e) => Either::B(future::err((e, conn))),
})
};
self.0.run(query) // function which returns Future and accepts another function
}
}
But I want to write code of create_user as a struct implementing Future.
struct UserCreator(Pool<PostgresConnectionManager<NoTls>>, UserRequest);
impl UserCreator {
fn new(pool: Pool<PostgresConnectionManager<NoTls>>, reg_req: UserRequest) -> Self {
Self(pool, reg_req)
}
}
How to implement Future for this struct that works as first function? Please help me with an example.
Now I tried to make it like this, but nothing is computed and execution always blocks.
impl Future for UserCreator {
type Item = User;
type Error = RunError<Error>;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
// Code which which works like `DataManager.create_user`
let sql = "long and awesome sql";
let reg_req = &self.1;
let query = move |mut conn: Client| {
conn.prepare(sql).then(move |r| match r {
Ok(select) => {
let f = conn
.query(&select, &[®_req.email, ®_req.password])
.collect()
.map(|mut rows| {
let row = rows.remove(0);
row.into()
})
.then(move |r| match r {
Ok(v) => Ok((v, conn)),
Err(e) => Err((e, conn)),
});
Either::A(f)
}
Err(e) => Either::B(future::err((e, conn))),
})
};
self.0.run(query).poll()
}
}
I want to build a tree using exactly two structs: Node and Tree and then recursively search for a target node from the tree. If a target is found, return true, else return false.
The challenge for me here is how to recursively call the find function, since it is only defined on Tree not Node.
pub struct Node<T> {
value: T,
left: Option<Box<Node<T>>>,
right: Option<Box<Node<T>>>,
}
pub struct Tree<T> {
root: Option<Box<Node<T>>>,
}
impl<T: Ord> Tree<T> {
/// Creates an empty tree
pub fn new() -> Self {
Tree { root: None }
}
// search the tree
pub fn find(&self, key: &T) -> bool {
let root_node = &self.root; // root is Option
match *root_node {
Some(ref node) => {
if node.value == *key {
return true;
}
let target_node = if *key < node.value {
&node.left
} else {
&node.right
};
match *target_node {
Some(sub_node) => sub_node.find(key),
None => {
return false;
}
}
}
None => return false,
}
}
}
fn main() {
let mut mytree: Tree<i32> = Tree::new();
let node1 = Node {
value: 100,
left: None,
right: None,
};
let boxed_node1 = Some(Box::new(node1));
let root = Node {
value: 200,
left: boxed_node1,
right: None,
};
let boxed_root = Some(Box::new(root));
let mytree = Tree { root: boxed_root };
let res = mytree.find(&100);
}
The current code reports the error:
error: no method named `find` found for type `Box<Node<T>>` in the current scope
--> src/main.rs:36:48
|
36 | Some(sub_node) => sub_node.find(key),
| ^^^^
|
= note: the method `find` exists but the following trait bounds were not satisfied: `Node<T> : std::iter::Iterator`
= help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `find`, perhaps you need to implement one of them:
= help: candidate #1: `std::iter::Iterator`
= help: candidate #2: `core::str::StrExt`
I understand that find is only implemented on Tree, so there is an error, but I don't think it is efficient to implement find on both Tree and Node. Any hint to solve this?
You need to move the majority of the implementation to the Node type, then leave only a small shim in Tree:
impl<T: Ord> Tree<T> {
pub fn find(&self, key: &T) -> bool {
self.root.as_ref().map(|n| n.find(key)).unwrap_or(false)
}
}
impl<T: Ord> Node<T> {
// search the tree
pub fn find(&self, key: &T) -> bool {
if self.value == *key {
return true;
}
let target_node = if *key < self.value {
&self.left
} else {
&self.right
};
target_node.as_ref().map(|n| n.find(key)).unwrap_or(false)
}
}
However, I might avoid multiple comparisons by just matching on the result:
pub fn find(&self, key: &T) -> bool {
use ::std::cmp::Ordering::*;
match self.value.cmp(key) {
Equal => true,
Less => self.left.as_ref().map(|n| n.find(key)).unwrap_or(false),
Greater => self.right.as_ref().map(|n| n.find(key)).unwrap_or(false),
}
}
Or
pub fn find(&self, key: &T) -> bool {
use ::std::cmp::Ordering::*;
let child = match self.value.cmp(key) {
Equal => return true,
Less => self.left.as_ref(),
Greater => self.right.as_ref(),
};
child.map(|n| n.find(key)).unwrap_or(false)
}
I found it is hard to understand target_node.as_ref().map(|n| n.find(key)).unwrap_or(false). I just started to learn the iterator. Is that possible to explain the long expression step by step?
Just follow the type signatures of each function:
self is a &Node<T>
&self.left / &self.right / target_node are a &Option<Box<Node<T>>>
Option::as_ref converts an &Option<T> to Option<&T>. Now we have Option<&Box<Node<T>>>.
Option::map applies a function (which may change the contained type) to the option if it is Some, otherwise it leaves it None.
The function we apply is Node::find, which takes a &Node<T> and returns a bool.
Box<T> implements Deref so any methods on T appear on Box<T>.
Automatic dereferencing allows us to treat &Box<T> as Box<T>.
Now we have Option<bool>
Option::unwrap_or returns the contained value if there is one, otherwise the fallback value provided. The final type is bool.
There is no usage of the Iterator trait. Both Iterator and Option have a map method. If you are interested in the fact that they have the same name and do similar things, that [is what people refer to as a monad. Understanding monads is interesting but not required to actually use them.
Implement the find method on Node and create a stub find method for Tree which could look like this:
impl<T: Ord> Tree<T> {
pub fn find(&self, key: &T) -> bool {
match self.root.as_ref() {
None => false,
Some(x) => x.find(key)
}
}
}
I have some code that looks like this:
trait Stack {
fn top(&mut self) -> Option<f64>;
}
impl Stack for Vec<f64> {
fn top(&mut self) -> Option<f64> {
match self.pop() {
None => None,
Some(v) => {
self.push(v);
Some(v)
}
}
}
}
fn main() {
let mut stack: Vec<f64> = Vec::new();
stack.push(5.3);
stack.push(2.3);
stack.push(1.3);
match stack.top() {
Some(v) => println!("Top of the stack: {}", v),
None => println!("The stack is empty"),
}
}
Right now, the top() method is modifying self, but I think that this should not be necessary. The obvious way to do it didn't really work:
fn top(&mut self) -> Option<f64> {
match self.len() {
0 => None,
n => self[n - 1],
}
}
I've toyed around a bit with converting usize to i32 and back, but none of what I'm writing looks as short and readable as I think it should.
You can use slice::last:
fn top(&mut self) -> Option<f64> {
self.last().copied()
}
Option::copied (and Option::cloned) can be used to convert from an Option<&f64> to an Option<f64>, matching the desired function signature.
You can also remove the mut from both the implementation and the trait definition.
And just after posting the question, the answer appears to be obvious:
fn top (&mut self) -> Option<&f64> {
match self.len() {
0 => None,
n => Some(&self[n-1])
}
}
I.e. the usize was never the problem - the return type of top() was.