1

私は余暇に Rust を学んでいますが、この問題の答えを見つけるのに苦労しています。少し変更された以下のコードは、別の質問への回答として Stack-O に表示されました。テスト目的で 9 行目と 14 行目を分割しましたが、これは必須ではありません。

私がやりたいのは、match ステートメントを使用して、8/9 行目から変数を割り当てることです。または、8/9 行目と 14 行目を組み合わせたものも適しています。

誰かが match ステートメントを使用してこれを行う方法を教えてもらえますか?

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.")
    };
4

2 に答える 2

1

戻り値の型はbindですOption<TcpListener>。つまり、展開する必要があるオプションの「レイヤー」は 1 つだけです。matching を 2 回実行するか、matching と呼び出し.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");
        }
    }
}
于 2013-11-05T04:20:32.097 に答える