相关疑难解决方法(0)

如何以通用方式定义向量(或迭代器)的和?

我有以下sum功能的矢量i32编译和工作正常:

fn sum_vec(s: &Vec<i64>, init: &i64) -> i64 {
    (*s).iter().fold(*init, |acc, &item| acc + item)
}
Run Code Online (Sandbox Code Playgroud)

为了教自己关于Rust泛型,我想为任何T实现表单添加的 类型定义相应的泛型函数add(T, T) -> T.我试过了

use std::ops::Add;

fn sum_gen_1<T: Add>(s: &Vec<T>, init: &T) -> T {
    (*s).iter().fold(*init, |acc, &item| acc + item)
}
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误

error[E0308]: mismatched types
 --> src/lib.rs:4:42
  |
4 |     (*s).iter().fold(*init, |acc, &item| acc + item)
  |                                          ^^^^^^^^^^ expected type parameter, found associated type
  |
  = note: expected type `T`
             found type `<T as …
Run Code Online (Sandbox Code Playgroud)

generics sum rust

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

如何使用带有泛型向量的人造丝的.par_iter()?

这是一个人为的例子,但我相信如果我能够做到这一点,我可以将它应用于我的具体案例.

extern crate num;
extern crate rayon;
use rayon::prelude::*;
use num::Float;

fn sqrts<T: Float>(floats: &Vec<T>) -> Vec<T> {
    floats.par_iter().map(|f| f.sqrt()).collect()
}

fn main() {
    let v = vec![1.0, 4.0, 9.0, 16.0, 25.0];
    println!("{:?}", sqrts(&v));
}
Run Code Online (Sandbox Code Playgroud)

编译时出现这种错误,"方法par_iter存在,但不满足以下特征限制:&std::vec::Vec<T> : rayon::par_iter::IntoParallelIterator".如果我使用iter代替par_iter或如果我切换到使用f32f64代替通用,代码工作正常.

我能做些什么才能par_iter在泛型载体上使用?该IntoParallelIterator特征是否意味着由最终用户实施?我该怎么做呢?

generics rust rayon

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

我是否可以在泛型函数中使用原始类型的特征?

我试图写一个通用的功能,这将尝试将字符串转换为数字类型一样i32,f64等等.如果字符串是不可自由兑换,然后将返回0.我正在寻找一个适合在我的通用函数中使用的特性:

use std::str::FromStr;

fn get_num_from_str<T: FromStr>(maybe_num_str: &String) -> T {
    let maybe_num = T::from_str(maybe_num_str.as_str());
    if maybe_num.is_ok() {
        return maybe_num.unwrap();
    }
    0 as T
}

fn main() {
    let num_str = String::from("12");
    println!("Converted to i32: {}", get_num_from_str::<i32>(&num_str));
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接

我发现Rust有一个Primitive特征,之前被删除了.现在还有别的东西可以用吗?

我找到了一个解决方法:

use std::str::FromStr;

fn get_num_from_str<T: Default + FromStr>(maybe_num_str: &String) -> T {
    let maybe_num = T::from_str(maybe_num_str.as_str());
    maybe_num.unwrap_or(Default::default())
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接

正如特征约束所暗示的那样,这应该适用于任何具有两者的实现的东西Default,FromStr并且我应该重命名该函数以反映这一点,但是知道是否只有原始数字类型的任何特征我仍然会很好用于确保此功能不能用于数字类型以外的任何其他功能.

rust

5
推荐指数
2
解决办法
613
查看次数

当模式匹配类似结构的枚举变体与字段时,为什么会出现错误?

我无法摆脱这段代码的错误:

#[derive(PartialEq, Copy, Clone)]
pub enum OperationMode {
    ECB,
    CBC { iv: [u8; 16] },
}

pub struct AES {
    key: Vec<u8>,
    nr: u8,
    mode: OperationMode,
}

impl AES {
    pub fn decrypt(&mut self, input: &Vec<u8>) {
        match self.mode {
            OperationMode::ECB => {},
            OperationMode::CBC(_) => {},
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

decrypt函数末尾的模式匹配会产生错误:

error[E0532]: expected tuple struct/variant, found struct variant `OperationMode::CBC`
  --> src/main.rs:17:13
   |
17 |             OperationMode::CBC(_) => {},
   |             ^^^^^^^^^^^^^^^^^^ did you mean `OperationMode::CBC { /* fields */ }`?
Run Code Online (Sandbox Code Playgroud)

它告诉我看看rustc …

enums pattern-matching rust

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

在函数参数中,使用ref关键字和使用&符号有什么区别?

在此代码,sref1并且sref2是的地址s,和地址是相同的.ref和之间有什么区别&

fn main() {
    let s = String::from("hello");
    let sref1 = &s;
    let ref sref2 = s;
    println!("{:p}", sref1);
    println!("{:p}", sref2);

    f1(&s);
    f2(s);
}

fn f1(_s: &String) {
    println!("{:p}", _s);
}

fn f2(ref _s: String) {
    println!("{:p}", _s);
}
Run Code Online (Sandbox Code Playgroud)

_sin f1f2也是字符串的地址,f2将取得所有权,但打印f2的地址与打印的地址不同f1.为什么?

rust

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

如何将 &amp;i32 转换为 f64?

我正在尝试解决Rust Book 本章末尾的一个练习

这是一个代码示例:

fn mean(v: &Vec<i32>) -> f64 {
    let mut sum = 0.0;
    let mut count = 0.0;

    for val in v {
        sum += &f64::from(val);
        count += 1.0;
    }

    sum / count
}

fn main() {
    let v = vec![1, 2, 3, 4];

    println!("The mean is {}", mean(&v));
}
Run Code Online (Sandbox Code Playgroud)

错误是:

fn mean(v: &Vec<i32>) -> f64 {
    let mut sum = 0.0;
    let mut count = 0.0;

    for val in v {
        sum += &f64::from(val);
        count …
Run Code Online (Sandbox Code Playgroud)

rust

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

与 BTreeSet 相比,为什么使用 Vec 更快地找到整数集的交集?

我需要快速找出两个给定集合中存在多少个整数。这些集合只被写入一次,但这个操作将使用不同的集合对执行多次。这些集合包含 5-30 个整数,这些整数中最大的一个是 840000。

我最初尝试迭代一个Vec元素,并为每个元素检查它是否存在于另一个Vec. 然后我决定BTreeSet改用它,因为它在检查集合中是否存在整数时应该明显更快,但情况似乎并非如此。Vec在稳定的 Rust 1.34 下,在稳定的 Rust 1.34 下以发布模式调用数千个集合时,该实现需要 ~72ms 和 BTreeSet ~96ms,并且在夜间使用时具有相同的性能。

这是Vec实现:

use std::cmp;

fn main() {
    let mut sets = Vec::with_capacity(1000);
    for i in 1..1000 {
        let mut set = Vec::new();
        for j in 1..i % 30 {
            set.push(i * j % 50000);
        }
        sets.push(set);
    }
    for left_set in sets.iter() {
        for right_set in sets.iter() {
            calculate_waste(left_set, right_set);
        }
    }
}

fn calculate_waste(left_nums: &Vec<usize>, …
Run Code Online (Sandbox Code Playgroud)

b-tree vector set-intersection rust

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

如何在一行中连接不可变向量?

我有不可变的向量ab其中元素的复制成本很低,我想创建一个向量来形成这些现有向量的串联而不改变它们 (*)。

如果其中一个向量是可变的则较早的问题解决了这个问题,因此一个明显的答案是首先克隆向量a,例如

let mut r = a.clone();
r.extend(&b);
Run Code Online (Sandbox Code Playgroud)

但这似乎既不优雅也不高效(扩展很容易导致不必要的重新分配,对吧?)。我(作为 Rust 菜鸟)提出(修正后的)最佳选择是:

fn cat(a: &Vec<i32>, b: &Vec<i32>) -> Vec<i32> {
    let mut r = Vec::<i32>::with_capacity(a.len() + b.len());
    r.extend(a);
    r.extend(b);
    r
}
Run Code Online (Sandbox Code Playgroud)

由于元素复制起来很便宜,因此对于字符串向量更通用问题的答案应该适用于这里,但vec![a, b].concat()只有当您通过将向量移动到向量中来构造向量向量时,这似乎才有效,因为会vec![&a, &b].concat()产生“未concat找到命名的方法”。

对于这项看似简单的工作,即使它不是最佳的,是否有一种单行方式?


(*) 原来“不改变”有两种含义:

  • 只是不可变的,这在 Rust 中意味着如果代码编译,它不会看到具有更改值的变量;但变量可能会被移出,进一步或未来的代码不能再使用它
  • 实际上是只读的,保留变量不变以供进一步或将来的代码使用

vector concatenation rust

4
推荐指数
2
解决办法
2579
查看次数

如何在不首先将其转换为String的情况下将char或&str附加到String?

我试图写一个有趣的词法分析器,但有些东西一直困扰着我.

let mut chars: Vec<char> = Vec::new();
let mut contents = String::new();
let mut tokens: Vec<&String> = Vec::new();
let mut append = String::new();
//--snip--
for _char in chars {
    append += &_char.to_string();
    append = append.trim().to_string();

    if append.contains("print") {
        println!("print found at: \n{}", append);
        append = "".to_string();
    }
}
Run Code Online (Sandbox Code Playgroud)

任何时候,我想做为一个附加一些简单&strString我不得不使用它转换.to_string,String::from(),.to_owned,等.

有什么我做错了,所以我不必经常这样做,或者这是追加的主要方式?

string rust

4
推荐指数
1
解决办法
448
查看次数

在Rust中返回递归闭包

我有以下高阶函数

fn ensure_tonicty(tone_fn: &fn(&f64, &f64) -> bool) -> impl Fn(&Vec<f64>) -> bool {
    return |floats: &Vec<f64>| -> bool {
        let first = floats.first().unwrap();
        let rest = &floats[1..];
        fn f(tone_fn: &fn(&f64, &f64) -> bool, prev: &f64, xs: &[f64]) -> bool {
            match xs.first() {
                Some(x) => tone_fn(prev, x) && f(tone_fn, x, &xs[1..]),
                None => true,
            }
        };
        return f(tone_fn, first, rest);
    };
}
Run Code Online (Sandbox Code Playgroud)

我的目标是返回此lambda。我不知道如何有效地tone_fn在这里使用。

上面的代码出错了:

error[E0621]: explicit lifetime required in the type of `tone_fn`
 --> src/lib.rs:1:56
  |
1 | …
Run Code Online (Sandbox Code Playgroud)

recursion closures reference lifetime rust

4
推荐指数
1
解决办法
189
查看次数