Ich habe diesen Alias für den Schließungstyp:
type ClosureType = Box<Fn(i32) -> i32>;
diese Eigenschaft:
trait Trait {
fn change(&self, y: i32) -> i32;
}
und diese Funktionen:
fn with_one(x: Box<Fn(i32) -> i32>) -> i32 {
x(1)
}
fn plus_one(x: i32) -> i32 {
x+1
}
fn main() {
let a = Box::new(|x: i32|{x+1});
let b: ClosureType = Box::new(|x: i32|{x+1});
let c = Box::new(plus_one);
let d: ClosureType = Box::new(plus_one);
println!("{}", a.change(1));
println!("{}", b.change(1));
println!("{}", c.change(1));
println!("{}", d.change(1));
println!("{}", with_one(a));
println!("{}", with_one(b));
println!("{}", with_one(c));
println!("{}", with_one(d));
}
Wenn ich das Merkmal implementiere Trait
zum ClosureType
oder für Box<Fn(i32) -> i32>
Das ist das Gleiche, wenn ich Aliasnamen richtig verstanden habe:
impl Trait for ClosureType {
fn change(&self, y: i32) -> i32{
self(y)
}
}
oder
impl Trait for Box<Fn(i32) -> i32> {
fn change(&self, y: i32) -> i32{
self(y)
}
}
für Variable a
Ich bekomme:
<anon>:32:22: 32:31 error: no method named `change` found for type
`Box<[closure <anon>:28:22: 28:35]>` in the current scope
<anon>:32 println!("{}", a.change(1));
und für Variable c
Ich bekomme:
<anon>:34:22: 34:31 error: no method named `change` found for type
`Box<fn(i32) -> i32 {plus_one}>` in the current scope
<anon>:34 println!("{}", c.change(1));
Jedoch Variablen a
und c
werden von der Funktion akzeptiert with_one(x: Box<Fn(i32) -> i32>) -> i32
Mit anderen Worten, es scheint, dass sie den gleichen Typ haben (Box<Fn(i32) -> i32>
) für die Funktion with_one
aber anders(Box<[closure <anon>:24:22: 24:35]>
und Box<fn(i32) -> i32 {plus_one}
) zum Trait
Implementierung.
Ich habe das Gefühl, dass mir hier etwas fehlt, aber nicht sicher, was es ist.
Sie können den gesamten Code in finden dieser Rostspielplatz.
Antworten:
4 für die Antwort № 1Ich glaube, dass dies aufgrund einer automatischen Zwangsweise (d. H. Seiner Abwesenheit) von einem konkreten Typ zu einem Merkmalobjekttyp geschieht.
Wenn du anrufst with_one()
kann der Compiler anhand des Funktionsargumenttyps verstehen, dass ein Merkmalsobjekt gewünscht wird, und fügt daher automatische Zwangsmaßnahmen ein:
with_one(a as Box<Fn(i32) -> i32>);
with_one(c as Box<Fn(i32) -> i32>);
Zum b
und d
diese Zwänge sind bereits an ihrem Einsatzort in geschehen let
s.
Bei Merkmalsmethoden führt der Compiler jedoch keine Zwangsmaßnahmen aus. Dies ist ein allgemeines Verhalten bei Generika (und Eigenschaften werden über Generika implementiert - ihre) Self
type ist im Wesentlichen ein impliziter Typparameter für alle Merkmalsmethoden. Zum Beispiel führt Rust bei der Verwendung von Generika auch keine Deref-Zwangsmaßnahmen durch:
trait MyStringLike {}
impl<"a> MyStringLike for &"a str {}
fn function<T: MyStringLike>(t: T) {}
let s: String = "abcde".into();
function(&s); // the trait `main::MyStringLike` is not implemented for the type `&collections::string::String`