|
That's one of the most annoying things about the language for me, currently. I understand why the restriction is there but as a regular developer it ends up feeling like such an arbitrary restriction around a very common use case.
|
# ? Mar 14, 2020 23:17 |
|
|
# ? May 16, 2024 18:52 |
|
gonadic io posted:Yes, wanting to mutably borrow only one field of a struct and then pass the rest of the struct somewhere else is a common scenario but is unfortunately impossible* to reuse the struct itself. The easiest way is to make all the grouped fields in a second struct so you have like I find this dance usually ends up with me having better encapsulation than I otherwise would have, so it's not all bad.
|
# ? Mar 15, 2020 00:33 |
|
I'm running into a weird error. My basic code is this:code:
|
# ? Mar 23, 2020 19:58 |
|
I don't believe stream.read can be reset half way through like that - since my understanding of how select! works is it calls poll on its futures and then if one returns Ok(value) then it executes that branch. If rx.recv returns a value then steam.read.poll is never called and any incoming bytes stay in the buffer. If stream.read.poll is called, starting the read, then in the next iteration recv finishes quickly, then stream.read.poll will either finish its future or still not be ready. As for fixing this problem, could you get a minimal working example? There's too little context to make too much sense of it for me.
|
# ? Mar 23, 2020 21:48 |
|
Here is the streamlined version of the read method.code:
It seems select does not work well with functions that have serial side effects. edit: One fix I'm considering is having a background task constantly read from the stream and push the result into a queue which the read method would pop from. drainpipe fucked around with this message at 23:14 on Mar 23, 2020 |
# ? Mar 23, 2020 23:09 |
|
Consider something like https://docs.rs/tokio-util/0.3.1/tokio_util/codec/struct.Framed.html
|
# ? Mar 23, 2020 23:37 |
|
Oh great, thanks! It seems like that and the LengthDelimitedCodec are exactly what I'm looking for.
|
# ? Mar 24, 2020 13:07 |
|
I'm writing an app that does some basic network performance tests, and I'd like to be able to format some types from std in my print calls (e.g. std::net::SocketAddr). I stumbled around trying to implement the Display trait, which doesn't work because it's an external type. What's the idiomatic way to handle this? Make a wrapper type? Formatter function? Edit: It looks like I can't use a type alias - same error about an external crate. Do I need to make a type with a SockAddr field and getters/setters? That seems a bit ugly. Minus Pants fucked around with this message at 03:15 on Apr 17, 2020 |
# ? Apr 17, 2020 03:11 |
|
Minus Pants posted:I'm writing an app that does some basic network performance tests, and I'd like to be able to format some types from std in my print calls (e.g. std::net::SocketAddr). I stumbled around trying to implement the Display trait, which doesn't work because it's an external type. What's the idiomatic way to handle this? Make a wrapper type? Formatter function? code:
|
# ? Apr 17, 2020 03:29 |
|
But SocketAddr implements Display already?
|
# ? Apr 17, 2020 05:42 |
|
Ralith posted:But SocketAddr implements Display already? Sorry, I should have said I want to override the default implementation. Wrapper approach will work, I just wasn't sure if that's the Rust way to do it.
|
# ? Apr 17, 2020 06:14 |
|
Do you actually need the trait Display specifically? I often just make a write_foo method which, as a standalone function that just takes an SocketAddr as a parameter, doesn't care about orphan rules.
|
# ? Apr 17, 2020 10:12 |
|
Yeah that's true, and simpler. I need to get out of inherit-and-override thinking.
|
# ? Apr 18, 2020 07:32 |
|
To make a Display wrapper is probably the "better" approach so I would still use it e.g. in a big codebase with lots of coworkers who might accidentally use the display impl. And then there's stuff like Eq, Ord, and Hash that you usually do just have to make wrappers for. And as for (De)Serialise...
|
# ? Apr 18, 2020 13:08 |
|
I realized I don't know what a lot of the trait sections in rustdocs are as well as I thought I did. This is stuff like "Blanket implementation" and "Implementation on Foreign Types". Here's what I thought they meant: Trait implementations: Implementing foreign traits for a new struct/trait Auto-trait implementations: Foreign traits that are implemented by default for any new trait Implementors: Implementations of a new trait for foreign structs (like stuff from the standard library) Implementations on Foreign Types: Implementations of a new trait for foreign traits. Blanket implementations: ??? According to https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type, blanket implementations seem to be what I thought Implementations on Foreign Types are. But then what is the difference between the two? Also, if that is true, what is going on in the blanket implementations section of https://docs.rs/warp/0.2.2/warp/filters/multipart/struct.Part.html where everything is just stuff from the standard library (even when you click the source)? Why are those listed in these rustdocs?
|
# ? May 7, 2020 12:45 |
|
blanket implementations are generic implementations of the formcode:
code:
an implementation on a foreign type is just where you as the library author implement your trait on a type defined outside of your crate: code:
|
# ? May 7, 2020 15:45 |
|
Ok, that seems kinda minutiae-y, but understandable. But still, is there a reason why the Blanket implementation section of https://docs.rs/warp/0.2.2/warp/filters/multipart/struct.Part.html has stuff likecode:
code:
|
# ? May 7, 2020 18:29 |
|
i assume they are included so you don't have to remember the trait bounds required to receive the blanket impl or cross reference the type with the standard library traits yourself. it makes sense to me that you would want to see a summary of all of the functionality available for a particular type on the same page, regardless of whether that functionality is provided by the crate containing the type or by the standard library.
|
# ? May 7, 2020 18:46 |
|
I have a diff trait question: How do you find trait bounds in lib docs? Usually the docs and compiler messages are clear, but I'm striking out on both counts. Example: here. At the top, it defines bounds on I2C, but not I2CInterface
|
# ? May 7, 2020 19:09 |
|
that's because I2cInterface is a struct, not a generic type: https://docs.rs/crate/ads1x1x/0.2.0/source/src/interface.rs not sure why it doesn't show up in the rustdoc.
|
# ? May 7, 2020 21:22 |
|
Thank you; that sorts it out. Of note, some of the items in <> in that page are in the docs (and are linked), while most aren't. I'd assumed it not being in the docs meant it was a trait.
|
# ? May 7, 2020 21:56 |
|
Hello, I started learning Rust because this game/graphics engine called Amethyst uses it. I've been going through Rust by Example and I'm totally in love, but I was just wondering, who is responsible for Cargo staying up? Is it Mozilla?
|
# ? May 19, 2020 05:49 |
|
Stinky_Pete posted:Hello, I started learning Rust because this game/graphics engine called Amethyst uses it. I've been going through Rust by Example and I'm totally in love, but I was just wondering, who is responsible for Cargo staying up? Is it Mozilla? I don't think so, but Mozilla probably helps. There is a whole Cargo org and team, and I don't think Mozilla is a majority sponsor.
|
# ? May 19, 2020 06:22 |
|
Stinky_Pete posted:Hello, I started learning Rust because this game/graphics engine called Amethyst uses it. I've been going through Rust by Example and I'm totally in love, but I was just wondering, who is responsible for Cargo staying up? Is it Mozilla? Bet you could email them to find out.
|
# ? May 19, 2020 07:52 |
|
Mozilla Legal still makes the calls on DMCA/trademark/etc stuff, at least, and are the contact of record for privacy and data use notices.
|
# ? May 19, 2020 10:05 |
|
I have a question about kinda self-referential structs. I have a struct that generates objects, but I'd also like for it to store some references to the objects it generates. The following is a non-working example. It generates some Strings that it owns in a Vec. But I'd also like for it to have a Vec of references to some of the Strins that it has generated.code:
code:
Also, if this is possible, what should the lifetime 'a be? It seems like it should be the lifetime of Foo itself, but I don't know how to write that. I punted with 'static.
|
# ? May 25, 2020 19:35 |
|
Just as a quick answer, self-referential structs are only possible with the newish Pin infrastructure: https://doc.rust-lang.org/std/pin/index.html I don't really know how it works but if you try and fail I could take a look. It is a bit complicated though, so maybe indices is just an easier quicker bet. Also another way to do similar stuff is to not own the objs yourself but to store that somewhere else using e.g. a central memory arena or something. I believe this is the approach that e.g. the Specs entity container system (used by the Amethyst game engine) does to allow you to push and pull data while having lots of references to them in different places.
|
# ? May 25, 2020 19:55 |
|
Ok, I'll have a look at pin later. Moving the generation into its own structure makes a lot of sense, since there's no reason it has to be in in reference holder. It also clears up what 'a should be. I'll try both.
|
# ? May 25, 2020 20:15 |
|
I ended up splitting up the generation and reference storage since that made more sense. Also, I realized that the makenew method above really sucked since you can't do it twice while holding onto the references since it's a mutable borrow. I have a quick question. I have a struct containing a reference, and I'd like to use strict pointer equality to implement equality for the struct. However, it's not working. Here's the code. code:
edit: edited away extraneous detail edit2: drainpipe fucked around with this message at 20:07 on May 27, 2020 |
# ? May 27, 2020 19:50 |
|
code:
This prints true and true. The answer is that what you're actually matching on is (Foo::Bar(ref p1), Foo::Bar(ref p2)) i.e. references to p1 and p2, which are references to a. You can't move p1 and p2 directly into your ptr::eq when you're matching on the references of b and c (but explicitly dereferencing the outer pointer copies them in). Rust used to not insert refs into matches for you, then people got a bunch of errors and threw ref into odd places until it worked. So now rust does implicitly insert them in for you leading to situations like this. e: you can make things even clearer by changing your printlns to e.g. code:
gonadic io fucked around with this message at 20:10 on May 27, 2020 |
# ? May 27, 2020 20:06 |
|
Ah, ok. That makes sense. Thanks!
|
# ? May 27, 2020 20:08 |
|
I would really recommend avoid using raw pointers for your memory arena thing. Better to use std::rc::Rc imo, way WAY less chance of your unsafe blocks being incorrect and invoking UB. (because there won't be unsafe blocks)
gonadic io fucked around with this message at 20:15 on May 27, 2020 |
# ? May 27, 2020 20:11 |
|
Yeah, I realized the Rc thing, and I just switched to an owned version of the generator and store since the reference version also had some awkwardness to it. This is a completely separate part. I'm writing a toy compiler and this is for tracking identifiers. The reference is to the node on the AST that bound the identifier. This should allow me to differentiate between two identifiers of the same name.
|
# ? May 27, 2020 20:18 |
|
For a fairly low level networking app, would you stick to the standard library, or use something like Socket2 or some other crate? I'm still wrapping my head around the Rust ecosystem. I'm looking in that direction since it seems like std::net is missing some functionality. E.g. a way to enumerate u32 network interfaces for join_multicast_v6() or v4 bind methods that don't require IpAddrs.
|
# ? May 30, 2020 04:38 |
|
You can also just fill in the gaps with libc, if you don't mind complicating portability/if you want more system specific stuff.
|
# ? May 30, 2020 16:58 |
|
Used a lifetime for the first time today. It's always been a feature I've never needed to use, in my range of Rust projects. The case was trying to format strs using byte buffers in a no_std / no allocator environment. The resulting &'static str needed to be tied to the buffer arg.
|
# ? May 31, 2020 00:49 |
|
Anecdote: I’ve been learning Rust by using it for a little side project that involves parsing some text files and converting them into other formats. After a day bashing my head against the borrow checker trying to give myself the most efficient string performance with the fewest copies, I decided to just make copies whenever convenient and get the drat thing done. I suppose I learned less than I would’ve by conquering lifetimes and Copy on Write but the final result processes a typical file in 2 milliseconds, so I realized I was putting myself through hell for no reason. Something about “learning Rust” made me think I had to find the most efficient possible solution but the language is already really drat efficient even if you do things the sloppy, naive way.
|
# ? Dec 29, 2020 07:43 |
|
That's a solid allegory for programming in general: make it work first, then worry about performance.
|
# ? Dec 29, 2020 07:56 |
|
It's a common tale. People, myself included, often feel like they're "doing it wrong" but as you say, it's rarely actually needed. Having said that, god I love nom's zero copy stuff. Turning a flat file into a complex AST, all the strings only references into the original one. Luckily my files are small enough I can just read them into memory and don't have to figure out the streaming api.
|
# ? Dec 29, 2020 16:57 |
|
|
# ? May 16, 2024 18:52 |
|
gonadic io posted:It's a common tale. People, myself included, often feel like they're "doing it wrong" but as you say, it's rarely actually needed. nom is real good. I’m converting a thing from using hand-rolled parsers (because “I’m only going to need to parse a couple things!”) I’m trying to not use the macros though, have you found good resources on that? Function calls seem to be the preferred new way, but the documentation still mixes the two and most tutorials are for the macro style.
|
# ? Dec 30, 2020 03:53 |