-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can ScopeGuards be returned? #13
Comments
A bare I think a boxed trait object
|
Ok, so I messed around with pub fn get_mut<'a, Q: ?Sized>(&'a mut self, k: &Q) -> ScopeGuard<Option<&'a mut V>, impl for<'r> FnMut(&'r mut Option<&'a mut V>) -> (), scopeguard::Always>
where
<V as DeriveKey>::KeyType: ::std::borrow::Borrow<Q>,
Q: hash::Hash + Eq,
{
guard(self.data.get_mut(k), |v| ())
} Here's a complete self-contained example: pub struct Container(u8);
fn guard_test<'a>(container: &'a mut Container) -> ScopeGuard<&'a mut u8, impl for<'r> FnMut(&'r mut &'a mut u8) -> (), scopeguard::Always> {
guard(&mut container.0, |v| ())
} |
even more complete example: #[derive(Debug)]
pub struct Container(u8);
fn guard_test<'a>(
container: &'a mut Container
) -> ScopeGuard<&'a mut u8, impl for<'r> FnMut(&'r mut &'a mut u8) -> (), scopeguard::Always> {
guard(&mut container.0, |v| { **v = **v + 1; })
}
#[test]
fn guards() {
let mut c = Container(3);
{
let mut value = guard_test(&mut c);
**value = **value + 1;
}
assert_eq!(c.0, 5);
} |
Hi, great that you have resolved the syntactical issues. I think that this is not what the scopeguard crate is implementing or has as use case, it's implementing a guard for a lexical scope, and it is not designed to be returned or to “guard” something else. What you would typically do is to use a custom type that keeps the book keeping for you. Look closely at how std's RefCell::borrow and Mutex::lock work. |
Hi @bluss! I'm not sure why scopeguard is inappropriate for this use case -- it seems to do exactly what I want. Is there a hidden infelicity in my example? I realize I could create a custom type with Drop, but scopeguard makes it much easier to set this up. |
There's a lot about your problem that I don't know. If it is unsafe critical that the cleanup code runs, then scope guard is not a solution, since if you give the user the scope guard, they can just choose to forget it to skip its drop. That the return type can't be properly expressed in stable Rust is another good reason I would not use it like this. |
…text stack The format_range_var_table_sample method was pushing a context without popping. Having a macro that ensures both are always done simplifies this. I originally wanted this to be a method that returned a guard, but I'm not sure how to specify the ScopeGuard<...> type parameters in the return type. See bluss/scopeguard#13 for discussion of this.
Hi, I'm not really sure if ScopeGuard does what I'm looking for (or if it's possible at all in Rust).
I can't find any examples of code that returns ScopeGuards without parameterizing the guard closure type.
Imagine I have a collection and I would like to implement a
get_mut
which returns a mutable reference to an element of the collection. Also imagine that I need to perform some bookkeeping with the element after it's been mutated by user-code. I'd like to return aScopeGuard
wrapped around the element with my own closure that will do that bookkeeping. I haven't been able to figure out how to do this since I can't figure out how to write the ScopeGuard type (but this may just be my lack of experience with Rust).Here's some example code which wraps a HashMap. I'm not really sure what the heck I'm doing with that second type parameter for ScopeGuard; I got there just by following compiler errors.
but this isn't working because rustc is saying that the
for<'r> FnMut
type is not Sized.So I'd just like to see if what I'm trying to do is even possible before further banging my head against it :)
The text was updated successfully, but these errors were encountered: