简体   繁体   English

std :: sync :: Rust中的特征弧

[英]std::sync::Arc of trait in Rust

I am trying to implement library for making TCP servers. 我正在尝试实现用于制作TCP服务器的库。

This is very simplified code with a problem: 这是一个非常简化的代码,有一个问题:

#![crate_name="http_server2"]
#![crate_type="lib"]

use std::io::{TcpListener, Listener, Acceptor, TcpStream, IoResult, Reader, Writer};
use std::ops::Fn;
use std::sync::Arc;


pub trait Handler: Sized + Send {
    fn do_it(s: TcpStream) -> IoResult<()>;
}

fn serve(handler: Arc<Handler + Sized>) -> IoResult<()>
{
    let listener = TcpListener::bind("127.0.0.1", 1234);

    for stream in try!(listener.listen()).incoming() {
        let stream = try!(stream);
        let handler = handler.clone();
        spawn(proc() {
            handler.do_it(stream);
        });
    }
    Ok(())
}

Compiler totally ignores my specifications of Handler + Sized . 编译器完全忽略了我的Handler + Sized规范。 If I implement structure with trait Handler and try to call serve with this structure, such advice about size will be ignored too ( http://is.gd/OWs22i ). 如果我使用trait Handler实现结构并尝试使用此结构调用serve ,那么关于大小的建议也将被忽略( http://is.gd/OWs22i )。

<anon>:13:1: 25:2 error: the trait `core::kinds::Sized` is not implemented for the type `Handler+'static+Sized`
<anon>:13 fn serve(handler: Arc<Handler + Sized>) -> IoResult<()>
<anon>:14 {
<anon>:15     let listener = TcpListener::bind("127.0.0.1", 1234);
<anon>:16 
<anon>:17     for stream in try!(listener.listen()).incoming() {
<anon>:18         let stream = try!(stream);
          ...
<anon>:13:1: 25:2 note: the trait `core::kinds::Sized` must be implemented because it is required by `alloc::arc::Arc`
<anon>:13 fn serve(handler: Arc<Handler + Sized>) -> IoResult<()>
<anon>:14 {
<anon>:15     let listener = TcpListener::bind("127.0.0.1", 1234);
<anon>:16 
<anon>:17     for stream in try!(listener.listen()).incoming() {
<anon>:18         let stream = try!(stream);
          ...
error: aborting due to previous error

How can I implement one template function with multithreading that will accept different handlers? 如何使用多线程实现一个接受不同处理程序的模板函数?

As I said in my comment above, 正如我在上面的评论中所说,

use std::io::{TcpListener, Listener, Acceptor, TcpStream, IoResult, Writer};
use std::sync::Arc;

pub trait Handler: Sized + Send {
    fn do_it(&self, s: TcpStream) -> IoResult<()>;
}

fn serve<T: Handler + Sized + Send + Sync>(handler: Arc<T>) -> IoResult<()> {
    let listener = TcpListener::bind("127.0.0.1", 1234);
    for stream in try!(listener.listen()).incoming() {
        let stream = try!(stream);
        let handler = handler.clone();
        spawn(proc() { 
            let _ = handler.do_it(stream); 
        });
    }
    Ok(())
}

struct Hello {
    x: u32,
}

impl Handler for Hello {
    fn do_it(&self, mut s: TcpStream) -> IoResult<()> { s.write_le_u32(self.x) }
}

fn main() { 
    let s = Arc::new(Hello{x: 123,}); 
    let _ = serve(s); 
}

compiles fine. 编译好。 (playpen) (围栏)


Changes 变化

  1. Make do_it take &self . make do_it take &self
  2. Make serve generic, by adding a type parameter with the constraints you want. 通过添加具有所需约束的类型参数,使serve变得通用。
  3. Make the impl of Handler for Hello in do_it not discard the result of the write (remove ; ). do_it使用Hello do_it Handlerimpl不会丢弃write(remove ; )的结果。
  4. Clarify with let _ = ... that we intentionally discard a result. 澄清let _ = ...我们故意丢弃结果。

You will not be able to execute it in the playpen though ( application terminated abnormally with signal 31 (Bad system call) ), as the playpen forbids IO (network IO in this case). 您将无法在游戏围栏中执行它( application terminated abnormally with signal 31 (Bad system call) ),因为游戏围栏禁止IO(在这种情况下为网络IO)。 It runs fine on my local box though. 它虽然在我当地的盒子上运行良好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Rust 2021 与 2018:特征 `std::marker::Send` 未实现 - 在 2021 版中执行此操作的正确方法是什么? - Rust 2021 vs. 2018: trait `std::marker::Send` is not implemented - what is the correct way to do this in 2021 edition? Rust:使用Mutex和Arc进行变异 - Rust: Using Mutex and Arc to mutate Rust中的共享互斥锁问题(为Arc实现AsyncRead/AsyncWrite <mutex<ipstack> &gt;) </mutex<ipstack> - The shared mutex problem in Rust (implementing AsyncRead/AsyncWrite for Arc<Mutex<IpStack>>) Rust - 与 Arc 一起使用时无法读取互斥锁内的文件 - Rust - Unable to read a file inside a mutex when it is used with an Arc std :: launch :: async像同步进程一样阻塞 - std::launch::async is blocking like a sync process 使用std :: atomic和std :: condition_variable,Sync是不可靠的 - Sync is unreliable using std::atomic and std::condition_variable 修改 Arc 是否安全<mutex<t> &gt; 来自 Rust 线程和外国线程? </mutex<t> - Is it safe to modify an Arc<Mutex<T>> from both a Rust thread and a foreign thread? 将包含 Arc 的 self 移动到新线程时,为什么会出现“同步不满足”的错误? - Why do I get an error that "Sync is not satisfied" when moving self, which contains an Arc, into a new thread? 既然 U32 已经实现了同步,为什么还要在 Rust 中使用 AtomicU32? - Why use an AtomicU32 in Rust, given that U32 already implements Sync? MFC ResumeThread 和 std::condition_variable 等待后偶尔线程同步失败 - Occassional thread sync fail after MFC ResumeThread and std::condition_variable wait
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM