Cloning self for callbacks


#1

In a gtk-rs context so lots of callbacks. A method creates an object which has signals, the call backs of which have to access methods that are “sibling” to the method. I think the following is a reasonable sketch:

fn some_method(&self) {
    let x = X::new();
    x.connect_action({
        let capture_self = ?????????;
        move || { capture_self.another_method(); }
    });
}

For all other types cloning of a “pointer” type does the job. But everything I have tries with self just leads to “cannot move out of borrowed content”. There must be a way of getting the reference to the current object.


#2

Have you seen the gtk-rs tutorial?

The easiest way to handle your situation is to make the state that the callback needs shared via an Rc - self and the callback then share a reference to it via their own Rc instances. The extreme case of this is to make all of self cloneable by holding all its state in an Rc.


#3

I believe the tutorial is as the gtk-rs examples, they do not seem to have this situation when you need to call a sibling method of the object.


#4

If you must call a sibling method (rather than using associated functions) then you can make self cloneable as I mentioned in the previous reply. Here is a contrived playground sketching it out.


#5

Thanks for the reply, much appreciated. I’ll have to go away and have a mull over all this. Clearly the way I am modelling things is not really working in Rust despite seeming the right way of doing it.

I am not sure what you mean by “associated function” here. The callback has to be called on a very specific bit of data and it seemed that a method was the right way of doing it.


#6

IIRC gtk-rs callbacks all (or most?) require the callback to be 'static - essentially, this means the closure representing the callback cannot borrow anything, such as a reference to self. The easiest and most practical way to work with this setup is to use Rc to share ownership over the state.

An associated function is a function that doesn’t take self in any capacity, but is otherwise associated with a type. If you’re familiar with C# or Java, this is roughly a static method. In Rust, these are quite useful precisely because they don’t require &self or &mut self but instead take explicit arguments - this oftentimes makes it easier to avoid borrowing issues.

Here is the same example as above except using an associated function to handle the logic of the callback.

BTW, you can see the gtk-rs tutorial using clones to move state into closures, such as the examples starting here.


#7

The cloning for closures as callbacks technique I am already using. It is impossible to do anything else.:slight_smile:

I have to admit, apart from new I hadn’t thought about functions being in the implementation section but not being methods. I must investigate the difference between these associated functions and module level functions. Stuff to learn. :slight_smile:

I am now fairly sure I can recast my problem without using methods and using an Rc so as do the usual cloning, but without self being involved. I suspect I was thinking in far too C++ and D a way!

Thanks for your comments and code, this has been really useful for me,and hopefully will make my Rust code more idiomatic. Which is clearly isn’t just now.