/ / Eigenschaft für Schließartalias implementieren - Schließungen, Rost, Merkmale, Typalias

Merkmal für Verschlusstyp-Alias ​​implementieren - Verschlüsse, Rost, Merkmale, Typ-Alias

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>) -> i32Mit 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 № 1

Ich 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 lets.

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`