Unter Verwendung von rustc 1.10.0
versuche ich, Code zu schreiben, der verklemmte Schließungen passiert - das letztendliche Ziel ist es, eine Animation von Fraktalen prozedural zu generieren. Im Moment habe ich einige Funktionssignaturen wie folgt aus:Boxed Fn benötigt Lebenszeit nur beim Testen statisch?
pub fn interpolate_rectilinear(width: u32, height: u32, mut min_x: f64, mut max_x: f64, mut min_y: f64, mut max_y: f64)
-> Box<Fn(u32, u32) -> Complex64 + Send + Sync + 'static> { ... }
pub fn interpolate_stretch(width: u32, height: u32, mut min_x: f64, mut max_x: f64, mut min_y: f64, mut max_y: f64)
-> Box<Fn(u32, u32) -> Complex64 + Send + Sync + 'static> { ... }
pub fn parallel_image<F>(width: u32, height: u32, function: &F, interpolate: &Box<Fn(u32, u32) -> Complex64 + Send + Sync>, threshold: f64)
-> ImageBuffer<image::Luma<u8>, Vec<u8>>
where F: Sync + Fn(Complex64) -> Complex64
{ ... }
pub fn sequential_image<F>(width: u32, height: u32, function: &F, interpolate: &Box<Fn(u32, u32) -> Complex64>, threshold: f64)
-> ImageBuffer<image::Luma<u8>, Vec<u8>>
where F: Fn(Complex64) -> Complex64
{ ... }
Ausführen dieses Code für ein Bild zu einem Zeitpunkt in einem binären Arbeiten ohne Probleme:
let interpolate = interpolate_rectilinear(width, height, -1.0, 1.0, -1.0, 1.0);
let image = parallel_image(width * 2, height * 2, &default_julia, &interpolate, 2.0);
Aber ich wollte meine serielle und parallele, um sicherzustellen, Bildproduktion waren beide die gleichen Ergebnisse zu erzielen, so schrieb ich die folgende Testfunktion:
#[test]
fn test_serial_parallel_agree() {
let (width, height) = (200, 200);
let threshold = 2.0;
let interpolate = interpolate_stretch(width, height, -1.0, 1.0, -1.0, 1.0);
assert!(parallel_image(width, height, &default_julia, &interpolate, threshold)
.pixels()
.zip(sequential_image(width, height, &default_julia, &interpolate, threshold)
.pixels())
.all(|(p, s)| p == s));
}
Dieser weigert sich zu kompilieren, und ich kann es einfach nicht herausfinden. Der Fehler ist wie folgt:
> cargo test
Compiling julia-set v0.3.0
src/lib.rs:231:66: 231:78 error: mismatched types [E0308]
src/lib.rs:231 .zip(sequential_image(width, height, &default_julia, &interpolate, threshold)
^~~~~~~~~~~~
src/lib.rs:229:9: 233:36 note: in this expansion of assert! (defined in <std macros>)
src/lib.rs:231:66: 231:78 help: run `rustc --explain E0308` to see a detailed explanation
src/lib.rs:231:66: 231:78 note: expected type `&Box<std::ops::Fn(u32, u32) -> num::Complex<f64> + 'static>`
src/lib.rs:231:66: 231:78 note: found type `&Box<std::ops::Fn(u32, u32) -> num::Complex<f64> + Send + Sync>`
error: aborting due to previous error
Build failed, waiting for other jobs to finish...
error: Could not compile `julia-set`.
Ich weiß wirklich nicht, was dort vor sich geht. Ich weiß nicht, warum ich Send
und Sync
in den Boxed-Return-Typen der Interpolationsfunktionen manuell markieren muss, wenn der Compiler diese Merkmale normalerweise automatisch ableitet. Immerhin fügte ich einfach Marker hinzu, die der Compiler vorgeschlagen hatte, bis die Dinge funktionierten.
Das eigentliche Problem ist, dass, während ich denke, ich habe eine ziemlich gute Vermutung, warum Sie nicht einfach einen verschlossenen Verschluss 'static
markieren, weiß ich nicht, was diese Lebensdauer in diesem Fall oder wie es zu beheben erfordert.
Ich vermutete, dass möglicherweise das Problem war, dass ich versuchte, die Schließung von zwei Read-borrows auf einmal zu referenzieren (was in Ordnung sein sollte, aber ich war verzweifelt); Auf jeden Fall gibt interpolate
in einem Rc
den gleichen Fehler, so dass das Problem nicht war.
Haben Sie ein Git Repo oder eine solche? Ich würde das gern testen. – Veedrac
Zusätzlich zu Veedracs Kommentar solltest du einen [MCVE] angeben, wenn du hier eine Frage zu Stack Overflow stellst (wirklich überall, aber besonders hier). Wenn wir Ihr Problem nicht ausschließlich von dem, was hier enthalten ist, reproduzieren können, wird die Frage geschlossen. – Shepmaster
@Veedrac Ja, das Repository ist [hier] (https: // github.com/coriolinus/julia-set/baum/c3b1d31ec9bc981f1a0575c7e3fcc2d377de30db). Der Ort, an dem der Anruf funktioniert, ist [hier] (https://github.com/coriolinus/julia-set/blob/master/src/bin.rs#L79-L82), und der Test, bei dem es nicht funktioniert, ist [hier] (https://github.com/coriolinus/julia-set/blob/master/src/lib.rs#L223-L234). Ich hatte so wenig eingefügt wie hier, weil es so aussah, als sei die Frage schon ziemlich lang und detailliert, und es wäre nicht minimal gewesen, mehrere hundert Zeilen überflüssiger Quellen einzufügen. – coriolinus