These are chat archives for rust-lang/rust

14th
Mar 2018
Fredrik Portström
@portstrom
Mar 14 2018 08:48
Is there a way for a for a macro that defines a variable to export the identifier so it can be used within a block given to the macro?
Fredrik Portström
@portstrom
Mar 14 2018 08:57
I think I just figured out the right solution. Apparently the caller of the macro can provide the identifier, and the macro can use the provided identifier for declaring the variable.
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:08
I want to delete first N random keys from HashMap - what is the best way to do that?
I was trying to do something along the lines h.keys().take(start) - then use that iterator to remove from map, but it seems I can't do that without persisting keys into other collection
what is best way to do it iteratively?
Zakarum
@omni-viral
Mar 14 2018 09:10
use h.keys().next()
for _ in 0 .. N {
    if let Some(key) = h.keys().next() {
        h.remove(key);
    } else {
        break;
    }
}
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:11
interesting, will h.keys() - return new random iterator every time?
Zakarum
@omni-viral
Mar 14 2018 09:11
It never returns random iterator
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:11
actually instead of removing I want to mutate value of first N keys
will it still work?
I assume if I'm not removing - then h.keys() might give me the same key over and over
Zakarum
@omni-viral
Mar 14 2018 09:12
for _ in 0 .. N {
    if let Some(key) = h.keys().next() {
        *h.get(&key).unwrap() = newvalue;
    } else {
        break;
    }
}
Ah. Yes.
for i in 0 .. N {
    if let Some(key) = h.keys().skip(i).next() {
        *h.get(&key).unwrap() = newvalue;
    } else {
        break;
    }
}
Might be suboptimal :smile:
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:13
this one would work, but n^2
Zakarum
@omni-viral
Mar 14 2018 09:14
You know what
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:14
I can't find a way to do it iteratively while keeping constant memory/big O
Zakarum
@omni-viral
Mar 14 2018 09:15
for val in h.values_mut().take(N) {
    *val = newvalue
}
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:15
ah, that should work!
thanks!
Zakarum
@omni-viral
Mar 14 2018 09:15
no problem!
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:17
@omni-viral also, as I understand iterating and removing keys are mutually exclusive
Zakarum
@omni-viral
Mar 14 2018 09:17
Of course
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:18
is that a borrow checker artifact?
Zakarum
@omni-viral
Mar 14 2018 09:20
Not entirely
It depends on structure.
But you can't guarantee that you won't remove next key in iterator.
That operation will invalidate iterator
For trees and lists removing elements that aren't next in iterator is safe operation. But Rust requires static guarantees
Michal 'vorner' Vaner
@vorner
Mar 14 2018 09:23
For deletion, you could use retain or retain_mut and use a variable in the closure to determine the count.
If you want to just mutate them, then iter_mut or for … in &mut collection
Zakarum
@omni-viral
Mar 14 2018 09:24
@vorner good point with retain. It does just that. Iterates and removes. And keeps guarantees about validty of iterator internally.
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 09:28
yep, I'm going to do that, just was interested why - some other languages let you iterate and remove keys
Zakarum
@omni-viral
Mar 14 2018 09:28
@Kane-Sendgrid some other languages let you shoot in your foot at the same time :smile:
Vyacheslav Kim (Kane)
@kanekv
Mar 14 2018 23:58
what is a good way to build long string in rust (similar to string builder)? will push_str double capacity to avoid extra allocations or it will allocate exactly what's needed to append a string? In other terms, is manual capacity management needed?