< 返回版块

Neutron3529 发表于 2021-03-12 00:44

今天的leetcode,遇到一个问题

我想直接把String变成iter之后传iter,但问题是,我不知道改如何标注iter的类型

fn valid(iter:&mut _)->bool显然通不过编译

但我实在不知道该如何查看iter的类型

一个尝试是,让编译器报错,然而编译器报错如下:

Line 4, Char 43: no field `fuck` on type `std::iter::Filter<std::str::Bytes<'_>, [closure@src/main.rs:4:46: 4:56]>` (solution.rs)
  |
4 |         iter.next() == Some(b'#') || iter.fuck
  |                                           ^^^^ unknown field
error: aborting due to previous error

显然std::iter::Filter<std::str::Bytes<'_>, [closure@src/main.rs:4:46: 4:56]>不是一个能让函数满意的标注

而直接泛型则会报错说:

Line 9, Char 16: binary operation `==` cannot be applied to type `std::option::Option<<T as std::iter::Iterator>::Item>` (solution.rs)
   |
9 |     iter.next()==Some(b',')
   |     -----------^^---------- std::option::Option<u8>
   |     |
   |     std::option::Option<<T as std::iter::Iterator>::Item>
   |
   = note: the trait `std::cmp::PartialEq` is not implemented for `std::option::Option<<T as std::iter::Iterator>::Item>`
error: aborting due to previous error

很好奇如果我想传iter(而不是index),我应该怎么做。

//我的脏到极致的解法:
impl Solution {
    pub fn is_valid_serialization(preorder: String) -> bool {
        let mut iter=preorder.bytes().filter(|&x|x<b'0'); //b','==44,b'#''==35
        valid(&mut iter) && iter.next() == None
    }
}
fn valid<T:Iterator>(iter:&mut T)->bool
  where <T as Iterator>::Item: std::cmp::PartialEq<u8>,
        Option<<T as Iterator>::Item>: std::cmp::PartialEq<Option<u8>>
{
    if let Some(x)=iter.next(){
        x==b'#' ||
            valid(iter) && iter.next() == Some(b',') && valid(iter)
    }else{false}
}

本来或许可以match的,但写了泛型只能if let然后比较了

很想知道这里能否做一些更简单或者更通用的标注方法。

望大神们不吝赐教:)

评论区

写评论
作者 Neutron3529 2021-03-13 15:49

感谢回复

感觉泛型什么的……只能看缘分学一学了

--
👇
johnmave126: 我以前对别的语言的泛型有经验,以前有haskell/C++基础,所以其实是看了看The Book就直接上手的(

--
👇
Neutron3529: 感谢解答

顺便问一句,应该在哪里看泛型有关的教程呢?我rust基本都是用leetcode学的。。

作者 Neutron3529 2021-03-13 15:48

问题是Filter

这并不是标准的Iter,而是过了一遍Filter的Iter,已经不能用Iter这个结构体来描述了。

如果直接标Iter,一定会报错。

--
👇
hzqd: 如果是栈上分配的字符串,则 iter 的类型是 std::slice::Iter<'_, &str>,其中 &str 可以根据情况替换成 String&[u8] 等类型。

johnmave126 2021-03-13 10:25

我以前对别的语言的泛型有经验,以前有haskell/C++基础,所以其实是看了看The Book就直接上手的(

--
👇
Neutron3529: 感谢解答

顺便问一句,应该在哪里看泛型有关的教程呢?我rust基本都是用leetcode学的。。

hzqd 2021-03-13 01:13

如果是栈上分配的字符串,则 iter 的类型是 std::slice::Iter<'_, &str>,其中 &str 可以根据情况替换成 String&[u8] 等类型。

作者 Neutron3529 2021-03-12 12:25

感谢解答

顺便问一句,应该在哪里看泛型有关的教程呢?我rust基本都是用leetcode学的。。

--
👇
johnmave126: 简而言之就是抽象出要用的trait

几个注意点

  • associate type可以做限制,也可以直接指定
  • 函数参数用generics
  • 函数返回值用-> impl TheTraitNeeded

--
👇
johnmave126: 这样?

impl Solution {
    pub fn is_valid_serialization(preorder: String) -> bool {
        let mut it = preorder.split(',');
        Self::chew(&mut it) && it.next().is_none()
    }

    fn chew<'a, T>(it: &mut T) -> bool
    where T: Iterator<Item = &'a str> {
        match it.next() {
            Some("#") => true,
            Some(_) => Self::chew(it) && Self::chew(it),
            _ => false,
        }
    }
}
johnmave126 2021-03-12 02:51

简而言之就是抽象出要用的trait

几个注意点

  • associate type可以做限制,也可以直接指定
  • 函数参数用generics
  • 函数返回值用-> impl TheTraitNeeded

--
👇
johnmave126: 这样?

impl Solution {
    pub fn is_valid_serialization(preorder: String) -> bool {
        let mut it = preorder.split(',');
        Self::chew(&mut it) && it.next().is_none()
    }

    fn chew<'a, T>(it: &mut T) -> bool
    where T: Iterator<Item = &'a str> {
        match it.next() {
            Some("#") => true,
            Some(_) => Self::chew(it) && Self::chew(it),
            _ => false,
        }
    }
}
johnmave126 2021-03-12 02:41

这样?

impl Solution {
    pub fn is_valid_serialization(preorder: String) -> bool {
        let mut it = preorder.split(',');
        Self::chew(&mut it) && it.next().is_none()
    }

    fn chew<'a, T>(it: &mut T) -> bool
    where T: Iterator<Item = &'a str> {
        match it.next() {
            Some("#") => true,
            Some(_) => Self::chew(it) && Self::chew(it),
            _ => false,
        }
    }
}
1 共 7 条评论, 1 页