特定结构的 Rust 派生克隆

时间:2021-03-24 20:16:18

标签: rust rust-tokio rust-iced

注意:我使用 iced 作为 GUI TextInputtokio 作为网络 TcpStream

我有以下几点:

#[derive(Debug, Clone)]
enum Message {
    Session(Result<Connection, ConnectionError>), //Async Handler
    SendMessage,
    Send(Result<Connection, ConnectionError>), //Async Handler
    InputChanged(String),
    Button(usize, ButtonMessage),
    None,
}

#[derive(Debug)]
enum ConnectionError {
    ConnectError(usize),
    SendError(usize),
}

#[derive(Debug)]
struct Connection {
    stream: TcpStream,
    loc: usize,
}

问题是我的 Connection 结构包含一个无法克隆的 TcpStream(无论如何克隆它在逻辑上没有意义)。

所以我得到了错误...

>the trait bound `Connection: Clone` is not satisfied
  --> src\main.rs:27:10
   |
27 |     Session(Result<Connection, ConnectionError>), //Async Handler
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone`
   |
   = note: required because of the requirements on the impl of `Clone` for `std::result::Result<Connection, ConnectionError>`
   = note: required by `clone`
   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

>error[E0277]: the trait bound `ConnectionError: Clone` is not satisfied
  --> src\main.rs:27:10
   |
27 |     Session(Result<Connection, ConnectionError>), //Async Handler
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone`
   |
   = note: required because of the requirements on the impl of `Clone` for `std::result::Result<Connection, ConnectionError>`
   = note: required by `clone`
   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

>error[E0277]: the trait bound `Connection: Clone` is not satisfied
  --> src\main.rs:29:7
   |
29 |     Send(Result<Connection, ConnectionError>), //Async Handler
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone`
   |
   = note: required because of the requirements on the impl of `Clone` for `std::result::Result<Connection, ConnectionError>`
   = note: required by `clone`
   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

>error[E0277]: the trait bound `ConnectionError: Clone` is not satisfied
  --> src\main.rs:29:7
   |
29 |     Send(Result<Connection, ConnectionError>), //Async Handler
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone`
   |
   = note: required because of the requirements on the impl of `Clone` for `std::result::Result<Connection, ConnectionError>`
   = note: required by `clone`
   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

所以我删除了克隆

#[derive(Debug)]
enum Message {
    Session(Result<Connection, ConnectionError>), //Async Handler
    SendMessage,
    Send(Result<Connection, ConnectionError>), //Async Handler
    InputChanged(String),
    Button(usize, ButtonMessage),
    None,
}

并得到以下错误:

>the trait bound `Message: Clone` is not satisfied
   --> src\main.rs:516:15
    |
516 |         let input = TextInput::new(
    |                     ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Message`
    |
   ::: C:\Users\bratl\.cargo\registry\src\github.com-1ecc6299db9ec823\iced_native-0.3.0\src\widget\text_input.rs:84:22
    |
84  |         F: 'static + Fn(String) -> Message,
    |                      --------------------- required by this bound in `iced_native::widget::text_input::TextInput::<'a, Message, Renderer>::new`

>error[E0599]: no method named `padding` found for struct `iced_native::widget::text_input::TextInput<'_, Message, iced_graphics::renderer::Renderer<iced_wgpu::backend::Backend>>` in the current scope
   --> src\main.rs:522:4
    |
26  | enum Message {
    | ------------ doesn't satisfy `Message: Clone`
...
522 |         .padding(15)
    |          ^^^^^^^ private field, not a method
    |
    = note: the method `padding` exists but the following trait bounds were not satisfied:
            `Message: Clone`

所以我去了 TextInput 所在的位置并移除了 Clone

#[derive(Debug)]
struct ClientAdminChatPaneContent {
    scroll: scrollable::State,
    input: text_input::State,
    input_value: String,
}


#[derive(Debug)]
enum ChatPaneMessage {
    InputChanged(String),
}

impl ClientAdminChatPaneContent {
    fn new() -> Self {
        ClientAdminChatPaneContent { 
            scroll: scrollable::State::new(),
            input: text_input::State::new(),
            input_value: String::from(""),
        }
    }

    fn update(&mut self, message: ChatPaneMessage) {
        match message {
            ChatPaneMessage::InputChanged(value) => {
                //println!("Input Changed: {}", value);
                self.input_value = value;
            }
        }
    }

    fn view(&mut self) -> Element<Message> {

        //Text Input
        let input = TextInput::new(
            &mut self.input,
            "Message to Client",
            &self.input_value,
            Message::InputChanged,
        )
        .padding(15)    
        .size(30)
        .on_submit(Message::SendMessage);
        
        let text_input_container:Container<Message> = Container::new(input)
            .width(Length::Fill)
            .height(Length::Units(80))
            .padding(10);

        let scroll = Scrollable::new(&mut self.scroll)
            .width(Length::Fill)
            .spacing(10)
            .align_items(Align::Start);

        let scroll_container:Container<Message> = Container::new(scroll)
            .width(Length::Fill)
            .height(Length::Fill)
            .padding(10);

        let mut content = Column::new()
            .spacing(5);

        content = content.push(scroll_container);
        content = content.push(text_input_container);

        Container::new(content)
            .width(Length::Fill)
            .height(Length::Fill)
            .padding(5)
            .center_y()
            .into()
    }

    fn clear_text(&mut self) {
        self.input_value = String::from("");
    }
}

然后我收到一个新错误:

>the trait bound `Message: Clone` is not satisfied
   --> src\main.rs:516:15
    |
516 |         let input = TextInput::new(
    |                     ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Message`
    |
   ::: C:\Users\bratl\.cargo\registry\src\github.com-1ecc6299db9ec823\iced_native-0.3.0\src\widget\text_input.rs:84:22
    |
84  |         F: 'static + Fn(String) -> Message,
    |                      --------------------- required by this bound in `iced_native::widget::text_input::TextInput::<'a, Message, Renderer>::new`

至于为什么,我不确定为什么 let input = TextInput::new( 需要实现 Clone。但是,假设我需要这个结构来实现克隆,没有 Message 由于 TCP 实现克隆......

如何获得特定项目的克隆,例如 TextInput 而不为每个项目派生它或者这是一个完全不同的问题

0 个答案:

没有答案