如何修复在使用泛型字段时出现的“lifetime parameter is never used”问题?

5
以下代码会产生错误:
struct IntParseVisitor<'de, V: Visitor<'de>> {
    inner_visitor: V,
}

pub trait Visitor<'de>: Sized {
    fn visit_str<E>(self, v: &'de str) {}
}

error[E0392]: parameter `'de` is never used
 --> src/lib.rs:1:24
  |
1 | struct IntParseVisitor<'de, V: Visitor<'de>> {
  |                        ^^^ unused parameter
  |
  = help: consider removing `'de`, referring to it in a field, or using a marker such as `std::marker::PhantomData`

我不太理解它为什么没被使用。它难道对于 Visitor<'de> 不适用吗?修复的最佳方式是什么?请注意,我不能更改 Visitor 的代码,因为它在 Serde 中。


struct IntParseVisitor<'de, V: Visitor<'_>> { inner_visitor: V, } 可以使用建议的 PhantomData。 - Netwave
看起来你的问题可能已经在How does for<> syntax differ from a regular lifetime bound?的答案中得到了解答。如果不是,请**[编辑]**你的问题以解释区别。否则,我们可以将此问题标记为已回答。 - Shepmaster
1
实际上,那个答案没有提供足够的信息来让 for<> 在我的实际代码中工作,而 PhantomData 确实起作用了,所以我不认为它是一个重复的问题。此外,那个答案是关于函数的通用参数,不清楚它如何适用于结构体。请在将来关闭问题时给予更多的怀疑之处,谢谢。 - Timmmm
2个回答

4
啊,感谢@Shepmaster的提示,我尝试了这个,它可以编译通过:
struct IntParseVisitor<V: for<'de> Visitor<'de>> {
    inner_visitor: V,
}

pub trait Visitor<'de>: Sized {
    fn visit_str<E>(self, v: &'de str)
    {
    }
}

我对这里的生命周期并不完全理解,所以不要只听我的话。


1
你可以按照错误提示进行操作:

建议:考虑删除'de,在字段中引用它,或使用std::marker::PhantomData等标记。

struct IntParseVisitor<'de, V: Visitor<'de>> {
    inner_visitor: V,
    _phantom_data: std::marker::PhantomData<&'de ()>,
}

这个与我的代码一起工作,所以我认为这是最好的答案。当我尝试将 for<'de>serde::de::Visitor::Type 关联类型一起使用时,它并没有起作用。谢谢! - Timmmm
我的直觉可能是错误的,但 PhantomData<fn(&'de ())> 更正确。Visitor 的语义是一个以 'de 为参数的函数。Trait 实际上没有变异性,但如果有的话,那就是逆变的。使用协变的 PhantomData 可能会人为地限制 IntParseVisitor 的使用。 (但更有可能的是,HRTB 才是实际期望的解决方案。) - trent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接