当前位置: 首页 > 知识库问答 >
问题:

无法创建使用文字零的泛型函数

束高雅
2023-03-14

我正试图编写一个类似于内置范围的Rust函数,但我想要一个只返回X个数字的函数,并将其作为列表返回,这就是为什么我试图创建这个函数:extern crate num;

use num::Integer;

fn positions<T: Integer>(start: T, step: T, len: T) -> Vec<T> {
    (0..len).map(|i| start + step * i).collect()
}

fn main() {
    println!("{:?}", positions(10, 2, 10));
}

除了我收到一个编译器错误:

error[E0308]: mismatched types
 --> src/main.rs:6:9
  |
6 |     (0..len).map(|i| start + step * i).collect()
  |         ^^^ expected integral variable, found type parameter
  |
  = note: expected type `{integer}`
             found type `T`
  = help: here are some functions which might fulfill your needs:
          - .div_floor(...)
          - .gcd(...)
          - .lcm(...)
          - .mod_floor(...)

error[E0308]: mismatched types
 --> src/main.rs:6:37
  |
6 |     (0..len).map(|i| start + step * i).collect()
  |                                     ^ expected type parameter, found integral variable
  |
  = note: expected type `T`
             found type `{integer}`

共有1个答案

薛墨一
2023-03-14

问题是0。我现在还不清楚确切的规则,但让我们概括一下:0是某种特定的整数类型,它可能与T是什么,也可能不是什么。因此,编译器无法计算出范围的类型参数应该是什么。

您可以通过使用Zero::Zero

fn positions<T: Integer>(start: T, step: T, len: T) -> Vec<T> {
    (T::zero()..len).map(|i| start + step * i).collect()
}

这使编译器有足够的余地来推断range的两个参数属于同一类型。但是,这仍然不足以将Range用作迭代器:

error: no method named `map` found for type `std::ops::Range<T>` in the current scope
 --> src/main.rs:8:22
  |
8 |     (T::zero()..len).map(|i| start + step * i).collect()
  |                      ^^^
  |
  = note: the method `map` exists but the following trait bounds were not satisfied: `T : std::iter::Step`, `&'a T : std::ops::Add`, `std::ops::Range<T> : std::iter::Iterator`

不幸的是,从Rust 1.17开始,Steptrait不稳定,因此目前没有使用稳定的Rust解决此问题的好方法。

使用不稳定的Rust,您可能需要Step的实现:

#![feature(step_trait)]

extern crate num;

use num::Integer;

fn positions<T>(start: T, step: T, len: T) -> Vec<T>
    where T: Integer + std::iter::Step + Copy,
          for<'a> &'a T: std::ops::Add<Output = T>
{
    (T::zero()..len).map(|i| start + step * i).collect()
}

fn main() {
    println!("{:?}", positions(10, 2, 10));
}

您还需要要求T可以被复制(或克隆,如果您愿意),因为AddMul的实现按值消耗操作数,这意味着start step*i只能被调用一次,除非需要多次调用。

 类似资料:
  • 使用此类型类将地图转换为case类: 此函数用于隐式获取正确的映射器 它可以用作 但我也希望能够将此函数与 Option[Map[]] 或 Future[Map[]] 或 List[Map[]] 一起使用。所以我使用这样的函子实现了一个泛型函数: 但是现在这个函数必须用作 。 但是,我希望能够将该功能用作 无需指定函子类型。这在某种程度上是可能的吗? Shapeless的懒惰可以用来解决这个问题吗

  • 我试图解析spring Version4.3.6中FactoryBean中的泛型类型。我使用FactoryBean创建bean,该bean用于创建任意数量的CarClient实例。 通过构造函数参数1表示的不满足依赖关系;嵌套异常是org.springframework.beans.factory.nouniqueBeanDefinitionException:没有类型为“com.empire.c

  • 问题内容: 我想创建一个KeyValue类,但以通用方式,这就是我写的内容: 错误显示:“令牌“>上的语法错误”,此令牌后应有标识符” 那我该如何在Java中创建一个通用构造函数呢? 问题答案: 您需要从构造函数的签名中删除:它已经隐式存在。

  • 我希望有一个泛型类(在类型T中),它保存一个可为空的TS列表。 编译失败,出现以下错误。 错误CS0453:类型't'必须是非空值类型,才能将其用作泛型类型或方法'System.Nullable'中的类型参数't' 我做错了什么?

  • 问题内容: 如何创建泛型类型的数组?通用方法如何工作?它返回通用数组的副本。因此可以创建通用数组。但是如何?怎么能写一个类似的方法呢? 问题答案: 如果需要在运行时创建它,则至少需要在此时知道类型,因此可以使用以下方法: where 是泛型类型,是的类,并且是初始大小。 这里的文件

  • 问题内容: 我正在实现一个循环的DoublyLinkedList数据结构。像单链列表一样,双链列表中的节点都有对下一个节点的引用,但是与单链列表不同,双链列表中的节点也有对前一个节点的引用。 另外,由于列表是“循环的”,因此列表中最后一个节点中的“下一个”引用指向列表中的第一个节点,列表中第一个节点中的“上一个”引用指向列表中的最后一个节点名单。 我需要启动我的get方法的帮助,我一直在四处寻找,