[][src]Macro glib::clone

macro_rules! clone {
    ( => $($_:tt)*) => { ... };
    ($(move)? || $($_:tt)*) => { ... };
    ($(move)? | $($pattern:pat),* | $($_:tt)*) => { ... };
    ($($(@ $strength:ident)? self),+ => $($_:tt)* ) => { ... };
    ($($(@ $strength:ident)? $up:ident.$($variables:ident).+),+ => $($_:tt)* ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => @default-panic, move || $body:block ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => @default-panic, move || $body:expr ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => $(@default-return $return_value:expr,)? move || $body:block ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => $(@default-return $return_value:expr,)? move || $body:expr ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => @default-panic, move | $($pattern:pat),* | $body:block ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => @default-panic, move | $($pattern:pat),* | $body:expr ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => $(@default-return $return_value:expr,)? move | $($pattern:pat),* | $body:block ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => $(@default-return $return_value:expr,)? move | $($pattern:pat),* | $body:expr ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => @default-return $return_value:expr, || $body:block ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => @default-return $return_value:expr, | $($pattern:pat),* | $body:block ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => default-return $($x:tt)+ ) => { ... };
    ($($(@ $strength:ident)? $($variables:ident).+ $(as $rename:ident)?),+ => @default-return $($x:tt)+ ) => { ... };
    ($($(@ $strength:ident)? $variables:expr),+ => $($_:tt)* ) => { ... };
}

Macro for passing variables as strong or weak references into a closure.

This macro can be useful in combination with closures, e.g. signal handlers, to reduce the boilerplate required for passing strong or weak references into the closure. It will automatically create the new reference and pass it with the same name into the closure.

If upgrading the weak reference to a strong reference inside the closure is failing, the closure is immediately returning an optional default return value. If none is provided, () is returned.

Passing a strong reference

use glib::clone;
use std::rc::Rc;

let v = Rc::new(1);
let closure = clone!(@strong v => move |x| {
    println!("v: {}, x: {}", v, x);
});

closure(2);

Passing a strong and weak reference

use glib::clone;
use std::rc::Rc;

let v = Rc::new(1);
let u = Rc::new(2);
let closure = clone!(@strong v, @weak u => move |x| {
    println!("v: {}, u: {}, x: {}", v, u, x);
});

closure(3);

Renaming variables

use glib::clone;
use std::rc::Rc;

let v = Rc::new(1);
let u = Rc::new(2);
let closure = clone!(@strong v as y, @weak u => move |x| {
    println!("v as y: {}, u: {}, x: {}", y, u, x);
});

closure(3);

Providing a default return value if upgrading a weak reference fails

You can do it in two different ways:

Either by providing the value yourself using @default-return:

use glib::clone;
use std::rc::Rc;

let v = Rc::new(1);
let closure = clone!(@weak v => @default-return false, move |x| {
    println!("v: {}, x: {}", v, x);
    true
});

// Drop value so that the weak reference can't be upgraded.
drop(v);

assert_eq!(closure(2), false);

Or by using @default-panic (if the value fails to get upgraded, it'll panic):

# use glib::clone;
# use std::rc::Rc;
# let v = Rc::new(1);
let closure = clone!(@weak v => @default-panic, move |x| {
    println!("v: {}, x: {}", v, x);
    true
});
# drop(v);
# assert_eq!(closure(2), false);

Errors

Here is a list of errors you might encounter:

Missing @weak or @strong:

This example deliberately fails to compile
let v = Rc::new(1);

let closure = clone!(v => move |x| println!("v: {}, x: {}", v, x));

Passing self as an argument:

This example deliberately fails to compile
#[derive(Debug)]
struct Foo;

impl Foo {
    fn foo(&self) {
        let closure = clone!(@strong self => move |x| {
            println!("self: {:?}", self);
        });
    }
}

If you want to use self directly, you'll need to rename it:

#[derive(Debug)]
struct Foo;

impl Foo {
    fn foo(&self) {
        let closure = clone!(@strong self as this => move |x| {
            println!("self: {:?}", this);
        });
    }
}

Passing fields directly

This example deliberately fails to compile
#[derive(Debug)]
struct Foo {
    v: Rc<usize>,
}

impl Foo {
    fn foo(&self) {
        let closure = clone!(@strong self.v => move |x| {
            println!("self.v: {:?}", v);
        });
    }
}

You can do it by renaming it:


impl Foo {
    fn foo(&self) {
        let closure = clone!(@strong self.v as v => move |x| {
            println!("self.v: {}", v);
        });
    }
}