我在业余时间学习Rust,我很难找到这个问题的答案。下面的代码经过轻微修改后出现在Stack-O上以回答另一个问题。为了我的测试目的,我将第9行和第14行分开,但这并不重要。
我想要做的是使用match语句从第8/9行分配变量,或者从第8/9行和第14行分配变量也是合适的。
有人可以使用匹配声明告诉我如何使用这个吗?
001 use std::cell::Cell;
002 use std::rt::io::{Writer, Listener, Acceptor};
003 use std::rt::io::net::tcp::TcpListener;
004 use std::rt::io::net::ip::{SocketAddr, Ipv4Addr};
005
006 fn main() {
007
008 let o_listener = TcpListener::bind(
009 SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 9123}).listen();
010
011 print ("Listener opened : ");
012 std::io::stdin().read_line();
013
014 let mut o_acceptor = o_listener.unwrap();
015
016 println("listener is ready");
017 loop {
018 let stream = Cell::new(o_acceptor.accept().unwrap());
019 do spawn {
020 let mut stream = stream.take();
021 stream.write(bytes!("Hello World\r\n"));
022 }
023 }
024 }
仅示例:例如使用类似下面的内容,但显然是针对上述问题:
extern mod sqlite;
fn db() {
let database = match sqlite::open("test.db") {
Ok(result) => result,
Err(error) => {
println(fmt!("Error opening test.db: %?", error));
return;
}
};
编辑更新:发布问题后12小时 *
我在Win8上使用0.8
以下是我非常想解决问题的一个例子:
001 use std::cell::Cell;
002 use std::rt::io::{Writer, Listener, Acceptor};
003 use std::rt::io::net::tcp::TcpListener;
004 use std::rt::io::net::ip::{SocketAddr, Ipv4Addr};
005
006 fn main() {
007
008 // This works :
009 // let o_listener = TcpListener::bind(
010 // SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 9123}).listen();
011
012 // This doesn't work, and results in compile errors below:
013 let o_listener = match TcpListener::bind(
014 SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 9123}).listen() {
015 Some(result) => result,
016 None => fail!("Failed to open listener")
017 };
018
019 // this works in combination with lines 9/10
020 let mut o_acceptor = match o_listener {
021 Some(result) => result,
022 None => fail!("Failed to open acceptor.")
023 };
尝试编译上述结果(仅部分):
test_tcp_008.rs:20:8: 20:20 error: mismatched types: expected `std::rt::io::net:
:tcp::TcpAcceptor` but found `std::option::Option<<V21>>` (expected struct std::
rt::io::net::tcp::TcpAcceptor but found enum std::option::Option)
test_tcp_008.rs:20 Some(result) => result,
这也不起作用(编译错误):
fn main() {
let mut o_acceptor = match TcpListener::bind(
SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 9123})
.listen().unwrap() {
Some(result) => result,
None => fail!("Failed to open Listener/Acceptor.")
};
答案 0 :(得分:2)
你应该能够做到这样的事情:(我还没有尝试过编译,所以可能需要做一些改动)
let o_acceptor = match o_listener {
Some(listener) => listener,
None => fail!("Failed to open listener.")
};
答案 1 :(得分:1)
return type of bind
是Option<TcpListener>
,也就是说,只需要打开一个“层”选项。 match
两次,或match
和调用.unwrap()
(Option<T> -> T
),实际上假设类型为Option<Option<TcpListener>>
。因此,以下应该有效:
fn main() {
let o_acceptor = TcpListener::bind(
SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 9123}).listen();
print ("Listener opened : ");
std::io::stdin().read_line();
match o_acceptor {
Some(_) => println("listener is ready"),
None => println("listener failed to bind")
}
println("possibly starting requests");
match o_acceptor {
// this will need to be `Some(ref acpt)` or possibly
// `Some(ref mut acpt)` to avoid moving `o_acceptor`
// if you wish to use it later.
Some(acpt) => {
let mut acpt = acpt;
loop {
let stream = Cell::new(acpt.accept().unwrap());
do spawn {
let mut stream = stream.take();
stream.write(bytes!("Hello World\r\n"));
}
}
}
None => {
println("cannot accept because listener failed to bind");
}
}
}