【问题标题】:Iterating over a vector of functions that return objects sharing the same trait迭代返回具有相同特征的对象的函数向量
【发布时间】:2018-02-14 03:20:15
【问题描述】:

Iterate over vector of functions 非常相似,我想迭代一个 vec 函数。不同之处在于,我想调用每个函数并返回一个具有 std::fmt::Display 特征的对象。

use std::time::Instant;
use std::fmt;

fn timer<T: fmt::Display> (msg: &str, x: &Fn() -> T) -> T {
    let now = Instant::now();
    let val = x();
    println!("({}) took {} ms\n\tResult: {}", 
        msg,
        now.elapsed().subsec_nanos() / 1000,
        val
    );
    val
}

fn run_all<T: fmt::Display> () {
    let problems: Vec<&Fn() -> T> = vec![
        &|| prob_1(1000),
        &|| prob_2(4_000_000),
        &|| prob_3(600_851_475_143),
        &|| prob_4(3),
        &|| prob_5(20),
        &|| prob_6(100),
        &|| prob_7(10_000)
    ];

    for (i, func) in problems.iter().enumerate() {
        let problem_num: &str = ((i as u64) + 55).to_string().as_str();
        timer(i, &func);
    }
}

七个编译器错误之一看起来像

error[E0308]: mismatched types
  --> euler.rs:17:13
   |
17 |         &|| prob_1(1000),
   |             ^^^^^^^^^^^^ expected type parameter, found u32
   |
   = note: expected type `T`
              found type `u32`

到目前为止,这些函数中的每一个都返回 u32u64(它们是 Project Euler 问题),但如果可能的话,我希望将其推广到共享该特征的所有类型。

【问题讨论】:

  • 您没有向我们展示任何 prob_X 函数的类型签名,因此无法重现您的问题或回答此问题。
  • @loganfsmyth prob_1 是 u32 -> u32,prob_3 是 u64 -> u64。计时器函数的类型适用于每个问题调用闭包的单独调用,它是我现在似乎挂断的闭包和类型检查器的集合。

标签: rust closures traits


【解决方案1】:

首先,你会在当前设置中遇到生命周期错误,所以让我们切换到使用其他东西,而不是使用立即超出范围的闭包的引用......

let problems: Vec<fn() -> T> = vec![
        || prob_1(1000),
        || prob_2(4_000_000),
        || prob_3(600_851_475_143),
        || prob_4(3),
        || prob_5(20),
        || prob_6(100),
        || prob_7(10_000)
    ];

现在发生此错误是因为您的函数返回具体类型(即u32u64)。这些不会隐式转换为T,您必须手动执行此操作。我建议查找 From 特征并实施它,以便您可以进行转换。否则,请在任何地方使用具体类型。

【讨论】:

    猜你喜欢
    • 2016-08-27
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多