So I'll ask this thread's first stupid question. How does ownership work with arrays, vectors, etc? If I add a Foo to an array or vector, does that array gain ownership over the Foo? Hopefully it's clear what I'm asking here, if not I can try to whip up some code to clarify.
|
|
# ¿ Jan 29, 2015 07:44 |
|
|
# ¿ Apr 29, 2024 04:36 |
Jsor posted:Looks like it moves unless you implement copy: http://is.gd/VR7qVk Thanks, that makes sense. Now that I think about it I think that has to be the case--otherwise stuff like this wouldn't work: code:
|
|
# ¿ Jan 29, 2015 09:13 |
space kobold posted:Once you get over the initial hurdle of everything bitching at you about lifetimes and learning the ~Rustic~ approach to things, like always returning just a plain bit of value and letting the caller decide if they want to box it (unique pointer to heap allocated memory), stick it on the stack, atomic reference count it, etc, things really start to click and you can appreciate the beauty of what they're trying to do with the language. Is there a guide somewhere to doing things the ~Rustic~ way? I've made my way through the Guide and Rust By Example but I haven't really absorbed stuff like what kind of value to return.
|
|
# ¿ Jan 30, 2015 20:28 |
MALE SHOEGAZE posted:I'm kind of offended by hello world being implemented with a macro. To be fair, macros much better in Rust than they are in languages like C++. IMO Rust macros are sort of like C++ templates, in that they are often ugly internally but allow for seemingly magic functions that "just do" whatever a user wants them to do. sarehu posted:Whether a macro is complicated or the function is complicated, it's still just as complicated. It's really fruity that they don't have a non-macro version, though, but probably that would operate on bytestrings and not unicode strings, or static-lifetime string slices or whatever the gently caress a string literal is. You could do something like Rust code:
|
|
# ¿ May 16, 2015 19:59 |
Gul Banana posted:Why do you need the unwrap() at the end? You don't actually need the unwrap()--but if you don't put it there, you get a warning because write() has a tag which says to warn if you don't handle the failure case. I chose to panic in failure with unwrap(), but I suppose if I wanted a strictly equivalent program to "Hello, World!", I could do one of two things:
I'm pretty sure both should work, but apologies if they don't. I'm phone-posting and the Rust Playground is very hard to work with on mobile.
|
|
# ¿ May 17, 2015 18:32 |
VikingofRock fucked around with this message at 09:20 on Jul 3, 2015 |
|
# ¿ Jul 3, 2015 00:54 |
Speaking of unsafe Rust, there's a new Book in progress which covers it extensively.
|
|
# ¿ Jul 31, 2015 15:50 |
Tarion posted:1.5 is out and 'cargo install' seems pretty cool. Agreed. It seems like Rust tooling is really taking off, which is very exciting to me.
|
|
# ¿ Dec 19, 2015 23:30 |
Bognar posted:Found this joke on the rust subreddit and enjoyed it: I love it.
|
|
# ¿ Jan 12, 2016 01:14 |
Rust is officially getting some new syntactic sugar to make error handling less painful (specificially, a ? operator and a catch edit: fixed link, and statement -> expression VikingofRock fucked around with this message at 23:34 on Feb 8, 2016 |
|
# ¿ Feb 8, 2016 21:26 |
Vanadium posted:It's a catch expression thank you very much So it is. I've edited my post.
|
|
# ¿ Feb 8, 2016 23:35 |
gonadic io posted:Does anybody want to critique my babby's first data structure? http://codepad.org/SG2ERyJn I took a stab at re-writing this a little more idiomatically, which should hopefully be helpful. I would probably write the OctreeNode as this, or as this if keeping the ull indexing is important to you. I also made a more-minimally modified version of you code here, keeping the no-impl way of doing things intact.
|
|
# ¿ Feb 19, 2016 00:29 |
You might want to do something besides data structures for your first Rust project--they often have difficult ownership relations, so you'll spend a *ton* of time fighting the borrow checker, which is tough when you first start out. I've been coding in Rust for a year and a half now and I still had trouble with the borrow checker when I was coding up some of those Octree examples. Of course, I guess you could also make the case that going straight for data structures is a good way to dive into Rust head first, in which case go for it!
|
|
# ¿ Feb 19, 2016 20:59 |
piratepilates posted:Alright so I'm learning Rust again, and I'm trying to make a program that modifies images. I'm making a function that takes an image and returns a copy of that image that is grayscale, but I can't get it to compile yet. I took a stab at this, and I'll walk you through my thought process: First step: the code that you gave has the following error: quote:src/lib.rs:10:42: 10:52 error: no method named `dimensions` found for type `image::buffer::ImageBuffer<P, C>` in the current scope Reading the note there, it seems like we were just not meeting enough of the trait bounds for `dimensions` to exist. It only exists for ImageBuffer<P, C> where P is a Pixel and C is a container which implements `Deref<Target=[P::Subpixel]>` (see http://www.piston.rs/image/image/struct.ImageBuffer.html), but we haven't specified the latter. So now we have this: code:
quote:src/lib.rs:15:17: 15:27 error: attempted access of field `data` on type `&P`, but no field with that name was found Okay, so what is `data`? I can't find it under the documentation for Pixel, which makes sense because the error is saying it's not there. My guess is that you wanted to implement this for RGB images though (given your variable names), and `image::Rgb<T>` does have a field called `data`. Now this is not generic over all Pixel types: instead, we will just implement it for `image::RGB<T>`, with the appropriate bounds on `T`. code:
quote:src/lib.rs:13:5: 20:7 error: mismatched types: This is because from_fn() returns an ImageBuffer<P, Vec<P::Subpixel>>. So we need to specify this in our return type. After doing that, there are just a few more type errors to fix (you over-specified a few things). The final version looks like this: code:
|
|
# ¿ Mar 5, 2016 22:37 |
gonadic io posted:Is this a reasonable way to pass an optional value over a FFI boundary? Passing a (nullable) pointer and then having the C# code calling another function to free it seems like lots of pain. That seems pretty reasonable to me--in fact, I think that that's how an Option would be laid out if you put #[repr(C)] on it. (The piece I'm not sure about is whether it would use a bool as the discriminant.)
|
|
# ¿ Mar 14, 2016 02:15 |
gonadic io posted:Perfect, thanks. Well if you really want to get fancy, you could do something like what hyper (an http library) does for Responses, and verify this at type level at compile time. Here's an example of what that might look like for this case. edit: To be a bit more explicit (and maybe save you some reading), the idea is to make a Variable type, which is parameterized over a type that can be either Unassigned or Assigned. Then you implement an assign() function for Variable<Unassigned>, which consumes the Variable<Unassigned> and returns a Variable<Assigned>. Because of this consuming, you can guarantee that a Variable can be assigned at most once, and because there is no assign() function for Variable<Assigned>, you can guarantee that you can't re-assign a variable once it has been assigned. VikingofRock fucked around with this message at 07:04 on Mar 21, 2016 |
|
# ¿ Mar 21, 2016 06:49 |
Actually now that I think about it a little more, you probably want this to work at run-time, not compile time. You can either use the above approach and Any to do run-time type checking, or you could just write a wrapper around an Option (which is a lot simpler, but loses the ability to do compile-time checking). I guess it depends on your use case (I haven't really read through your code).
|
|
# ¿ Mar 22, 2016 00:39 |
Jsor posted:Though the immediately obvious problem that jumps out at me with this scheme is it makes loops problematic if you need to assign in those. It's not just in loops--you can't modify x in place because when you assign you change the type. So when you modify it you need to do something like what I did in my linked example code on like 42. That will work in loops (so long as you only assign once), but yeah it's pretty awkward. So maybe writing a wrapper is nicer anyways. It is a neat trick though--I was blown away when I saw it in hyper. edit: slightly better example of loops: http://is.gd/6i8ELg VikingofRock fucked around with this message at 04:19 on Mar 22, 2016 |
|
# ¿ Mar 22, 2016 04:14 |
Jsor posted:Oh yeah, you can do that. But I mentioned loops specifically because for most other constructs you can use a let rebind pattern: I often do something similar to "freeze" a variable. It's useful when there is some non-trivial initialization to a variable, but then the variable will not be mutated after the initialization. Like this: code:
|
|
# ¿ Mar 22, 2016 05:05 |
Yup, you got it (in your edit).
|
|
# ¿ Mar 23, 2016 18:35 |
gonadic io posted:Are people happy for me to continue asking this stuff here? I don't want to dominate the thread, I guess I could go to the terrible programmers yospos thread or the rust IRC instead. Definitely keep posting here, I'm learning a lot from thinking about the issues that you are presenting and people's responses to them. Also the Rust IRC is a fantastic resource. If you post a question here and no one answers it, you should ask IRC (and then post their response here so we can learn from it too).
|
|
# ¿ Mar 27, 2016 22:18 |
gonadic io posted:I have lot of fixed sized arrays. Functions that return [T; 8] etc. In my experience, working with arrays in Rust totally sucks and will likely continue to suck until they add dependent typing (which is planned, but which seems somewhat far-off). For now, I'd just use slices and save yourself the headache.
|
|
# ¿ Apr 4, 2016 22:22 |
Jsor posted:Wait, what? I thought Dependent Typing was a No Go for Rust. I mentioned it a few times in discussions on the issue tracker, and people mentioned they abandoned the idea because it wasn't a "good fit". Which is a shame because I'd really love it. Especially because first-class dependent typing isn't much work away from a full-on theorem prover which means you can prove some pretty strong guarantees for your implementations. (Unless Dependent Typing is a consequence of HKTs? I feel like people wouldn't have vehemently denied plans for dependent types if that were the case though, given that HKTs are very much in the works, though they don't think they can get it done in 2016). Okay so I looked into this a little more, and it seems like full-on dependent typing is pretty controversial, but there is at least a push for type-level numerics (which would make arrays much nicer to work with). Here is the most recent issue about it AFAIK.
|
|
# ¿ Apr 5, 2016 19:12 |
Jsor posted:
No longer true on nightly! Specialization allowed for this to be fixed.
|
|
# ¿ Jun 8, 2016 00:17 |
syncathetic posted:I don't think its possible for the first case to be null-pointer optimized. Consider https://is.gd/HtdE2R . What value/address does list_end return if the final Empty value isn't on the heap? Maybe I'm misunderstanding something here, but I think the idea is that you would represent List::Elem as a (i32, non-null address), and List::Empty as (32-bits-of-whatever, null). That way you can avoid having another byte in each List for the enum discriminant, because you can tell whether it is List::Empty or List::Elem by the value of its second field. So to answer your question the final List::Empty value would still be on the heap and you can still take it's address, because all the null-pointer optimization does is make the representation of each List more efficient. As for the unsafe stuff, my guess is that memcpying into non-C-like enums is undefined behavior, because the layout of non-C-like enums is undefined. But I'm not totally sure about that.
|
|
# ¿ Sep 23, 2016 20:17 |
Arcsech posted:1.12 is out, and I am irrationally excited about the new compiler errors that are actually understandable: Nice! I didn't even know this was in the pipeline.
|
|
# ¿ Sep 29, 2016 20:18 |
gonadic io posted:Or even better I could make a macro that's invoked like: Definitely do this, then post it here. This sounds awesome.
|
|
# ¿ Mar 23, 2017 00:54 |
gonadic io posted:Generalising the return type of main just got merged: https://github.com/rust-lang/rfcs/blob/master/text/1937-ques-in-main.md Awesome! This will make writing a lot of small programs and example code much cleaner.
|
|
# ¿ Jul 18, 2017 18:32 |
Ralith posted:Rust just got some really sweet enum memory layout optimizations. Highlights: This is extremely cool!
|
|
# ¿ Nov 21, 2017 20:45 |
Dominoes posted:Why do I need to explicitly declare &str in this case? Shouldn't applying & automatically do that? &replacement could be a &str or a &String (or a &&str or a &&String etc), and if this is the only time you use replacement rustc doesn't know which one to infer it as. Looking at the docs for the regex crate, it looks like the signature for replace_all is generic in its second parameter: pre:pub fn replace_all<'t, R: Replacer>( &self, text: &'t str, rep: R ) -> Cow<'t, str> I think this may be intentional, since in the future someone could theoretically go add an impl of Replacer for String (or add an impl of FnMut(&Captures) -> String for String), which would cause your code to break. So my guess is Rust purposefully makes you type out the type here for that reason.
|
|
# ¿ Mar 17, 2018 01:18 |
Walh Hara posted:I already knew this, but this seems extremely dumb to me? Do I really need to fill the array with garbage (when I declare the variable) so I can replace this garbage in the for loop with the correct values? I was assuming there must a be better way. You have a few options. Off the top of my head:
Personally, I'd go with the 3rd option. If you want to see what this looks like in practice, or if you want to play around with it, I wrote up some prototypes on the Rust playground.
|
|
# ¿ Mar 30, 2018 02:19 |
Dominoes posted:Yo bros. Trying to do some matrix mult; ref the thread's title. Any wisdom from bros on how to make it compile? I don't have a lot of experience with the ndarray crate, but it looks like dot() takes its argument by reference. So try putting an & in front of the array![...] in the definition of f? If the borrow checker gives you crap about that value not living long enough, take the argument to dot() and give it its own let binding. Whenever I get errors about the expected type of an argument, I always go and double check exactly what that argument is expecting and the type of what I'm giving it, and usually that solves it.
|
|
# ¿ Apr 22, 2018 04:52 |
Dominoes posted:I just moved &s around rando until it worked. Now you are programming like a true Rust expert! e: seriously though congrats on getting it to compile! It'll (mostly) click soon, don't worry.
|
|
# ¿ Apr 22, 2018 05:17 |
This is a fun bit of obfuscated rust from reddit:code:
|
|
# ¿ Jun 7, 2018 03:05 |
Dylan16807 posted:No, "integer constant" and "floating-point constant" are their own types. I guess that makes some sense, but it's pretty wild to me that this code:
code:
|
|
# ¿ Sep 30, 2018 07:46 |
Helicity posted:I already had imposter syndrome - I don't need a language to tell me I suck. Just remember that memory management is hard, and even people who have been writing C for decades get it wrong. Just look at the countless buffer overflow / use after free bugs that have gotten CVEs over years. So rustc isn't telling you that you suck, it's helping you catch the mistakes that everyone makes.
|
|
# ¿ Nov 14, 2018 04:20 |
Could you just implement a ToItem trait (or AsItem, if you are returning a borrowed "view") for all of the things that you want to convert to an item? Then you could either take a ToItem in you generic function, or you could call to_item() ahead of time. (playground link)
|
|
# ¿ Mar 4, 2023 21:19 |
gonadic io posted:From the perspective of learning, and I've taught several different colleagues from scratch, I feel like the knowledge you need for rust is basically half C++ half Haskell. This is very accurate I think. My Rust story is that around 2015 (or so?) I was writing C++ for work and Haskell for fun, and was pining for a C++ that took some of the nicer ideas from Haskell and which had better defaults. I googled around a bit to see if such a thing existed and found the Rust beta.
|
|
# ¿ Apr 30, 2023 15:11 |
street doc posted:I want to take an image, split it, send it to 16 threads to process, send results from that to 4 threads to process and then repeat all over again. Rayon is definitely what you want here. The result might not even be that different from the single-threaded code. E: if it works for your use case, I'd probably first just try doing something like image.par_chunks(image.size() / 16).reduce(empty_processed_chunk, combine_processed_chunks). Let rayon figure out the number of threads to use. VikingofRock fucked around with this message at 05:46 on May 10, 2023 |
|
# ¿ May 10, 2023 04:50 |
|
|
# ¿ Apr 29, 2024 04:36 |
Jo posted:I'd not heard of this, but it might save me a lot of trouble. Thank you! It looks like rtrb's Producer and Consumer implement Write and Read, respectively, so I think it might do what you want here? Worth at least trying IMO
|
|
# ¿ Sep 5, 2023 00:06 |