相关疑难解决方法(0)

如何将对堆栈变量的引用传递给线程?

我正在编写一个WebSocket服务器,其中一个Web客户端连接到多线程计算机AI上下棋.WebSocket服务器想要将Logger对象传递给AI代码.该Logger对象将管理从AI到Web客户端的日志行.在Logger必须包含对客户端连接的参考.

我对生命周期如何与线程交互感到困惑.我用Wrapper类型参数化的结构重现了这个问题.该run_thread函数尝试解包该值并记录它.

use std::fmt::Debug;
use std::thread;

struct Wrapper<T: Debug> {
    val: T,
}

fn run_thread<T: Debug>(wrapper: Wrapper<T>) {
    let thr = thread::spawn(move || {
        println!("{:?}", wrapper.val);
    });

    thr.join();
}

fn main() {
    run_thread(Wrapper::<i32> { val: -1 });
}
Run Code Online (Sandbox Code Playgroud)

wrapper参数存在于堆栈中,并且它的生命周期不会延伸超过run_thread堆栈帧,即使该线程将在堆栈帧结束之前连接.我可以从堆栈中复制值:

use std::fmt::Debug;
use std::thread;

struct Wrapper<T: Debug + Send> {
    val: T,
}

fn run_thread<T: Debug + Send + 'static>(wrapper: Wrapper<T>) {
    let thr = thread::spawn(move || …
Run Code Online (Sandbox Code Playgroud)

rust

22
推荐指数
1
解决办法
3771
查看次数

如何克隆存储盒装特征对象的结构?

我编写了一个程序,它具有特征AnimalDog实现特征的结构.它还有一个AnimalHouse存储动物作为特征对象的结构Box<Animal>.

trait Animal {
    fn speak(&self);
}

struct Dog {
    name: String,
}

impl Dog {
    fn new(name: &str) -> Dog {
        return Dog {
            name: name.to_string(),
        };
    }
}

impl Animal for Dog {
    fn speak(&self) {
        println!{"{}: ruff, ruff!", self.name};
    }
}

struct AnimalHouse {
    animal: Box<Animal>,
}

fn main() {
    let house = AnimalHouse {
        animal: Box::new(Dog::new("Bobby")),
    };
    house.animal.speak();
}
Run Code Online (Sandbox Code Playgroud)

它返回"Bobby:ruff,ruff!" 正如所料,但如果我尝试克隆house编译器返回错误:

fn main() {
    let house …
Run Code Online (Sandbox Code Playgroud)

struct clone traits cloneable rust

20
推荐指数
3
解决办法
3891
查看次数

克隆存储闭包的结构

我目前正在尝试在Rust中实现一个简单的Parser-Combinator库.为此,我希望有一个泛型map函数来转换解析器的结果.

问题是我不知道如何复制持有闭包的结构.示例是Map以下示例中的结构.它有一个mapFunction存储函数的字段,它接收前一个解析器的结果并返回一个新结果.Map它本身就是一个可以与其他解析器进一步组合的解析器.

但是,对于要组合的解析器,我需要它们是可复制的(具有Clone特征限制),但是我该如何提供Map呢?

示例:(只有伪代码,很可能无法编译)

trait Parser<A> { // Cannot have the ": Clone" bound because of `Map`.
    // Every parser needs to have a `run` function that takes the input as argument
    // and optionally produces a result and the remaining input.
    fn run(&self, input: ~str) -> Option<(A, ~str)>
}

struct Char {
    chr: char
}

impl Parser<char> for Char {
    // The char parser returns Some(char) if …
Run Code Online (Sandbox Code Playgroud)

rust rust-0.9

9
推荐指数
1
解决办法
729
查看次数

如何创建一个实现 Fn 并可以克隆到不同对象的特征对象?

如果我想要一个不可复制的类型擦除(动态类型)可调用,那就是

Box<dyn Fn(i32) -> ()>
Run Code Online (Sandbox Code Playgroud)

如果我想要一个引用计数类型擦除的可调用对象,那就是(取决于我是否需要线程安全)

Rc<dyn Fn(i32) -> ()>
Arc<dyn Fn(i32) -> ()>
Run Code Online (Sandbox Code Playgroud)

但在这里,这些副本都引用相同的底层内存——它们并不不同。

如果我想要不同的可调用对象,我该怎么做?当Implements时Box<T>已经实现,但未实现,因此不适用于此处。做类似的事情:CloneTCloneFnClone

Box<dyn Fn(i32) -> () + Clone>
Run Code Online (Sandbox Code Playgroud)

失败并显示:

error[E0225]: only auto traits can be used as additional traits in a trait object
 --> src/main.rs:7:35
  |
7 | fn foo(f: Box<dyn Fn(i32) -> () + Clone>) {
  |                   -------------   ^^^^^ additional non-auto trait
  |                   |
  |                   first non-auto trait
  |
  = help: consider creating a new trait …
Run Code Online (Sandbox Code Playgroud)

rust

5
推荐指数
1
解决办法
1194
查看次数

使用推断(?)类型克隆std :: iter :: Map

我无法以紧凑的方式克隆地图:

extern crate itertools_num;

use itertools_num::linspace;

fn main() {
    // 440Hz as wave frequency (middle A)
    let freq: f64 = 440.0;
    // Time vector sampled at 880 times/s (~Nyquist), over 1s
    let delta: f64 = 1.0 / freq / 2.0;
    let time_1s = linspace(0.0, 1.0, (freq / 2.0) as usize)
        .map(|sample| { sample * delta});

    let sine_440: Vec<f64> = time_1s.map(|time_sample| {
        (freq * time_sample).sin()
    }).collect();

    let sine_100: Vec<f64> = time_1s.map(|time_sample| {
        (100.0 * time_sample).sin()
    }).collect();
}
Run Code Online (Sandbox Code Playgroud)

我用这段代码得到的错误是

`time_1s` moved here …
Run Code Online (Sandbox Code Playgroud)

iterator clone type-inference rust

3
推荐指数
1
解决办法
106
查看次数

为什么在转移所有权后可以使用非捕获闭包?

我试图了解 Rust 中的所有权,但遇到了与转让所有权相关的误解。考虑以下代码:

fn main() {
    let closure = || 32;
    foo(closure);
    foo(closure); //perfectly fine
}

fn foo<F>(f: F) -> u32
where
    F: Fn() -> u32,
{
    f()
}
Run Code Online (Sandbox Code Playgroud)

操场

我认为应该转让所有权,foo(closure)不允许第二次调用。

为什么有效?

closures ownership rust borrow-checker

3
推荐指数
1
解决办法
56
查看次数

过滤器关闭时借用的时间不够长

当我尝试编译此代码(playground)时:

fn main() {
    let iter = "abc123".chars().filter(&|&c: &char| c.is_digit(10));
    match iter.clone().take(3).count() {
        3 => println!("{}", iter.collect::<String>()),
        _ => {}
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

error: borrowed value does not live long enough
 --> test.rs:2:41
  |
2 |     let iter = "abc123".chars().filter(&|c: &char| c.is_digit(10));
  |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value only lives until here
  |                                         |
  |                                         temporary value created here
...
7 | }
  | - temporary value needs to live until here
  |
  = note: consider using a `let` …
Run Code Online (Sandbox Code Playgroud)

lifetime rust

2
推荐指数
1
解决办法
949
查看次数