Подтвердить что ты не робот

Оператор компоновки и оператор прямой трубы в Rust

Существуют ли в Rust и операторы форматирования композиции и трубы (как на других языках)? Если да, то как они выглядят, и нужно ли отдавать предпочтение другому? Если этого не существует, почему этот оператор не нужен?

4b9b3361

Ответ 1

Нет такого встроенного оператора, но его особо трудно определить:

use std::ops::Shr;

struct Wrapped<T>(T);

impl<A, B, F> Shr<F> for Wrapped<A>
    where F: FnOnce(A) -> B
{
    type Output = Wrapped<B>;

    fn shr(self, f: F) -> Wrapped<B> {
        Wrapped(f(self.0))
    }
}

fn main() {
    let string = Wrapped(1) >> (|x| x + 1) >> (|x| 2 * x) >> (|x: i32| x.to_string());
    println!("{}", string.0);
}
// prints `4`

Структура нового типа Wrapped предназначена исключительно для экземпляра Shr, поскольку в противном случае мы должны были бы реализовать его на общем (т.е. impl<A, B> Shr<...> for A), и это не сработает.


Обратите внимание, что идиоматический Rust назвал бы это методом map вместо использования оператора. См. Option::map для канонического примера.

Ответ 2

Эти операторы не существуют в Rust, насколько я знаю. До сих пор я не ощущал большой потребности в них, и есть также попытка сохранить синтаксис основного ржавчины довольно небольшим. Например, у Rust были явные команды передачи сообщений, но они были удалены.

Возможно, вы сможете использовать перегрузку оператора, чтобы придумать что-то подобное, если хотите, или просто написать свои собственные функции компоновки или пересылки труб. Я бы не удивился, если бы команда Rust была открыта, чтобы включить их в стандартную библиотеку.

Ответ 3

Как сказал другой плакат, в Rust нет такого оператора и, скорее всего, его не добавят. Оператор прямой линии, описанный на странице, которую вы связываете, облегчает поток данных. Для этого путь ржавчины - это запуск задач и использование каналов данных для отправки информации между ними.

Задачи похожи на потоки на других языках, хотя они имеют гораздо более ограничительные (и, следовательно, более безопасные) правила обмена памятью. В качестве примера, здесь представлена ​​программа ржавчины, которая использует задачи и порты/каналы для облегчения потока данных между двумя процессами. Примечание - этот код был скомпилирован против версии 0.6

extern mod std;

// Import the relevant pipes structs and the stream fn
use core::pipes::{stream, Port, Chan};
use std::comm::DuplexStream;

// This function shows the simplest case of using a
// channel and a pipe
fn pipes() {
  // Create a new stream
  let (port, chan): (Port<int>, Chan<int>) = stream();
  // Spawn off a task to send '10' through the channel
  do spawn { chan.send(10); }
  // The recv call will block until data is present
  println(int::to_str(port.recv()));
}

// This function will serve as the logic for the
// data flow task below
fn plus_one(channel: &DuplexStream<int, int>) {
  let mut value: int;
  // Add one and send back the result until 0 is encountered
  loop { 
    value = channel.recv();
    channel.send(value + 1);
    if value == 0 { break; }
  }
}

fn main() {
  // DuplexStream, as the name implies, allows bidirectional
  // information flow
  let (from_child, to_child) = DuplexStream();

  do spawn { plus_one(&to_child); };

  from_child.send(22);
  from_child.send(23);
  from_child.send(24);
  from_child.send(25);
  from_child.send(0);

  for 4.times {
    let answer = from_child.recv();
    println(int::to_str(answer));
  }
}

Эта концепция может быть расширена для моделирования любого потока данных, который требуется для выполнения вашей программы. Может быть полезно повторить концептуализацию вашей проблемы с точки зрения Модель актера. Наконец, по мере того, как вы работаете с языком, в Интернете есть ряд действительно полезных ресурсов, которые я предлагаю вам посоветоваться:

Надеюсь, что это поможет, и добро пожаловать в сообщество Rust!