我正在尝试创建一个对通用数字类型的特征抽象。指定我希望特征需要T
(即T:Add
但是,当我尝试为
简化示例
use std::ops::Add;
trait Numeric where
Self: Sized,
// T + T
Self: Add<Output = Self>,
// T + &T
Self: for<'a> Add<&'a Self, Output = Self>,
// &T + T
// should specify &T + T on this trait but instead causes compile
// errors everywhere I try to use Numeric claiming no implementation
// for &T + T
// for<'a> &'a Self: Add<Self, Output = Self>,
// &T + &T
// should specify &T + &T on this trait but instead causes compile
// errors everywhere I try to use Numeric claiming no implementation
// for &T + &T
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
{}
impl <T> Numeric for T where
// T + T
T: Add<Output = Self>
+ Sized,
// T + &T
for<'a> T: Add<&'a T, Output = T>,
// &T + T
for<'a> &'a T: Add<T, Output = T>,
// &T + &T
for<'a, 'b> &'a T: Add<&'b T, Output = T>,
{}
// works
fn generic_add_0<T: Numeric>(a: T, b: T) -> T {
a + b
}
// works
fn generic_add_1<T: Numeric>(a: T, b: &T) -> T {
a + b
}
// doesn't infer &T + T from the trait?
fn generic_add_2<T: Numeric>(a: &T, b: T) -> T {
a + b
}
// doesn't infer &T + &T from the trait?
fn generic_add_3<T: Numeric>(a: &T, b: &T) -> T {
a + b
}
// works
fn generic_add_4<T: Numeric>(a: &T, b: &T) -> T
// I want to not have to specify this every time I use Numeric,
// I want Numeric to imply this constraint for me
where for<'a, 'b> &'a T: Add<&'b T, Output = T> {
a + b
}
fn main() {
generic_add_0(1.0, 2.0);
generic_add_1(1.0, &2.0);
generic_add_2(&1.0, 2.0);
generic_add_3(&1.0, &2.0);
generic_add_4(&1.0, &2.0);
}
我想我已经设法回答了我自己的问题,因为我盯着num特性
是如何做到的,并且跟踪和错误了很长一段时间。
我最初示例的这个修改版本创建了两个额外的特性,让您能够非常接近原始目标。尽管您仍然需要where子句,但当您为其他操作添加更多约束时,它的大小不会增加。
use std::ops::Add;
/**
* Trait defining what a numeric type is, in this case just something
* that can be added to a right hand side and yield itself as output
*/
trait NumericByValue<Rhs = Self, Output = Self>: Sized + Add<Rhs, Output = Output> {}
/**
* All types implemeting the by value operations are NumericByValue
*/
impl <T, Rhs, Output> NumericByValue<Rhs, Output> for T where
T: Add<Rhs, Output = Output> {}
/**
* The trait to define &T op T and &T op &T versions for NumericByValue
* based off the MIT/Apache 2.0 licensed code from num-traits 0.2.10
* http://opensource.org/licenses/MIT
* https://docs.rs/num-traits/0.2.10/src/num_traits/lib.rs.html#112
*
* The trick is that all types implementing this trait will be references,
* so the first constraint expresses some &T which can be operated on with
* some right hand side type T to yield a value of type T.
*
* In a similar way the second constraint expresses &T op &T -> T operations
*/
trait NumericRef<T>:
// &T op T -> T
NumericByValue<T, T>
// &T op &T -> T
+ for<'a> NumericByValue<&'a T, T> {}
/**
* All types implementing the operations from NumericByValue by reference,
* are NumericRef<T>, ie a type like &u8 is NumericRef<u8>.
*/
impl <RefT, T> NumericRef<T> for RefT where
RefT: NumericByValue<T, T>
+ for<'a> NumericByValue<&'a T, T> {}
/**
* A trait extending the constraints in NumericByValue to
* types which also support the operations with a right hand side type
* by reference.
*
* When used together with NumericRef this can express all 4 by value
* and by reference combinations for the operations using the
* following
*
* ```ignore
* fn function_name<T: Numeric>()
* where for<'a> &'a T: NumericRef<T> {
* ```
*/
trait Numeric: NumericByValue + for<'a> NumericByValue<&'a Self> {}
/**
* All types implemeting the operations in NumericByValue with a right hand
* side type by reference are Numeric.
*/
impl <T> Numeric for T where T: NumericByValue + for<'a> NumericByValue<&'a T> {}
fn generic_add_0<T: Numeric>(a: T, b: T) -> T
where for<'a> &'a T: NumericRef<T> {
a + b
}
fn generic_add_1<T: Numeric>(a: T, b: &T) -> T
where for<'a> &'a T: NumericRef<T> {
a + b
}
fn generic_add_2<T: Numeric>(a: &T, b: T) -> T
where for<'a> &'a T: NumericRef<T> {
a + b
}
fn generic_add_3<T: Numeric>(a: &T, b: &T) -> T
where for<'a> &'a T: NumericRef<T> {
a + b
}
fn main() {
generic_add_0(1.0, 2.0);
generic_add_1(1.0, &2.0);
generic_add_2(&1.0, 2.0);
generic_add_3(&1.0, &2.0);
}
我有一个有界泛型类,我们称之为泛型,它的参数T扩展了抽象类abstract: 泛型类: 抽象类 泛型类中T引用的类 当尝试引用方法 getMap() 时,该方法来自 T 边界内的类(并且根据抽象类定义,T 的所有可能实例都将具有该方法),我收到以下错误: 不能从静态上下文引用非静态方法getMap() 然而,任何地方都没有静态关键字。我错过了什么?? 谢谢!
我试图实现一个接受泛型参数的函数定义,只要它扩展了另一个特定的泛型类型。简言之参数A必须扩展参数B,其中A和B都是泛型的。 下面是我的示例 用法示例如下 一些封闭的班级 和函数调用 我不想在抽象类声明中定义E,因为T已经在那里定义了。 我也试着做了以下几点: 将myList定义为接受扩展T的键 将E定义为T类型(无法找到如何指定它在函数中扩展T 但它从来都不起作用。有没有办法做到这一点?我在Sta
我正在尝试有一个通量通用转换器使用通用类型在Java 8。我把我的代码建立在这个答案的基础上。其思想基本上是实现这个特定的转换器->: 类型转换器->转换为我想要的任何类型。因此,我正在使用构造函数创建一个类型为的类,并返回一个方法。我想在调用上创建类似这样的多个条目:,但类类型不同。但它甚至对整数也不起作用。 当我使用此单元测试进行测试时,我得到错误:。
我有大约40个API,它们具有类似的基本响应结构,如下所示: 因此,我有一个基本响应类,采用T类型的泛型,如下所示: 因此,对于API A,它返回类型为的对象及其自己的字段,我将返回响应作为控制器中的API响应: 在控制器中:响应数据=新响应();ResponseEntity response=新的ResponseEntity 在swagger中有没有一种方法可以递归地指定响应对象的模型?例如,我
我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类
我的目标是为CRUD操作使用一个通用类,这样我就不需要为我的应用程序中的每个域模型实现一个单独的类。 该层还在我的DTO和域模型之间进行转换。 get和delete方法工作正常。但是,如何实现save方法。对于新实体,我需要创建泛型的新实例,并将DTO映射到泛型上。 我的Service类如下所示: