< 返回版块

minstrel1977 发表于 2021-11-11 21:53

Tags:mut

use std::io::Read;

struct MockStream (Vec<u8>);
impl Read for MockStream {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { todo!() }
}
fn handle_stream(mut stream: impl Read) {
    let mut buffer = [0; 1024];
    stream.read(&mut buffer).unwrap();
    // ... 
}
fn main() {
    let ms1 = MockStream(Vec::new());
    handle_stream(ms1);
    // println!("{}", ms1.0.len()); // use after move
    let mut ms2 = MockStream(Vec::new());
    handle_stream(&mut ms2);
    println!("{}", ms2.0.len());
}

评论区

写评论
作者 minstrel1977 2021-11-12 10:04

sorry,还是我看书不认真,也有impl<'a, T> Unpin for &'a mut T where T: 'a + ?Sized 的。谢谢各位的费心帮忙。

--
👇
minstrel1977: 那我能继续追问一下吗,像async fn handle_connection(mut stream: impl Read + Write + Unpin) 这样的签名也能适配传入所有权的参数 或传入 可变引用 这样的参数。如果说Read和Write分别应用了impl<R: Read + ?Sized> Read for &mut R和impl<W: Write + ?Sized> Write for &mut W这两条Implementors,但Unpin应用了哪条Implementor?

--
👇
Bai-Jinlin: R实现了Read,&mut R也实现了Read。 https://doc.rust-lang.org/stable/std/io/trait.Read.html,翻到最下面。

作者 minstrel1977 2021-11-12 09:09

那我能继续追问一下吗,像async fn handle_connection(mut stream: impl Read + Write + Unpin) 这样的签名也能适配传入所有权的参数 或传入 可变引用 这样的参数。如果说Read和Write分别应用了impl<R: Read + ?Sized> Read for &mut R和impl<W: Write + ?Sized> Write for &mut W这两条Implementors,但Unpin应用了哪条Implementor?

--
👇
Bai-Jinlin: R实现了Read,&mut R也实现了Read。 https://doc.rust-lang.org/stable/std/io/trait.Read.html,翻到最下面。

作者 minstrel1977 2021-11-12 08:53

果然,有 impl<R: Read + ?Sized> Read for &mut R 这条,谢谢,终于算是弄明白了

--
👇
Bai-Jinlin: R实现了Read,&mut R也实现了Read。 https://doc.rust-lang.org/stable/std/io/trait.Read.html,翻到最下面。

Aya0wind 2021-11-11 23:03

你试试运行一下这段代码,看看T的类型是不是不一样。

#[derive(Debug)]
struct S;
impl Read for S{
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        unimplemented!()
    }
} 


fn func<T:Read>(stream:T){
    eprintln!("{:?}",std::any::type_name::<T>());
}



fn main() {
    let mut i = S{};
    func(&mut i);
    func(i);
}

--
👇
Aya0wind: 你写成impl Read其实这个函数就是一个泛型函数了,只不过没有显式的泛型参数而已,和写成func<T:Read>(mut stream:T)是等价的,然后你传了个&mut s2,那T自然就推导成&mut Stream。要能变成带所有权的就乱套了,你明明传一个引用,结果给出去的是所有权,这不合理。

--
👇
minstrel1977: 我直觉是那个自动引用和解引用规则起了作用,传入&mut ms2,就被自动解引用为mut ms2。但我又觉得不会这么简单...

--
👇
Aya0wind: 第二次的T推导为&mut MockStream,没有所有权。

Bai-Jinlin 2021-11-11 23:00

R实现了Read,&mut R也实现了Read。 https://doc.rust-lang.org/stable/std/io/trait.Read.html,翻到最下面。

Aya0wind 2021-11-11 22:57

你写成impl Read其实这个函数就是一个泛型函数了,只不过没有显式的泛型参数而已,和写成func<T:Read>(mut stream:T)是等价的,然后你传了个&mut s2,那T自然就推导成&mut Stream。要能变成带所有权的就乱套了,你明明传一个引用,结果给出去的是所有权,这不合理。

--
👇
minstrel1977: 我直觉是那个自动引用和解引用规则起了作用,传入&mut ms2,就被自动解引用为mut ms2。但我又觉得不会这么简单...

--
👇
Aya0wind: 第二次的T推导为&mut MockStream,没有所有权。

作者 minstrel1977 2021-11-11 22:43

我直觉是那个自动引用和解引用规则起了作用,传入&mut ms2,就被自动解引用为mut ms2。但我又觉得不会这么简单...

--
👇
Aya0wind: 第二次的T推导为&mut MockStream,没有所有权。

作者 minstrel1977 2021-11-11 22:38

能指点一下哪里有资料能说明一个函数能生成多个函数签名吗?

--
👇
Grobycn: fn handle_stream(mut stream: impl Read)生成的两个函数签名分别为 fn(mut stream: MockStream) fn(mut stream: &mut MockStream) 第二个不消耗变量的所有权

Aya0wind 2021-11-11 22:33

第二次的T推导为&mut MockStream,没有所有权。

Grobycn 2021-11-11 22:24

fn handle_stream(mut stream: impl Read)生成的两个函数签名分别为 fn(mut stream: MockStream) fn(mut stream: &mut MockStream) 第二个不消耗变量的所有权

1 共 10 条评论, 1 页