< 返回版块

FreeWong 发表于 2019-09-22 12:39

largest函数的参数 list 明明是一个由 i32 元素组成的 slice.

这个调用 largest(&number_list),number_list 是一个 Vec, &number_list 是一个 Vec 的引用,具体到这里就是 &std::vec::Vec 为什么这里编译没有任何问题 从来没有任何解释为什么这里没有任何问题

fn largest(list: &[i32]) -> i32 {
    let mut largest = list[0];

    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest(&number_list);
    println!("The largest number is {}", result);
    
}

评论区

写评论
linjio 2019-09-23 14:51

对以下内容的回复:

并不是吧, 这个说法有误导性. Slice就是Slice, 不过是Vec实现了Deref<Target=Slice>

说的有理,确实有一定的误导性,我从内存的角度来解释一下, Vec和Slice它们都是一块连续的内存,具有共性,因此可用相同的方法给访问它,而Deref/AsRef是这种共性的实现形式。

再次声明,如果从语言的角度来看,它是不一样的东西,不好意思了。

shaitao 2019-09-23 13:43

对以下内容的回复:

并不是吧, 这个说法有误导性. Slice就是Slice, 不过是Vec实现了Deref<Target=Slice>

linjio 2019-09-23 10:48

最近也在学习Rust,个人觉得&Vec 和Slice 是一个东西, 都可以写成:s[a..b]这样的形式, &Vec可以特别看成Vec[..]。

shaitao 2019-09-23 10:39

Deref啊, 包括&String转为&str也是, 老哥没看全教程吧.

cnrust 2019-09-22 22:12

查看说明:https://doc.rust-lang.org/book/ch15-02-deref.html

标准库实现了类型vec的the Deref trait。

摘要:“Deref coercion allows Rust to handle these conversions for us automatically. When the Deref trait is defined for the types involved, Rust will analyze the types and use Deref::deref as many times as necessary to get a reference to match the parameter’s type.“

Nugine 2019-09-22 17:54

========老哥没看完教程吧=========

spqchk 2019-09-22 15:06

函数或方法的解引用强制多态

解引用强制多态是Rust表现在函数或方法传参的一种便利机制。其将实现了Deref的类型的引用转换为Deref所能够转换的类型的引用。当这种类型的引用作为实参传递给和形参类型不同的函数或方法时,解引用强制多态会自动发生。这时会有一系列的deref方法被调用,把我们提供的类型转换成参数所需的类型。

你这里的调用会被编译器转换为:let result = largest((&number_list).deref());

标准库中Vec的Deref定义:

```Rust
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Deref for Vec<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self.as_ptr(), self.len)
        }
    }
}
```
chirsz-ever 2019-09-22 14:44

楼上说的不对吧,这是Deref trait 的功效,Vec<T> 实现了 Deref<Target=[T]>,所以该用 &[T] 的地方可以用 &Vec<T>

Ryan-Git 2019-09-22 14:21

类似 c++ 的隐式转换,rust 的方式是实现特定接口。比如这里就是楼上说的 AsRef。

songzhi 2019-09-22 12:59
// rust/src/liballoc/vec.rs:2268
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> AsRef<[T]> for Vec<T> {
    fn as_ref(&self) -> &[T] {
        self
    }
}
1 共 10 条评论, 1 页