[英]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)
(围栏)
do_it
take &self
. do_it
take &self
。 serve
generic, by adding a type parameter with the constraints you want. serve
变得通用。 impl
of Handler
for Hello
in do_it
not discard the result of the write (remove ;
). do_it
使用Hello
do_it
Handler
的impl
不会丢弃write(remove ;
)的结果。 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.