Wie setzen Sie bestimmte Arten, die auf generische Merkmale in rust?
Ich nahm zunächst an, Sie könnten dies tun, weil die Dokumentation (http://doc.rust-lang.org/rust.html#implementations) schlägt vor, Sie können:
trait Bar<T> {
fn ex(&self) -> T;
}
struct Foo {
y:f64
}
impl Bar<int> for Foo {
fn ex(&self) -> int {
return self.y.floor() as int;
}
}
impl Bar<uint> for Foo {
fn ex(&self) -> uint {
if (self.y < 0.0) {
return 0u;
}
return self.y.floor() as uint;
}
}
...aber das scheint nicht zu funktionieren. Ich bekomme Fehler wie:
error: multiple applicable methods in scope
error: expected Bar<uint>, but found Bar<int> (expected uint but found int)
error: expected Bar<int>, but found Bar<uint> (expected int but found uint)
So, ich dachte, vielleicht Foo muss generisch sein, für diese zu arbeiten, so dass jede spezifische Foo hat eine eigene Bar-Implementierung auf Sie:
trait Bar<T> {
fn ex(&self) -> T;
}
struct Foo<T> {
y:f64
}
impl<T> Foo<T> {
fn new<U>(value:f64) -> Foo<U> {
return Foo { y: value } as Foo<U>;
}
}
impl Bar<int> for Foo<int> {
fn ex(&self) -> int {
return self.y.floor() as int;
}
}
impl Bar<uint> for Foo<uint> {
fn ex(&self) -> uint {
if (self.y < 0.0) {
return 0u;
}
return self.y.floor() as uint;
}
}
fn main() {
let z = Foo::new::<int>(100.5);
let q = Foo::new::<uint>(101.5);
let i:int = z.ex();
let j:uint = q.ex();
}
...aber mein Konstruktor scheint nicht zu funktionieren:
x.rs:11:12: 11:38 error: non-scalar cast: `Foo<<generic #1>>` as `Foo<U>`
x.rs:11 return Foo { y: value } as Foo<U>;
^~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Edit: ich habe auch versucht:
impl<T> Foo<T> {
fn new<U>(value:f64) -> Foo<U> {
let rtn:Foo<U> = Foo { y: value };
return rtn;
}
}
Dem lösen der casting-Fehler, aber die Ergebnisse in:
x.rs:32:11: 32:26 error: cannot determine a type for this expression: unconstrained type
x.rs:32 let z = Foo::new::<int>(100.5);
^~~~~~~~~~~~~~~
O_o ich habe keine Ahnung, was das bedeutet.
Wie tun Sie dies?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
impl Bar<int> for Foo
undimpl Bar<uint> for Foo
ist ein Fehler, weil, im moment, nur eineimpl
erlaubt ist pro Merkmal und Typ-paar (ohne Berücksichtigung der Parameter auf das Merkmal). Ich ging mehr ins detail in diese Antwort, darunter eine Arbeit um mit einem sekundären Merkmal, das verhindert, dass SieFoo
generische (das ist wahrscheinlich nicht das, was Sie wollen).Der zweite Fehler ist, weil Sie zwei Typ-Parameter
T
undU
"in scope" für dienew
Funktion, sondern sind nur eine Angabe (U
). DieT
muss angegeben werden, durch das schreibenFoo::<int>::...
aber ich glaube nicht, dass dies ist, was Sie wollen, anstatt, Sie sollten mit denT
Generika in dernew
Funktion:Als hintergrund, der compiler muss wissen, die konkrete Art der
T
da die Implementierung vonnew
ändern könnte:dann
Foo::<()>::new::<int>(0.0)
geben würdey == 0.0
, aberFoo::<u64>::new::<int>(0.0)
geben würdey == 8.0
.T
, das gleiche wielet a = 1; { let a = 2; }
ist die Definition einer neuen variablea
innerhalb der inneren Umfang. DieFoo<()>
Fall funktioniert, weil Sie dann nur noch den parameter " Typ " aus dernew<T>() -> Array<T>
, als Sie angegeben haben einen konkreten Typ (()
aka Einheit) für den type-parameter derFoo
: es ist nicht mehr generisch. Die-> Array<U>
nicht ableiten, das zurück geben, denn das wäre falsch, es gibt keinen Grund, dass dieU
und dieT
haben das gleiche zu sein...impl<T> Array<T> { fn convert<U>(&self) -> Array<U> { ... } }
ist, dass ein array von einem anderen Typ sein: nur weil Sie erwähnenArray<...>
bedeutet nicht, es muss entsprechend derArray<...>
imimpl
header.<()>
Sache ist nur die übergabe der()
- Typ als Typ-parameterimpl Foo<uint> { ... }
würde auch die "Arbeit" gleich gut, aber ziemlich sicher nicht das, was Sie eigentlich wollen.)