These are chat archives for rust-lang/rust

15th
Sep 2018
John
@gitlabaccount624_gitlab
Sep 15 2018 01:37
is there any way to move all of the values out of a struct?
why i want to do this: my struct has two values and i'm spawning a thread that uses one of the values and then calls and_then and that closure uses the other value. currently i'm just cloning each value of the struct and moving one to one closure and one to the other but i was wondering if there was a way to avoid that :thinking:
and i don't think i can move the entire struct into the first closure and then move it to the second closure when it's done with the first ... or at least i'm not sure how to do that and i got errors when i tried
John
@gitlabaccount624_gitlab
Sep 15 2018 02:48
anyone there =?
Ichoran
@Ichoran
Sep 15 2018 03:06
You can use match, can't you?
John
@gitlabaccount624_gitlab
Sep 15 2018 03:07
is that in response to my question? if so i don't quite see how that'd work
maybe some pseudocode will help.. sec
let connection = establish_connection();

req.cpu_pool().spawn_fn(move || {
    diesel.query(&connection)
}).and_then(move || {
    diesel.query(&connection) // <--- error: connection already moved into first closure. can't use it here
});
does that make sense?
Ichoran
@Ichoran
Sep 15 2018 03:10
I don't think you can get the values back after you move them into the first struct, so no, in general you can't.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:11
i see
Ichoran
@Ichoran
Sep 15 2018 03:11
The problem is not that you can't move them out of the struct but that you can't get them back once you move them into the closure.
If half the values go to one closure and the other half to another, then you're okay.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:12
why is that by the way? you can move other variables twice, no? and you can also move variables out of a struct? so ...
actually don't even need the second part
because i'm not taking anything out of the struct i don't think
Ichoran
@Ichoran
Sep 15 2018 03:12
You can only move out a variable once. You can move from the new thing into an even newer thing.

So you can write a pattern like

let x = foo()
let y = bar(x)
let z = baz(y)

but you can't write

let x = foo()
let y = bar(x)
let z = baz(x)  // Already moved x!
John
@gitlabaccount624_gitlab
Sep 15 2018 03:14
oh so u can move up and down many times but left and right only once?
Ichoran
@Ichoran
Sep 15 2018 03:14
You can only consume a variable once.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:16
gotcha
Ichoran
@Ichoran
Sep 15 2018 03:17
It's a little complicated because some things are Copy and are always duplicated, but basically, if you get the thing--you don't borrow it, you actually get it--nobody else can use it any more.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:17
yeah no that was my confusion just now because it was working with ints but then i remembered they were copy so i understand now
ok so the problem is.....
Ichoran
@Ichoran
Sep 15 2018 03:17
:+1:
Now if you're going to ask if you can just clone a connection and have everything work, I have no idea :P I try to stay away from databases.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:18
this closure is a future ... so i have to move connection into it.. because the function returns immediately... and if i don't do that it won't have it ... and then the next and_then won't have it ... because it was already moved into the first closure .. so i either have to clone the connection or get rid of my and_then and perform both calls in the same closure ..
right?
or is there a 3rd alternative
Ichoran
@Ichoran
Sep 15 2018 03:19
A closure is not a future; a future is a way to run a closure in the background and complete it "sooner or later".
John
@gitlabaccount624_gitlab
Sep 15 2018 03:19
sorry edited that
uhh it's still wrong but yeah i understand
Ichoran
@Ichoran
Sep 15 2018 03:19
Any values that the closure uses have to be moved into the closure, which is given to the future to use at the appropriate time.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:19
yeah
i get that
so any other solutions besides cloning the connection or doing all database calls in the same closure?
Ichoran
@Ichoran
Sep 15 2018 03:20
I'm not sure of the API, but if you can return (answer, connection) as the result of the future, you can pass the connections along.
But it looks like you're not taking any arguments, so I don't know if that works. I haven't studied the type signatures of futures yet.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:21
hmm ok i might try that
Ichoran
@Ichoran
Sep 15 2018 03:21
That's how I do it in Scala, though. I pass the resource through.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:21
actually i have no idea how i would do the syntax for that so i think i might just do it all in the same closure
i think i'd have to map the future or something
not sure how to do that
oh i have another question
so currently i'm doing all this future stuff with and_then
the new async/await stuff coming out is just sugar for that right?
i think it's like that in javascript
Ichoran
@Ichoran
Sep 15 2018 03:23
I can't say without looking at the types, and I don't have time to look at the types right now. Good luck though!
async/await is a bit of sugar and a bit of performance optimization.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:23
oh performance too?
Ichoran
@Ichoran
Sep 15 2018 03:23
It's not going to turn the world upside-down.
I think it was supposed to be. I haven't kept track lately.
John
@gitlabaccount624_gitlab
Sep 15 2018 03:23
yeah i hear about async await all the time but i was wondering what the big deal was .. at least in my code the and_then isn't that bad.. but i'm not really doing anything too complex i guess
i hear a lot about library authors are like "yeah waiting on async await to hit stable before i implement xyz feature"
but .. isn't it just some sugar for future combinators? no one really needs async await right? trying to see what the fuss is about
I need to get going. I think that explains it reasonably well. When you read things like "can borrow across yield points", think "if I didn't borrow, I would need to clone or something, and that would be slower".
John
@gitlabaccount624_gitlab
Sep 15 2018 03:26
okie dokie thanks
Ichoran
@Ichoran
Sep 15 2018 03:27
But mostly it's ergonomics.
Kelly Thomas Kline
@kellytk
Sep 15 2018 05:46
What brief video/reading would you recommend to learn best practices and tradeoffs of performance optimization with Rust? For example, when dedicating a new thread to something is justified, locks, etc
Michal 'vorner' Vaner
@vorner
Sep 15 2018 05:57
@kellytk I don't think there are things for that, it comes down mostly to measurement and experience. But as the runtime semantics of Rust are more or less the same as with C or C++, any textbook or lecture (or tool, when it comes to that) dealing with performance in these is most likely to be accurate for Rust too.
trsh
@trsh
Sep 15 2018 08:48
Is someone using lettre to send emails via Rust, any exp?
error[E0308]: mismatched types
  --> manu/src/impls/email/email.rs:30:46
   |
30 |         ClientTlsParameters::new(EMAIL_SMTP, tls_builder.build().unwrap());
   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `native_tls::TlsConnector`, found struct `impls::email::email::native_tls::TlsConnector`
   |
   = note: expected type `native_tls::TlsConnector`
              found type `impls::email::email::native_tls::TlsConnector`
note: Perhaps two different versions of crate `native_tls` are being used?
  --> manu/src/impls/email/email.rs:30:46
   |
30 |         ClientTlsParameters::new(EMAIL_SMTP, tls_builder.build().unwrap());
Can't get smart with this err
trsh
@trsh
Sep 15 2018 08:54
Because I import it like use self::native_tls::TlsConnector; its not a diff lib, right? :D
trsh
@trsh
Sep 15 2018 08:59
vm, actually some other lib had this depencie with older version
Farzeen
@happycoder97
Sep 15 2018 14:43
#![allow(unused_variables)]

fn connect_callback<F: Fn()+'static>(cb: F) {}
fn disconnect_callback() {}

fn main() {
    {
        let a = String::from("Hello");
        let cb = || {
            println!("{}", &a);
        };
        connect_callback(cb);
        // .... 
        disconnect_callback();
    }
}
Here I am manually making sure that references inside cb does live longer than the time during which the callback is registered. In such cases, is there any unsafe {..} way to override the lifetime checker?
The connect functions of gtk-rs only accept Fn()+'static
Jan Hlavatý
@hlavaatch
Sep 15 2018 16:42
what am i supposed to do to make rls work again in VSCode? rls-preview disappeared from nightly...
switched to stable for now...