相关疑难解决方法(0)

iter和into_iter有什么区别?

我正在做Rust示例教程,其中包含以下代码片段:

// Vec example
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];

// `iter()` for vecs yields `&i32`. Destructure to `i32`.
println!("2 in vec1: {}", vec1.iter()     .any(|&x| x == 2));
// `into_iter()` for vecs yields `i32`. No destructuring required.
println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2));

// Array example
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];

// `iter()` for arrays yields `&i32`.
println!("2 in array1: {}", array1.iter() …
Run Code Online (Sandbox Code Playgroud)

rust

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

何时取消引用或不取消引用

我正在浏览“Rust Book”网站,以便学习即将到来的工作面试的语言。在向量章节中,有两个代码示例:

fn main() {
    let v = vec![100, 32, 57];
    for i in &v {
        println!("{}", i);
    }
}
Run Code Online (Sandbox Code Playgroud)

和:

fn main() {
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        *i += 50;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想知道,为什么对于第一个样本,当我们将对向量元素i的引用传递到:

println!("{}", i);

但是在我们向向量的每个元素添加 50 的示例中,在添加到 50 之前,我们必须使用 * 取消引用该元素?

我们为什么不/不能做以下事情:

fn main() {
    let v = vec![100, 32, 57];
    for i in &v {
        println!("{}", *i); // why don't we have to dereference before we …
Run Code Online (Sandbox Code Playgroud)

pointers reference dereference rust

16
推荐指数
1
解决办法
4367
查看次数

引用和 Box<T> 在内存中的表示方式有什么区别?

我试图了解引用和Box<T>工作方式。让我们考虑一个代码示例:

fn main() {
    let x = 5;
    let y = &x;

    assert_eq!(5, x);
    assert_eq!(5, *y);
}
Run Code Online (Sandbox Code Playgroud)

在我的想象中,Rust 将内存中的值保存为:

在此处输入图片说明

考虑第二个代码片段Box<T>

fn main() {
    let x = 5;
    let y = Box::new(x);

    assert_eq!(5, x);
    assert_eq!(5, *y);
}
Run Code Online (Sandbox Code Playgroud)

将如何x存储Box?内存是什么样子的?

上面的例子来自使用DerefTrait处理像常规引用一样的智能指针。对于第二个例子,本书将其解释为:

y示例15-7 和示例15-6 之间的唯一区别是,这里我们设置为指向 in 值的框的实例,x而不是指向 值的引用x

这是否意味着y在框中直接指向 value 5

rust

14
推荐指数
1
解决办法
845
查看次数

为什么在(* x).into()中需要显式取消引用,而在x.my_into()中却不需要?

在阅读了方法调用表达式解引用运算符方法查找自动解引用之后,我认为我对该主题有了很好的理解。但是后来我遇到了一种情况,我希望自动重新引用会发生,而实际上却没有发生。

示例如下。

#[derive(Clone, Copy, Debug)]
struct Foo();

impl Into<&'static str> for Foo {
    fn into(self) -> &'static str {
        "<Foo as Into>::into"
    }
}

fn vec_into<F: Copy + Into<T>, T>(slice: &[F]) -> Vec<T> {
    slice.iter().map(|x| (*x).into()).collect()
}

fn main() {
    let array = [Foo(), Foo(), Foo()];
    let vec = vec_into::<_, &'static str>(&array);
    println!("{:?}", vec);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码有效,但是我认为不需要(*x).into()在函数中vec_into进行显式取消引用。我的理由是,因为x: &Foo,然后x.into()就试图找到接受类型的方法&Foo&&Foo&mut &Foo, …

traits dereference implicit-conversion rust

10
推荐指数
1
解决办法
151
查看次数

将 Rc&lt;dyn Trait&gt; 作为函数参数传递时出错

将 aRc<dyn Trait>作为函数参数传递时,我面临一些奇怪的行为。下面的代码演示了这个问题。

use std::rc::Rc;

trait Trait {}

struct Struct {}

impl Trait for Struct {}

fn function(_t: Rc<dyn Trait>) {}

fn main() {
    let n = Rc::new(Struct {});

    // ok
    let r = Rc::clone(&n);
    function(r);

    // error, why?
    // function(Rc::clone(&n));
}
Run Code Online (Sandbox Code Playgroud)

如果我将 存储Rc在一个临时变量中,则一切正常。但是,如果我尝试Rc::clone在函数调用中直接调用,则会出现以下错误。

use std::rc::Rc;

trait Trait {}

struct Struct {}

impl Trait for Struct {}

fn function(_t: Rc<dyn Trait>) {}

fn main() {
    let n = Rc::new(Struct {});

    // ok
    let r …
Run Code Online (Sandbox Code Playgroud)

rust

10
推荐指数
1
解决办法
469
查看次数

自动解除引用和deref强制之间有什么关系?

经过一些讨论,我现在有点困惑之间的关系auto-dereferencingderef coercion.

似乎 "自动解除引用"一词仅适用于取消引用的目标是方法接收者,而"deref强制"一词似乎适用于函数参数及其所需的所有上下文.

我认为解除引用并不总是涉及deref强制,但我不确定:dereferencing是否始终使用某些Deref::deref特征实现?

如果是这样,是T: Deref<Target = U> where T: &U编译器内置的实现者吗?

最后,在编译器隐式转换&&&&x为的所有情况下,使用术语"autoderef"听起来很自然&x:

pub fn foo(_v: &str) -> bool {
    false
}

let x="hello world";
foo(&&&&x);
Run Code Online (Sandbox Code Playgroud)

这是社区的普遍共识吗?

terminology dereference rust

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

在Rust中,引用如何成为指向指针的指针?

今天的Rust之谜来自The Rust Programming Language,第一版的第4.9节.引用和借用的示例有这个例子:

fn main() {
    fn sum_vec(v: &Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }

    fn foo(v1: &Vec<i32>) -> i32 {
        sum_vec(v1);
    }

    let v1 = vec![1, 2, 3];

    let answer = foo(&v1);
    println!("{}", answer);
}
Run Code Online (Sandbox Code Playgroud)

这看似合理.它打印出"6",这是你所期望如果 vsum_vec是一个C++参考; 它只是一个内存位置的名称,v1我们定义的向量main().

然后我sum_vec用这个替换了身体:

fn sum_vec(v: &Vec<i32>) -> i32 {
    return (*v).iter().fold(0, |a, &b| a + b);
}
Run Code Online (Sandbox Code Playgroud)

它按预期编译和工作.好吧,那不是......完全疯了.编译器试图让我的生活更轻松,我明白了.令人困惑的是,我必须记住这个语言的特定时态,但并不完全是疯狂的.然后我尝试了:

fn sum_vec(v: &Vec<i32>) -> i32 {
    return (**v).iter().fold(0, |a, &b| …
Run Code Online (Sandbox Code Playgroud)

rust

8
推荐指数
1
解决办法
414
查看次数

为什么忽略“按特征发送”实现的特征范围?

为什么Send在特征实现中忽略自动特征的特征边界?(游乐场(1)

trait IsSend {
    fn is_send(&self);
}

impl<T: Send> IsSend for T {
    fn is_send(&self) {}
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let i = std::rc::Rc::new(43);
    i.is_send(); // (!!) no compiler error although Rc<...> is not Send
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

例如,使用绑定到自定义特征(X)的特征可以工作:(Playground(2)

trait X {}

trait IsSend {
    fn is_send(&self);
}

impl<T: X> IsSend for T {
    fn is_send(&self) {}
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let i = std::rc::Rc::new(43);
    i.is_send(); // …
Run Code Online (Sandbox Code Playgroud)

generics dereference rust

8
推荐指数
1
解决办法
68
查看次数

参考模式如何出现两次取消引用?

有人可以解释一下,根据匹配人体工程学规则(RFC 2005) ,在参考模式中使用单个值如何出现 两次取消引用匹配值的情况?&

例子

假设我们有一个map: HashMap<i32, bool>. 考虑表达式map.iter().filter(|entry| ...),其中 的类型entry&(&i32, &bool)entry现在,如果我们通过以下两种方式进行模式匹配会怎么样?

map
    .iter()
    .filter(|entry| {
        let (key1, _) = entry;   // typeof(key1) -> &&i32
        let (&key2, _) = entry;  // typeof(key2) -> i32
    })
Run Code Online (Sandbox Code Playgroud)

据我了解,这两种模式都使用非引用模式匹配引用(对元组),因此将默认绑定模式更改为ref. 但令我困惑的是 类型key2最终是 asi32和 not &i32

根据 RFC 2005,这里尝试编写上述两种模式的脱糖模式:

let &(ref key1_desugared, _) = entry;    // typeof(key1_desugared) -> &&i32
let &(& ref key2_desugared, _) …
Run Code Online (Sandbox Code Playgroud)

rust

7
推荐指数
1
解决办法
141
查看次数

为什么Rust没有deref && String to && str?

这段代码:

fn main() {
    let s = "hello".to_string();
    let keywords = vec!["hello", "bye"];

    // if keywords.contains(&s.as_str())
    if keywords.contains(&&s)
    // ~> expected &&str, found &collections::string::String
    {
        println!("exists");
    }
}
Run Code Online (Sandbox Code Playgroud)

通常,当函数期望&str类型时,你可以给一个String

let s = "abc".to_string();
foo(&s); // ok,
Run Code Online (Sandbox Code Playgroud)

但是&&s不DEREF来&&str,我认为这是不一致的.

string rust

6
推荐指数
0
解决办法
402
查看次数