通用的特性,适用于所有实现iter()的容器。

huangapple go评论77阅读模式
英文:

Generic trait for all containers implementing iter()

问题

抱歉,您提供的代码有一些问题,需要做一些更改才能使其正常工作。以下是修复后的代码:

  1. trait Monotonic<'a, T: 'a + ?Sized> {
  2. fn is_monotonic(&mut self) -> bool {
  3. return true;
  4. }
  5. }
  6. impl<'a, T: 'a + ?Sized, C> Monotonic<'a, T> for C
  7. where C: IntoIterator<Item=&'a T> + ?Sized {}
  8. fn main() {
  9. let v = vec![1u32, 2u32, 3u32];
  10. if v.is_monotonic() {
  11. print!("Is monotonic!");
  12. }
  13. }

您的问题是关于类型边界和生命周期的问题。在 IntoIterator 的实现中,Item 的生命周期应该与 trait 的生命周期 'a 一致。此外,您的 print! 宏应该使用单引号 ' 而不是双引号 "

经过这些更改,您的代码应该能够正常工作。这个修复解决了编译器报告的问题。希望这有所帮助!

英文:

I'm trying to implement a trait for all containers that implement iter(), ie. for all containers that provide an IntoIterator&lt;Item=&amp;&#39;a T&gt;. I've tried this, but unfortunately, even for the simplest case it is failing. Maybe someone knows what I'm doing wrong?

  1. trait Monotonic&lt;&#39;a, T: &#39;a + ?Sized&gt; {
  2. fn is_monotonic(&amp;mut self) -&gt; bool {
  3. return true;
  4. }
  5. }
  6. impl&lt;&#39;a, T: &#39;a + ?Sized, C&gt; Monotonic&lt;&#39;a, T&gt; for C
  7. where C: IntoIterator&lt;Item=&amp;&#39;a T&gt; + ?Sized {}
  8. fn main() {
  9. let v = vec![1u32, 2u32, 3u32];
  10. if v.is_monotonic() {
  11. print!(&quot;Is monotonic!&quot;);
  12. }
  13. }

The compiler complains about not satisfied bounds:

  1. error[E0599]: the method `is_monotonic` exists for struct `Vec&lt;u32&gt;`, but its trait bounds were not satisfied
  2. --&gt; src/test.rs:13:10
  3. |
  4. 13 | if v.is_monotonic() {
  5. | ^^^^^^^^^^^^ method cannot be called on `Vec&lt;u32&gt;` due to unsatisfied trait bounds
  6. --&gt; /rustc/fc594f15669680fa70d255faec3ca3fb507c3405/library/alloc/src/vec/mod.rs:400:1
  7. |
  8. | = note: doesn&#39;t satisfy `&lt;Vec&lt;u32&gt; as IntoIterator&gt;::Item = &amp;_`
  9. = note: doesn&#39;t satisfy `Vec&lt;u32&gt;: Monotonic&lt;&#39;_, _&gt;`
  10. |
  11. note: trait bound `[u32]: IntoIterator` was not satisfied
  12. --&gt; src/test.rs:8:10
  13. |
  14. 7 | impl&lt;&#39;a, T: &#39;a + ?Sized, C&gt; Monotonic&lt;&#39;a, T&gt; for C
  15. | ---------------- -
  16. 8 | where C: IntoIterator&lt;Item=&amp;&#39;a T&gt; + ?Sized {}
  17. | ^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
  18. note: the following trait bounds were not satisfied:
  19. `&lt;Vec&lt;u32&gt; as IntoIterator&gt;::Item = &amp;_`
  20. `&lt;[u32] as IntoIterator&gt;::Item = &amp;_`
  21. --&gt; src/test.rs:8:23
  22. |
  23. 7 | impl&lt;&#39;a, T: &#39;a + ?Sized, C&gt; Monotonic&lt;&#39;a, T&gt; for C
  24. | ---------------- -
  25. 8 | where C: IntoIterator&lt;Item=&amp;&#39;a T&gt; + ?Sized {}
  26. | ^^^^^^^^^^ unsatisfied trait bound introduced here
  27. error: aborting due to previous error
  28. For more information about this error, try `rustc --explain E0599`.

I've already tried to solve this on my own, but after several attempts I'm at a point where some help would be highly appreciated!

答案1

得分: 2

根据其文档Vec&lt;T&gt; 实现以下 IntoIterator 特质:

  • IntoIterator&lt;Item = &amp;&#39;a T&gt; for &amp;&#39;a Vec&lt;T, A&gt;
  • IntoIterator&lt;Item = &amp;&#39;a mut T&gt; for &amp;&#39;a mut Vec&lt;T, A&gt;
  • IntoIterator&lt;Item = T&gt; for Vec&lt;T, A&gt;

你正在调用它的变量 v 是一个 Vec&lt;u32&gt;,它只实现了 IntoIterator&lt;Item = u32&gt;,而不是任何与你的特质需要的 &amp;&#39;a u32 相关的内容。

有几种解决方法。第一种是在 &amp;v 上运行代码:

  1. trait Monotonic&lt;&#39;a, T: &#39;a + ?Sized&gt; {
  2. fn is_monotonic(&amp;mut self) -&gt; bool {
  3. return true;
  4. }
  5. }
  6. impl&lt;&#39;a, T: &#39;a + ?Sized, C&gt; Monotonic&lt;&#39;a, T&gt; for C where C: IntoIterator&lt;Item = &amp;&#39;a T&gt; + ?Sized {}
  7. fn main() {
  8. let v = vec![1u32, 2u32, 3u32];
  9. if (&amp;v).is_monotonic() {
  10. print!(&quot;Is monotonic!&quot;);
  11. }
  12. }

尽管这可能不是你想要的,因为我从你的问题中了解到你想要你的 Monotonic 特质尽可能通用地实现。为此,只需删除 &amp; 要求:

  1. trait Monotonic&lt;&#39;a, T: &#39;a + ?Sized&gt; {
  2. fn is_monotonic(&amp;mut self) -&gt; bool {
  3. return true;
  4. }
  5. }
  6. impl&lt;&#39;a, T: &#39;a + ?Sized, C&gt; Monotonic&lt;&#39;a, T&gt; for C where C: IntoIterator&lt;Item = T&gt; + ?Sized {}
  7. fn main() {
  8. let mut v = vec![1u32, 2u32, 3u32];
  9. if v.is_monotonic() {
  10. print!(&quot;Is monotonic!&quot;);
  11. }
  12. }

关于你当前的代码结构,有几点需要注意:

  • 尽管这在技术上可以编译,但将无法实现你的函数。IntoIterator 消耗 你调用它的对象,但你的 is_monotonic 函数只能对其进行 &amp;mut 访问,所以你将无法在这里调用 into_iter

    你可能希望的是让 is_monotonic 消耗 这个值,然后仅为 &amp;T 实现它。

  • 你的 Monotonic 函数不需要任何泛型参数,因此请将它们删除。

  1. trait Monotonic {
  2. fn is_monotonic(self) -&gt; bool;
  3. }
  4. impl&lt;&#39;a, T, C&gt; Monotonic for &amp;&#39;a C
  5. where
  6. &amp;&#39;a C: IntoIterator&lt;Item = T&gt;,
  7. {
  8. fn is_monotonic(self) -&gt; bool {
  9. let mut iter = self.into_iter();
  10. // 对迭代器进行某些操作
  11. let x = iter.next().unwrap();
  12. // 返回结果
  13. true
  14. }
  15. }
  16. fn main() {
  17. let v = vec![1u32, 2u32, 3u32];
  18. if v.is_monotonic() {
  19. print!(&quot;Is monotonic!&quot;);
  20. }
  21. }

这是一个假设 is_monotonic 是指单调递增的示例实现:

  1. trait Monotonic {
  2. fn is_monotonic(self) -&gt; bool;
  3. }
  4. impl&lt;&#39;a, T, C&gt; Monotonic for &amp;&#39;a C
  5. where
  6. &amp;&#39;a C: IntoIterator&lt;Item = T&gt;,
  7. T: PartialOrd,
  8. {
  9. fn is_monotonic(self) -&gt; bool {
  10. let mut iter = self.into_iter();
  11. if let Some(first) = iter.next() {
  12. let mut previous = first;
  13. for next in iter {
  14. if !next.ge(&amp;previous) {
  15. return false;
  16. }
  17. previous = next;
  18. }
  19. true
  20. } else {
  21. // 没有元素的迭代器是单调的。
  22. // 尽管这可能是一个哲学上的争论。
  23. true
  24. }
  25. }
  26. }
  27. fn main() {
  28. let v = vec![1u32, 2u32, 3u32];
  29. if v.is_monotonic() {
  30. println!(&quot;Is monotonic!&quot;);
  31. }
  32. println!(&quot;{:?}&quot;, v);
  33. }
  1. Is monotonic!
  2. [1, 2, 3]
英文:

According to its documentation, Vec&lt;T&gt; implements the following IntoIterator traits:

  • IntoIterator&lt;Item = &amp;&#39;a T&gt; for &amp;&#39;a Vec&lt;T, A&gt;
  • IntoIterator&lt;Item = &amp;&#39;a mut T&gt; for &amp;&#39;a mut Vec&lt;T, A&gt;
  • IntoIterator&lt;Item = T&gt; for Vec&lt;T, A&gt;

The variable v you are calling it on is a Vec&lt;u32&gt;, which only implements IntoIterator&lt;Item = u32&gt;, and not any kind of &amp;&#39;a u32 as your trait requires.

There are a couple of solutions. The first one is to run the code on &amp;v:

  1. trait Monotonic&lt;&#39;a, T: &#39;a + ?Sized&gt; {
  2. fn is_monotonic(&amp;mut self) -&gt; bool {
  3. return true;
  4. }
  5. }
  6. impl&lt;&#39;a, T: &#39;a + ?Sized, C&gt; Monotonic&lt;&#39;a, T&gt; for C where C: IntoIterator&lt;Item = &amp;&#39;a T&gt; + ?Sized {}
  7. fn main() {
  8. let v = vec![1u32, 2u32, 3u32];
  9. if (&amp;v).is_monotonic() {
  10. print!(&quot;Is monotonic!&quot;);
  11. }
  12. }

Although that's probably not what you want, because I read from your question that you want your Monotonic trait to be implemented as generically as possible. For that, simply remove the &amp; requirement:

  1. trait Monotonic&lt;&#39;a, T: &#39;a + ?Sized&gt; {
  2. fn is_monotonic(&amp;mut self) -&gt; bool {
  3. return true;
  4. }
  5. }
  6. impl&lt;&#39;a, T: &#39;a + ?Sized, C&gt; Monotonic&lt;&#39;a, T&gt; for C where C: IntoIterator&lt;Item = T&gt; + ?Sized {}
  7. fn main() {
  8. let mut v = vec![1u32, 2u32, 3u32];
  9. if v.is_monotonic() {
  10. print!(&quot;Is monotonic!&quot;);
  11. }
  12. }

Couple of remarks concerning your current code structure, though:

  • While this technically compiles, it won't be possible to implement your function. IntoIterator consumes the object you call it on, but your is_monotonic function only has &amp;mut access to it, so you won't ever be able to call into_iter here.

    What you probably want instead is to have is_monotonic consume the value, but then only implement it for &amp;T.

  • Your Monotonic function doesn't require any generic parameters, so remove them.

  1. trait Monotonic {
  2. fn is_monotonic(self) -&gt; bool;
  3. }
  4. impl&lt;&#39;a, T, C&gt; Monotonic for &amp;&#39;a C
  5. where
  6. &amp;&#39;a C: IntoIterator&lt;Item = T&gt;,
  7. {
  8. fn is_monotonic(self) -&gt; bool {
  9. let mut iter = self.into_iter();
  10. // Do something with iter
  11. let x = iter.next().unwrap();
  12. // Return result
  13. true
  14. }
  15. }
  16. fn main() {
  17. let v = vec![1u32, 2u32, 3u32];
  18. if v.is_monotonic() {
  19. print!(&quot;Is monotonic!&quot;);
  20. }
  21. }

Here is an example implementation of is_monotonic, assuming it means monotonic rising:

  1. trait Monotonic {
  2. fn is_monotonic(self) -&gt; bool;
  3. }
  4. impl&lt;&#39;a, T, C&gt; Monotonic for &amp;&#39;a C
  5. where
  6. &amp;&#39;a C: IntoIterator&lt;Item = T&gt;,
  7. T: PartialOrd,
  8. {
  9. fn is_monotonic(self) -&gt; bool {
  10. let mut iter = self.into_iter();
  11. if let Some(first) = iter.next() {
  12. let mut previous = first;
  13. for next in iter {
  14. if !next.ge(&amp;previous) {
  15. return false;
  16. }
  17. previous = next;
  18. }
  19. true
  20. } else {
  21. // An iterator without elements is monotonic.
  22. // Although that&#39;s probably up for philosophical debate.
  23. true
  24. }
  25. }
  26. }
  27. fn main() {
  28. let v = vec![1u32, 2u32, 3u32];
  29. if v.is_monotonic() {
  30. println!(&quot;Is monotonic!&quot;);
  31. }
  32. println!(&quot;{:?}&quot;, v);
  33. }
  1. Is monotonic!
  2. [1, 2, 3]

huangapple
  • 本文由 发表于 2023年2月18日 19:20:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75492981.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定