简体   繁体   English

如何注释结构成员 function 返回实现读写的 object

[英]How to annotate a struct member that is a function that returns an object that implements Read and Write

I'm implementing a small service that accepts commands over TCP and relays it to device that also accepts commands over TCP.我正在实施一项小型服务,它接受 TCP 上的命令并将其中继到也接受 TCP 上的命令的设备。

I wrote the entire thing then went to test it and thought that the best way would be to use dependency injection so that I can provide some stream representing the device to test against that.我写了整个东西然后去测试它,我认为最好的方法是使用依赖注入,这样我就可以提供一些 stream 代表设备来测试它。

I am having trouble annotating the struct member that produces the stream.我在注释生成 stream 的结构成员时遇到问题。

How should I go about annotating a struct member that is a function that returns a type that implements Read and Write ? go 我应该如何注释一个返回实现ReadWrite的类型的 function 结构成员?

This is a rough sketch of the situation.这是一个粗略的情况。

struct Handle {
    // I want to describe a function that returns a object that implements Read and Write
    stream_factory: Result<Box<dyn Read + Write>, Box<dyn std::error::Error>>
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let tcp_factory = || std::net::TcpStream::connect("127.0.0.1:1");
    let handle_a = Handle {
        stream_factory: tcp_factory
    }
    
    let file_factory = || std::file::File::options()
    .read(true)
    .write(true)
    .open("foo.txt");
    let handle_b = Handle {
        stream_factory: tcp_factory
    }
    
    Ok(())
}

You can either box the a trait that has Read and Write as a supertrait您可以将具有ReadWrite作为超特征的特征框起来

use std::io::{Read, Write};
use std::net::TcpStream;

trait ReadWrite: Read + Write {}
impl ReadWrite for TcpStream {}

struct Handle {
    // You will need to use Box<Fn() -> ...>
    // if you want to capture data in the factory function
    stream_factory: fn() -> Result<Box<dyn ReadWrite>, std::io::Error>,
}

fn main() {
    let tcp_factory = || {
        TcpStream::connect("127.0.0.1:1")
            .map(|x| Box::new(x) as Box<dyn ReadWrite>)
    };
    let handle_a = Handle {
        stream_factory: tcp_factory,
    };
}

Or you could use generics, though this may not work in your case if you need to pass different Read+Write types to the same place.或者您可以使用 generics,但如果您需要将不同的Read+Write类型传递到同一位置,这可能不适用于您的情况。

struct Handle<T> 
where T : Read + Write {
    stream_factory: fn() -> Result<T, std::io::Error>,
}

fn main() {
    let tcp_factory = || {
        TcpStream::connect("127.0.0.1:1")
    };
    let handle_a = Handle {
        stream_factory: tcp_factory,
    };
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM