These are chat archives for rust-lang/rust

11th
Jan 2019
Sergey Nikolaev
@qvantor
Jan 11 09:10
struct Rect {
    id: u32,
    name: String,
    color: Color
}
impl ObjectTR for Rect {}
impl SomeOtherTrait for Rect {
    fn id(&self) -> u32
}
struct Collection {
    objects: Vec<Box<ObjectTR>> // I sad here that in Vec should be obj witch is impl ObjectTR trait
// But object inside Vec can also impl SomeOtherTrait, or any other trait 
}
let collect = Collection { objects: vec![] }
collect.push(Box::new(Rect::new()))
a.objects[0].id() // i can't call fn from SomeOtherTrait here, only from ObjectTR trait
How to use methods from all available traits inside vector? If different object impl different traits, but all object impl ObjectTR trait?
Can anyone help with that?
niveau0
@niveau0
Jan 11 09:27
@qvantor I don't think this can work, since your Vec can hold an object of type ObjectTR, which is not of type SomeOtherTrait, so .id() would fail on that.
e.g. "impl ObjectTR for Circle", then collect.push(aCircle), but Circle is missing "impl SomeOtherTrait for Circle"
Sergey Nikolaev
@qvantor
Jan 11 09:32
@niveau0 yes, sure.
but it's something like a match for types like I can do cycle, and if an item implements SomeOtherTrait i can use it
Georg Semmler
@weiznich
Jan 11 10:48
Does anyone have an idea how to make something like this working?
Denis Lisov
@tanriol
Jan 11 10:53
@qvantor There are a few options. The most idiomatic, if you're talking about match, is using an explicit enum instead of Box<dyn Trait>. You can also try downcasting to the specific type if you know it, but that feels like a layering violation to me. Finally, you can use some SpecialTrait: ObjectTR and make its implementations give you access to the SomeOtherTrait implementations if available.
Sergey Nikolaev
@qvantor
Jan 11 11:03
@tanriol can you tell me about SpecialTrait: ObjectTR this implementation more? Some links on examples or documentation.
Do i right that is similar to type composition in haskell?
Tim Robinson
@1tgr
Jan 11 11:03
I had the same suggestion for number 3
earthengine
@earthengine
Jan 11 11:03
@weiznich I have been worked through that code to proof (i32, HasMany<Foo>) and it requires cyclic reasoning. So yes, without any modification your code will not work...
Tim Robinson
@1tgr
Jan 11 11:03
On ObjectTR you could add: fn as_some_other_trait(&self) -> Option<&dyn SomeOtherTrait>
Georg Semmler
@weiznich
Jan 11 11:04
@earthengine So no clever way to workaround that?
Sergey Nikolaev
@qvantor
Jan 11 11:05
@1tgr sound reasonable, i will try :) Tnx
earthengine
@earthengine
Jan 11 11:07
@weiznich Your code have some name that don't match its purpose, so I don't know what you are actually trying to do. Talking about theoratical examples does not mean anything, we all know this can happen.
Georg Semmler
@weiznich
Jan 11 11:12
The problem with the original code is that it is much more complex and involves several more layers of abstraction, but here you go :see_no_evil:
(That said I totally understand what's the problem here. I've just wanted to ask if someone has an idea how to "solve" this…)
For example it works fine as soon as I implement everything for the concrete types that are involved and not in a generic way. Therefore it seems like some sort of cyclic reasoning seems to be supported…
earthengine
@earthengine
Jan 11 11:15
One thing I could think of, is to introduce some wrapper types/traits to break the circle?
Georg Semmler
@weiznich
Jan 11 11:22
So adding more levels of abstraction to this. Let's try that…
Ash
@ashthespy
Jan 11 14:27
what is a good way to drop a running thread? Other than setting up a channel, or an arc boolean that can be flipped to kill it - is there a simpler way I am missing?
Denis Lisov
@tanriol
Jan 11 14:31
@ashthespy You usually don't want to kill a thread in the middle of its work... for example, it may be accessing something Mutex-protected and cause a deadlock.
Ash
@ashthespy
Jan 11 14:33
it's work currently is just to wait for external commands - so no mutex stuff
Ingvar Stepanyan
@RReverser
Jan 11 14:34
Then still better to use a boolean, at least you'll have a guaranteed point of exit
Denis Lisov
@tanriol
Jan 11 14:34
Also, if your program is done, you can just exit it... AFAIR, the other threads get killed on termination automatically.
Ash
@ashthespy
Jan 11 14:36
Righto - I will rethink how best to implement this!
Tim Robinson
@1tgr
Jan 11 14:38
The ways you already mentioned are fine... you ask a thread to stop running, you don't kill it from outside
Channels or Arc<bool> are fine for this
Or or the whole program is exiting then you don't have to do anything, all the threads will exit
Ash
@ashthespy
Jan 11 14:56
I would imagine Arc<bool> is more efficient than setting up a channel just to signal the thread to stop right?
@1tgr My wording was wrong, I indeed meant to signal the thread to stop and clean up.
Tim Robinson
@1tgr
Jan 11 14:58
You'd normally pass the 'stop' flag to wherever the thread is looking for work
So if the thread gets its work from a channel, you put a special value in the channel that tells it to stop
Ash
@ashthespy
Jan 11 15:01
Unfortunately the thread just listens to external commands i,e from a socket -
but will lookup more thread implementation for some inspiration.
Farhan Ahmed
@IMacronaut_twitter
Jan 11 21:18
Hello, is there a recommended crate (or something built-in to the assert macros) for asserting accuracy for floating point number up to a certain places after the decimal point in a test?
Michal 'vorner' Vaner
@vorner
Jan 11 21:26
If it's for tests, I'd probably go searching through galvanic-assert, though I'm not sure if it's in there.