给定一个依赖于泛型类型参数的结构,我们可以定义一个实现依赖于该类型的关联函数吗?
我想将结构传递给例程,但根据内部类型,让关联的函数以不同的方式计算。这个例程还取决于结构中的成员,所以我宁愿不把所有东西都移到一个特质上。
例如,以下代码尝试根据所涉及的类型定义不同的printme
函数:
// Trait locked to a type
trait MyF64 {}
impl MyF64 for f64 {}
trait MyU32 {}
impl MyU32 for u32 {}
// Some kind of struct
struct Foo<T> {
t: T,
}
// Implementation for f64
impl<T> Foo<T>
where
T: MyF64,
{
fn printme(&self) {
println!("In a f64: {}", self.t);
}
}
// Implementation for u32
impl<T> Foo<T>
where
T: MyU32,
{
fn printme(&self) {
println!("In a u32: {}", self.t);
}
}
// Takes a foo
fn foo<T>(x: Foo<T>) {
foo.printme();
}
fn main() {
// Try both cases
foo(Foo { t: 1.2 });
foo(Foo { t: 12 });
}
这会导致编译器错误:
error[E0592]: duplicate definitions with name `printme`
--> src/main.rs:17:5
|
17 | / fn printme(&self) {
18 | | println!("In a f64: {}", self.t);
19 | | }
| |_____^ duplicate definitions for `printme`
...
27 | / fn printme(&self) {
28 | | println!("In a u32: {}", self.t);
29 | | }
| |_____- other definition for `printme`
如果我将printme
的定义转移到另一个特征中,我们就会遇到一个类似但不同的问题。
// Trait locked to a type
trait MyF64 {}
impl MyF64 for f64 {}
trait MyU32 {}
impl MyU32 for u32 {}
// Some kind of struct
struct Foo<T> {
t: T,
}
// Trait for Foo
trait FooTrait {
fn printme(&self);
}
// Implementation for f64
impl<T> FooTrait for Foo<T>
where
T: MyF64,
{
fn printme(&self) {
println!("In a f64: {}", self.t);
}
}
// Implementation for u32
impl<T> FooTrait for Foo<T>
where
T: MyU32,
{
fn printme(&self) {
println!("In a u32: {}", self.t);
}
}
// Takes a foo
fn foo<T>(x: Foo<T>)
where
Foo<T>: FooTrait,
{
foo.printme();
}
fn main() {
// Try both cases
foo(Foo { t: 1.2 });
foo(Foo { t: 12 });
}
这会导致编译器错误:
error[E0119]: conflicting implementations of trait `FooTrait` for type `Foo<_>`:
--> src/main.rs:28:1
|
18 | / impl<T> FooTrait for Foo<T>
19 | | where
20 | | T: MyF64,
21 | | {
... |
24 | | }
25 | | }
| |_- first implementation here
...
28 | / impl<T> FooTrait for Foo<T>
29 | | where
30 | | T: MyU32,
31 | | {
... |
34 | | }
35 | | }
| |_^ conflicting implementation for `Foo<_>`
严格来说,我们可以通过向类型添加更好的特征来修复这个实验:
// External libraries
use std::fmt::Display;
// Trait gives the name
trait MyTrait {
fn name(&self) -> String;
}
impl MyTrait for f64 {
fn name(&self) -> String {
"f64".to_string()
}
}
impl MyTrait for u32 {
fn name(&self) -> String {
"u32".to_string()
}
}
// Some kind of struct
struct Foo<T> {
t: T,
}
impl<T> Foo<T>
where
T: MyTrait + Display,
{
fn printme(&self) {
println!("In a {}: {}", self.t.name(), self.t);
}
}
// Takes a foo
fn foo<T>(x: Foo<T>)
where
T: MyTrait + Display,
{
x.printme();
}
fn main() {
// Try both cases
foo(Foo { t: 1.2 });
foo(Foo { t: 12 });
}
给出正确的输出:
In a f64: 1.2
In a u32: 12
也就是说,此代码相对简单,因此这种修复很容易。更一般地说,我有一个依赖于用户定义数据的结构。此数据必然具有一组不同的关联方法,并且很难强制每种数据具有通用接口。但是,依赖于此数据的结构可以很好地吸收此信息,只要它知道它拥有哪种数据。从理论上讲,我们可以定义两种不同的结构,接受两种不同类型的数据,并让这些结构实现一个通用的接口。也就是说,我真的希望访问一组通用的字段,并且宁愿不必定义许多 setter 和 getter。有没有更好的方法来实现这一目标?
好吧,我想我应该考虑更长的时间,但是以下内容实现了我在没有二传手和获取器的情况下想要的:
// Trait locked to a type
trait Float {
fn bar(&self) -> String;
}
impl Float for f32 {
fn bar(&self) -> String {
"f32".to_string()
}
}
impl Float for f64 {
fn bar(&self) -> String {
"f64".to_string()
}
}
trait Int {
fn baz(&self) -> &'static str;
}
impl Int for i32 {
fn baz(&self) -> &'static str {
"i32"
}
}
impl Int for i64 {
fn baz(&self) -> &'static str {
"i64"
}
}
// Define all of the different implementations that we care to implement in Foo
enum MyTypes {
Float(Box <dyn Float>),
Int(Box <dyn Int>),
}
// Some kind of struct
struct Foo {
t : MyTypes,
}
// Implementation for f64
impl Foo {
fn printme(&self) {
match self.t {
MyTypes::Float(ref t) => {
println!("In a Float({})", t.bar());
}
MyTypes::Int(ref t) => {
println!("In an Int({})", t.baz());
}
}
}
}
// Takes a foo
fn foo(x : Foo) {
x.printme();
}
fn main() {
// Try both cases
foo(Foo { t : MyTypes::Float(Box::new(1.2_f32))});
foo(Foo { t : MyTypes::Int(Box::new(12_i64))});
}
从本质上讲,如果我们知道用户定义的数据将来自有限数量的特征,我们可以将所有内容包装在枚举中
,然后让结构根据用户提供的数据类型更改其实现。这需要根据特征对传入的用户数据进行装箱,从而适当地隐藏基础类型。
问题内容: 我有一个参数化的类: 致电: 那么,如何使用Java泛型来获取实际的类型? 问题答案: 可以做到,但是类型擦除可能会很困难。正如其他答案所讨论的那样,您必须成为的子类或将类型的字段添加到中,而执行此操作所需的反射代码却很复杂。 在这种情况下,我建议您解决以下问题: 由于Java对静态方法的类型推断,因此无需太多额外的样板即可构造类: 这样,您就具有完全的通用性和类型安全性,并且仍然可以
我不想为每个类型T编写这个方法只是为了调用getMessage()并将其传递给下一个方法。 有可能写出这样的方法吗?我只想访问ConstraintViolation接口的方法,这些方法不依赖于类型T(如字符串getMessage())。
问题内容: 如果我有一个像这样的抽象类: 还有一些从Item派生的类是这样的: 我不明白为什么我不能使用泛型调用构造函数: 我知道可以有一个没有构造函数的类型,但是这种情况是不可能的,因为Pencil具有没有参数的构造函数,而Item是抽象的。但是我从eclipse中得到了这个错误: 无法实例化 我不明白为什么的 T类型 ,以及如何避免这种情况? 问题答案: 无法使用Java类型系统来强制类层次结
我试图编写一个函数来返回
假设我有以下课程: 我想添加一个构造函数,它需要一个
我正在做作业,所以我只想修复我的编译错误,这样我就可以继续工作了。我需要创建一个PointList类,在ArrayList中保存一个Point对象列表。PointList类应该接受任何作为Point类实例或Point子类的对象。 我不断收到一个编译器错误,上面写着 我真的不明白我错过了什么,我已经通读了这本书,似乎不明白为什么我会得到这个错误。我已经制作了 Point 类并完成了测试,但似乎无法编