< 返回版块

tavel 发表于 2021-06-02 15:40

println!("{}", left[x][j]);改为println!("{}", left[0][j]);就可以正常编过,迷惑


Ext Link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1e5da4af929890a33880049f72333d4f

评论区

写评论
作者 tavel 2021-06-03 09:12

感谢~

--
👇
fefit: 间接类似的这种issue好像还挺多, https://github.com/rust-lang/rust/issues/76112,这种依赖强推导的可能还是尽量避免比较好~

fefit 2021-06-02 22:18

间接类似的这种issue好像还挺多, https://github.com/rust-lang/rust/issues/76112,这种依赖强推导的可能还是尽量避免比较好~

作者 tavel 2021-06-02 21:31

感谢各位!估计是x的类型没有推断出来导致left[x]的类型信息也没有推断出来。(但为什么报错的时候又能打印出类型

作者 tavel 2021-06-02 19:31

谢谢!我感觉这里应该是推出来的x的类型的,看这个例子

--
👇
fefit: 插件里的确可以推断出来,但rust编译通过不了,说明插件和rust编译器并没有完全保持逻辑上的一致。感觉rust编译器可能为了保证效率,如果stackpush操作没有出现在取元素x之前,stack的元素类型就是未知的。如果要能正确推断,编译器在这里可能要停止解析继续向下搜索直到获取到stack内的元素信息为止,然后再回到上一次的停止点,这应该很影响编译效率。当然这只是个人的猜想啦,不管如何,碰到这种情况还是多敲点代码把类型信息写上,或许还能编译得快一点。

作者 tavel 2021-06-02 19:28

谢谢!我又试了一下,把println!("{}", left[x][j]);改为了println!("{:?}", left[x]);,发现居然能编过(https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=68aa09511b10c1e368a1e022b1f5679f)。所以这里编译器推不出来的应该是left[x]?(但我觉得不应该啊,

--
👇
Aya0wind: 我用vscode的ra是显示无法推断的。理论上确实是可以推断的,可能是Clion的分析工具可以做到,但是编译器暂时还做不到。你这里left[x][y],要推断其返回值类型用于print,首先要推导x的类型,然后x的类型又要由i推导,应该是编译器还不支持这种推导的类型要依赖另一个需要推导的类型的情况。

--
👇
tavel: 谢谢!但我还有一迷惑的地方: 按照我的理解,根据这条语句stack.push(i);应该是可以推断出stack的类型的(CLion里也确实推断出了x是usize)。然后我又把println!("{}", left[x][j]);这里修改为println!("{}", x + "");,然后编译器报错no implementation for usize + &str,所以我认为这里应该是推断出了x的类型的。请问是我的理解有问题吗?

--
👇
Aya0wind: 推断不出x的类型,你指定一下Vec的泛型参数即可。

let mut stack = Vec::<usize>::new();
fefit 2021-06-02 18:34

插件里的确可以推断出来,但rust编译通过不了,说明插件和rust编译器并没有完全保持逻辑上的一致。感觉rust编译器可能为了保证效率,如果stackpush操作没有出现在取元素x之前,stack的元素类型就是未知的。如果要能正确推断,编译器在这里可能要停止解析继续向下搜索直到获取到stack内的元素信息为止,然后再回到上一次的停止点,这应该很影响编译效率。当然这只是个人的猜想啦,不管如何,碰到这种情况还是多敲点代码把类型信息写上,或许还能编译得快一点。

Aya0wind 2021-06-02 18:10

又试了一下确实可以推断,不过还是过不了编译。

--
👇
苦瓜小仔: RA 可以推断啊,你是不没更新。注释的地方就是 RA 推断的。

pub fn maximal_rectangle(matrix: Vec<Vec<char>>) -> i32 {
    let (m, n) = (matrix.len(), matrix[0].len()); // m: usize // n: usize
    let left: Vec<Vec<i32>> = vec![vec![0; n]; m];

    for j in 0..n { // j: usize
        let mut stack = Vec::new(); // mut stack: Vec<usize>

        for i in 0..m { // i: usize
            while let Some(&x) = stack.last() { // x: usize
                println!("{}", left[x][j]);
            }
            stack.push(i);
        }
    }
    0
}

fn main() {}

--
👇
Aya0wind: 我用vscode的ra是显示无法推断的。理论上确实是可以推断的,可能是Clion的分析工具可以做到,但是编译器暂时还做不到。你这里left[x][y],要推断其返回值类型用于print,首先要推导x的类型,然后x的类型又要由i推导,应该是编译器还不支持这种推导的类型要依赖另一个需要推导的类型的情况。

--
👇
tavel: 谢谢!但我还有一迷惑的地方: 按照我的理解,根据这条语句stack.push(i);应该是可以推断出stack的类型的(CLion里也确实推断出了x是usize)。然后我又把println!("{}", left[x][j]);这里修改为println!("{}", x + "");,然后编译器报错no implementation for usize + &str,所以我认为这里应该是推断出了x的类型的。请问是我的理解有问题吗?

--
👇
Aya0wind: 推断不出x的类型,你指定一下Vec的泛型参数即可。

let mut stack = Vec::<usize>::new();
苦瓜小仔 2021-06-02 17:51

RA 可以推断啊,你是不没更新。注释的地方就是 RA 推断的。

pub fn maximal_rectangle(matrix: Vec<Vec<char>>) -> i32 {
    let (m, n) = (matrix.len(), matrix[0].len()); // m: usize // n: usize
    let left: Vec<Vec<i32>> = vec![vec![0; n]; m];

    for j in 0..n { // j: usize
        let mut stack = Vec::new(); // mut stack: Vec<usize>

        for i in 0..m { // i: usize
            while let Some(&x) = stack.last() { // x: usize
                println!("{}", left[x][j]);
            }
            stack.push(i);
        }
    }
    0
}

fn main() {}

--
👇
Aya0wind: 我用vscode的ra是显示无法推断的。理论上确实是可以推断的,可能是Clion的分析工具可以做到,但是编译器暂时还做不到。你这里left[x][y],要推断其返回值类型用于print,首先要推导x的类型,然后x的类型又要由i推导,应该是编译器还不支持这种推导的类型要依赖另一个需要推导的类型的情况。

--
👇
tavel: 谢谢!但我还有一迷惑的地方: 按照我的理解,根据这条语句stack.push(i);应该是可以推断出stack的类型的(CLion里也确实推断出了x是usize)。然后我又把println!("{}", left[x][j]);这里修改为println!("{}", x + "");,然后编译器报错no implementation for usize + &str,所以我认为这里应该是推断出了x的类型的。请问是我的理解有问题吗?

--
👇
Aya0wind: 推断不出x的类型,你指定一下Vec的泛型参数即可。

let mut stack = Vec::<usize>::new();
Aya0wind 2021-06-02 17:09

我用vscode的ra是显示无法推断的。理论上确实是可以推断的,可能是Clion的分析工具可以做到,但是编译器暂时还做不到。你这里left[x][y],要推断其返回值类型用于print,首先要推导x的类型,然后x的类型又要由i推导,应该是编译器还不支持这种推导的类型要依赖另一个需要推导的类型的情况。

--
👇
tavel: 谢谢!但我还有一迷惑的地方: 按照我的理解,根据这条语句stack.push(i);应该是可以推断出stack的类型的(CLion里也确实推断出了x是usize)。然后我又把println!("{}", left[x][j]);这里修改为println!("{}", x + "");,然后编译器报错no implementation for usize + &str,所以我认为这里应该是推断出了x的类型的。请问是我的理解有问题吗?

--
👇
Aya0wind: 推断不出x的类型,你指定一下Vec的泛型参数即可。

let mut stack = Vec::<usize>::new();
作者 tavel 2021-06-02 16:33

谢谢!但我还有一迷惑的地方: 按照我的理解,根据这条语句stack.push(i);应该是可以推断出stack的类型的(CLion里也确实推断出了x是usize)。然后我又把println!("{}", left[x][j]);这里修改为println!("{}", x + "");,然后编译器报错no implementation for usize + &str,所以我认为这里应该是推断出了x的类型的。请问是我的理解有问题吗?

--
👇
Aya0wind: 推断不出x的类型,你指定一下Vec的泛型参数即可。

let mut stack = Vec::<usize>::new();
Aya0wind 2021-06-02 16:02

推断不出x的类型,你指定一下Vec的泛型参数即可。

let mut stack = Vec::<usize>::new();
1 共 11 条评论, 1 页