Size: a a a

Rust — русскоговорящее сообществo

2020 September 16

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
Кстати, в этой программе не нужно ни одного return:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=58e3227c772437f4a8499cd0de9453c6
источник

Z

Zymlex (Юрий) in Rust — русскоговорящее сообществo
Ок, спасибо!
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
А имеет ли смысл заиметь try_collect() -> Result<T,E> как обертку вокруг вот этого?

https://github.com/search?q=%22.collect%3A%3A%3CResult%3CVec%3C_%3E%2C+_%3E%3E%28%29%22&type=code
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
.collect::<Result<Vec<_>, _>>()
источник

Э

Эрик in Rust — русскоговорящее сообществo
Нет. Иногда делают collect::<Option<T>>. Твой try_collect так не сможет без привязки к какому-нибудь Try трейту, а это анстейбл и куча ненужной работы.
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
точно, там же Try
источник

r

red75prime in Rust — русскоговорящее сообществo
Если ограничиться только Result<Vec<_>, _>, то почему бы и нет.
trait TryCollectVec: Sized + Iterator {
   fn try_collect<V, E>(self) -> Result<Vec<V>, E>
   where Result<Vec<V>, E>: FromIterator<Self::Item>
   {
       self.collect()
   }
}

impl<I: Iterator> TryCollectVec for I {}
источник

Э

Эрик in Rust — русскоговорящее сообществo
red75prime
Если ограничиться только Result<Vec<_>, _>, то почему бы и нет.
trait TryCollectVec: Sized + Iterator {
   fn try_collect<V, E>(self) -> Result<Vec<V>, E>
   where Result<Vec<V>, E>: FromIterator<Self::Item>
   {
       self.collect()
   }
}

impl<I: Iterator> TryCollectVec for I {}
А если нужно собирать не в вектор?
источник

r

red75prime in Rust — русскоговорящее сообществo
Эрик
А если нужно собирать не в вектор?
Сделать две функции, одну для векторов, вторую обобщённую. try_collect_vec() и try_collect() -> Result<Container, E>
источник

f

folex in Rust — русскоговорящее сообществo
У меня есть вот такой вот макрос

macro_rules! poll_loop {
 ($self:ident,$behaviour:expr,$cx:expr,$params:expr,$either:path) => {{
   ...
   Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, event, handler, }) => {
     return Poll::Ready(NetworkBehaviourAction::NotifyHandler {
       peer_id,
       event: $either(event),
       handler,
     })
   }
   ...
 }};
}

И у меня загвоздка с $either. Вот так всё работает:
poll_loop!(self, self.plumber, cx, params, EitherOutput::First);
poll_loop!(self, self.dht, cx, params, EitherOutput::Second);

Но еще хотелось бы уметь передавать в $either какой-то вид identity, т.е. "ничего". Чтобы в итоге event: $either(event) превратилось просто в event: event.

Есть идеи, как можно этого добиться? Как-то вот так не работает
poll_loop!(self, self.plumber, cx, params, ::);

P.S. Совсем круто было бы уметь указывать какую-то ast-лямбду, типа
poll_loop!(self, self.plumber, cx, params, event => EitherOutput::First(EitherOutput::First(event)));
но я не нашел ничего такого
источник

Э

Эрик in Rust — русскоговорящее сообществo
folex
У меня есть вот такой вот макрос

macro_rules! poll_loop {
 ($self:ident,$behaviour:expr,$cx:expr,$params:expr,$either:path) => {{
   ...
   Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, event, handler, }) => {
     return Poll::Ready(NetworkBehaviourAction::NotifyHandler {
       peer_id,
       event: $either(event),
       handler,
     })
   }
   ...
 }};
}

И у меня загвоздка с $either. Вот так всё работает:
poll_loop!(self, self.plumber, cx, params, EitherOutput::First);
poll_loop!(self, self.dht, cx, params, EitherOutput::Second);

Но еще хотелось бы уметь передавать в $either какой-то вид identity, т.е. "ничего". Чтобы в итоге event: $either(event) превратилось просто в event: event.

Есть идеи, как можно этого добиться? Как-то вот так не работает
poll_loop!(self, self.plumber, cx, params, ::);

P.S. Совсем круто было бы уметь указывать какую-то ast-лямбду, типа
poll_loop!(self, self.plumber, cx, params, event => EitherOutput::First(EitherOutput::First(event)));
но я не нашел ничего такого
Такое не работает?

macro_rules! poll_loop {
($self:ident, $behaviour:expr ,$cx:expr, $params:expr, ::) => {};
($self:ident, $behaviour:expr, $cx:expr, $params:expr, $either:path) => {};
}
источник

в🧇

вафель 🧇 in Rust — русскоговорящее сообществo
folex
У меня есть вот такой вот макрос

macro_rules! poll_loop {
 ($self:ident,$behaviour:expr,$cx:expr,$params:expr,$either:path) => {{
   ...
   Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, event, handler, }) => {
     return Poll::Ready(NetworkBehaviourAction::NotifyHandler {
       peer_id,
       event: $either(event),
       handler,
     })
   }
   ...
 }};
}

И у меня загвоздка с $either. Вот так всё работает:
poll_loop!(self, self.plumber, cx, params, EitherOutput::First);
poll_loop!(self, self.dht, cx, params, EitherOutput::Second);

Но еще хотелось бы уметь передавать в $either какой-то вид identity, т.е. "ничего". Чтобы в итоге event: $either(event) превратилось просто в event: event.

Есть идеи, как можно этого добиться? Как-то вот так не работает
poll_loop!(self, self.plumber, cx, params, ::);

P.S. Совсем круто было бы уметь указывать какую-то ast-лямбду, типа
poll_loop!(self, self.plumber, cx, params, event => EitherOutput::First(EitherOutput::First(event)));
но я не нашел ничего такого
А нельзя просто напросто передать туда std::convert::identity?
источник

Э

Эрик in Rust — русскоговорящее сообществo
И вместо $either:path можно передавать $into_event:expr. Туда просто пихать любые лямбды или функции, которые могут принимать event.
источник

f

folex in Rust — русскоговорящее сообществo
Эрик
Такое не работает?

macro_rules! poll_loop {
($self:ident, $behaviour:expr ,$cx:expr, $params:expr, ::) => {};
($self:ident, $behaviour:expr, $cx:expr, $params:expr, $either:path) => {};
}
Я сделал примерно так же:
macro_rules! poll_loop {
 ($self:ident,$behaviour:expr,$cx:expr,$params:expr$(,$either:path)?) => {{
     $(let event = $either(event);)?
     ...
 }};
}
источник

Э

Эрик in Rust — русскоговорящее сообществo
macro_rules! poll_loop {
 ($self:ident, $behaviour:expr, $cx:expr, $params:expr, $into_event:expr) => {{
   ...
   Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, event, handler, }) => {
     return Poll::Ready(NetworkBehaviourAction::NotifyHandler {
       peer_id,
       event: $into_event(event),
       handler,
     })
   }
   ...
 }};
}

poll_loop!(self, self.plumber, cx, params, EitherOutput::First);
poll_loop!(self, self.plumber, cx, params, std::convert::identity);
poll_loop!(self, self.plumber, cx, params, |event| event.into());
источник

Э

Эрик in Rust — русскоговорящее сообществo
Вот такое вот должно работать.
источник

f

folex in Rust — русскоговорящее сообществo
folex
Я сделал примерно так же:
macro_rules! poll_loop {
 ($self:ident,$behaviour:expr,$cx:expr,$params:expr$(,$either:path)?) => {{
     $(let event = $either(event);)?
     ...
 }};
}
Но вариант с into_event мне нравится больше, спасибо!
источник

m

mAX in Rust — русскоговорящее сообществo
Товарищи, подскажите пожалуйста!
хочу сделать удобный доступ к объекту из разных потоков
Не очень хочется таскать за собой Arc<RwLock<>> каждый раз и хочется спрятать все в одну структуру и сделать чтобы ее можно было клонировать и отправлять между потоками, тасками tokio

пусть внутри такой структуры уже будет Arc<RwLock<>> и весь код работы с примитивами синхронизации я хочу спрятать в ее методах

Допустим сделал вот так

#[derive(Debug)]
struct SegmentsStore {}

#[derive(Clone, Debug)]
struct SegmentsCache {
   store: std::sync::Arc<parking_lot::RwLock<SegmentsStore>>
}
unsafe impl Send for SegmentsCache {}
unsafe impl Sync for SegmentsCache {}

impl SegmentsCache {
   fn new() -> Self {
       Self { store: std::sync::Arc::new(parking_lot::RwLock::new(SegmentsStore {})) }
   }
   fn add(&self) {  unimplemented!() }
   fn remove(&self) {  unimplemented!() }
}

Достаточно ли этого?
Не понимаю как работают Send и Sync т.к. всегда использовал Arc<> и не парился) И есть опасение что мой вариант хоть и компилится, но может что-то поломать)
источник

MB

Mikail Bagishov in Rust — русскоговорящее сообществo
unsafe impl почти наверняка не нужен тут
источник

Э

Эрик in Rust — русскоговорящее сообществo
Убери unsafe impl. Если Arc<RwLock<T>> их будет имплементить, они автоматом твоей структуре зайдут.
источник