Crust of Rust: Lifetime Annotations

Поделиться
HTML-код
  • Опубликовано: 20 июл 2024
  • In the 2019 Rust Survey, a lot of people were asking for video content covering intermediate Rust content. So in this first video (possibly of many), we're going to investigate a case where you need multiple explicit lifetime annotations. We explore why they are needed, and why we need more than one in this particular case. We also talk about some of the differences between the string types and introduce generics over a self-defined trait in the process.
    And don't worry, I know that what we're implementing exists in the standard library :)
    0:00:00 Introduction
    0:03:36 Start a rust project
    0:05:20 Struct and method definitions for StrSplit and first test
    0:09:32 How you decide between a library and a binary
    0:10:58 Start implementing StrSplit
    0:16:15 When to use match vs if let some
    0:17:10 Doesn't compile! missing lifetime specifier
    0:20:33 Can I be wrong by specifying lifetimes?
    0:21:25 Anonymous lifetime '_
    0:23:10 Order lifetimes based on how long they are
    0:25:18 Anonymous lifetime '_ (with multiple lifetimes)
    0:26:52 Compile error: lifetime of reference outlives lifetime of borrowed content
    0:34:45 Static lifetime
    0:41:27 Bug when a delimiter tails a string
    0:48:07 What is the ref keyword and why not &
    0:51:36 What's the * on the left of remainder
    0:52:46 What is take() doing
    0:54:48 Mutable references are one level deep
    0:55:39 Solving a hang with as_mut()
    0:57:49 Multiple lifetimes, implementing until_char
    1:03:19 Difference between a str and a String
    1:08:15 Multiple lifetimes (continued)
    1:15:24 Generic delimiter (Delimiter trait)
    1:23:14 char length utf8
    1:25:30 Standard library split
    1:27:39 Q&A
    You can find the final code at gist.github.com/jonhoo/2a7fdc....
    You can watch the live version with comments at • Lifetime Annotations (...
  • НаукаНаука

Комментарии • 259

  • @FlaviusAspra
    @FlaviusAspra 4 года назад +526

    This is exactly the level of tutorials that we need. Not the "hello world" all over again.

    • @fgriane4589
      @fgriane4589 Год назад +6

      helo ser now write brintln!("helo ser from india")
      gud ser gud now we learned how to use brintln
      in our next lecture we will learn what is == and !=

    • @ParthKohli
      @ParthKohli 3 месяца назад +6

      @@fgriane4589could have gotten the point across without the racist undertone.

  • @tryashtar
    @tryashtar 9 месяцев назад +20

    Re-inventing parts of the standard library is such a good motivating example! I really can't click with contrived "foo/dog/shape" tutorials. Your explanations of the problems that come up are also very clear. These videos kept me from giving up on understanding rust, and I'm very grateful!

  • @ragy1986
    @ragy1986 Год назад +19

    One of the few videos online that not just a regurgitation of the Rust book. Love your work 👌

  • @nickkallis8073
    @nickkallis8073 4 года назад +131

    3:36 start a rust project
    5:20 struct and method definitions for StrSplit and first test
    9:32 how you decide between a library and a binary
    10:58 start implementing StrSplit
    16:15 when to use match vs if let some
    17:10 doesn't compile! missing lifetime specifier
    20:33 can i be wrong by specifying lifetimes?
    21:25 anonymous lifetime '_
    23:10 order lifetimes based on how long they are
    25:18 anonymous lifetime '_ (with multiple lifetimes)
    26:52 compile error: lifetime of reference outlives lifetime of borrowed content
    34:45 static lifetime
    41:27 bug when a delimiter tails a string
    48:07 what is the ref keyword and why not &
    51:36 what's the * on the left of remainder
    52:46 what is take() doing
    54:48 mutable references are one level deep
    55:39 solving a hang with as_mut()
    57:49 multiple lifetimes, implementing until_char
    1:03:19 difference between a str and a String
    1:08:15 multiple lifetimes (continued)
    1:15:24 generic delimiter (Delimiter trait)
    1:23:14 char length utf8
    1:25:30 standard library split
    1:27:39 Q&A

    • @jonhoo
      @jonhoo  4 года назад +45

      Wow, this is excellent, thank you! Mind if I copy this into the video description?

    • @nickkallis8073
      @nickkallis8073 4 года назад +16

      @@jonhoo Of course i don't mind! :)

  • @mottosson
    @mottosson 4 года назад +110

    This was excellent. 90-ish minutes are perfect length for this kind of stream. I also liked the level of difficulty of the topic. I'm not saying stop making longer streams, just more like this! :) Thanks a lot!

  • @jaumearus
    @jaumearus 3 года назад +6

    Finally, I've figured out what Rust lifetime annotations are, and how to use it. I've also liked the TDD way you have used here. Congratulations on your awesome job with this tutorial. Thanks a lot!

  • @frcrr
    @frcrr 3 года назад +2

    I almost gave myself a stroke trying to wrap my head around these lifetime things. This video literally saved me from it. Clear, concise, relevant.

  • @halbeard2996
    @halbeard2996 4 года назад +41

    Great lesson. The build up towards the std implementation is logical and gives an impression of how one would come up with a good implemention by iterating towards more general concepts.
    Would be awesome if you could find more examples that tie into the standard library in a similar way. One of the main hurdles after finishing some beginner course like the book is getting through the jungle of all the existing std traits. More so in rust than in other languages' standard libraries imo.

  • @MrJlgerber
    @MrJlgerber 4 года назад +34

    Fantastic content as usual. Your videos on Rust are one of the most valuable resources out there for those of us with a handle on the basics. i eagerly look forward to new ones. This focus on intermediate Rust content, along with its shorter length, is really really valuable IMHO. Keep up the great work!

  • @jordanseiler9546
    @jordanseiler9546 4 года назад +8

    Awesome stream! I've learned so much about Rust from your videos and I really hope you decide to make more intermediate content like this. I hope you're staying safe and healthy in these crazy times.

  • @TheGokhansa
    @TheGokhansa 4 года назад +7

    Great video! In addition to learning on lifetimes, I also really enjoyed side notes you provided along the way, like str vs String, and your answers to questions.

  • @thetrungtran686
    @thetrungtran686 Год назад +3

    I am grateful for the valuable information and knowledge you are sharing with the community. Thank you so so much, Mr. Gjengset.

  • @asaaki
    @asaaki 4 года назад +11

    Just watched it and it was awesome. This was probably the most practical and approachable way of getting a better understanding of lifetimes. Thank you for your time and effort in doing this. 🙇🏻‍♂️

  • @DrIngo1980
    @DrIngo1980 4 года назад +1

    @ Jon Gjengset
    Thanks for your videos. I thoroughly enjoy them and they teach me a lot. I'm a seasoned programmer of nearly 20 years with a huge variety of languages that I worked in, but I am pretty new to Rust (only started to really get into it last December) and your videos are perfect for me. They fill the knowledge gap that I felt I have after reading through the official Rust book. Please keep up the great work. It is really appreciated. Thank you.

  • @christopher8641
    @christopher8641 11 месяцев назад +2

    I once again come back to this video, I once again learn something new. As always, really great stuff Jon. Applicable teaching for various levels of understanding is quite a skill. Thanks again for making these

  • @pmmeurcatpics
    @pmmeurcatpics Месяц назад

    I used to just immediately panic whenever a lifetime-related error came up and make it shut up with Strings and whatnot, but I think your video made me really understand lifetimes for the first time ever, and realize that the errors weren't too scary after all. It feels a bit entitled to complain about Rust errors (which are notoriously clear compared to some other languages) but I guess the ones regarding lifetimes could be made somewhat less intimidating-looking. Anyway, thank you for this amazing video, this is the first video of yours that I watched, and I'm really looking forward to catch up with the rest of them :)

  • @letsgetrusty
    @letsgetrusty 3 года назад +2

    This content is gold! The people asking questions are reading my mind!

  • @kelleyvanevert
    @kelleyvanevert 4 года назад +1

    Awesome awesome :) Good explanation and with many small tidbits of other useful info while still staying on track till the end!

  • @donpeppinoo7152
    @donpeppinoo7152 7 месяцев назад +2

    Super grateful for these videos that provide so much value to me even after 3 years!

  • @daniellambert6207
    @daniellambert6207 4 года назад +15

    1:33:11 I'm very glad for the digestible length!!! Hoping you continue the Crust of Rust series :)

  • @Analogity
    @Analogity Год назад

    Wow this video is full of great stuff. I appreciate you taking the time to make all these amazing videos!

  • @johnradley7176
    @johnradley7176 4 года назад

    Excellent. Reading the book is so dry, but you brought the subject of lifetimes alive, and made it appear quite straightforward. Thanks

  • @maxheap
    @maxheap 4 года назад +2

    No matter how much experience you have, starting with Rust can be a struggle.
    The Curst of Rust episodes are very nice to level up to the advanced beginner / intermediate level in a practical way, Kudos Jon for it. I hope you keep them coming in the future :D

  • @markday3145
    @markday3145 4 года назад +4

    I thought I had a decent grasp of lifetimes and references. But I learned several things. Thank you! I appreciate your teaching style, and the level of difficulty of these Crust of Rust videos.

    • @jonhoo
      @jonhoo  4 года назад +1

      I'm glad you found the level about right! It's tricky to strike the right balance :)

  • @pixel8x
    @pixel8x 4 года назад +3

    This was super helpful. Thank you! I thought I had a pretty good handle on lifetimes before but I learned some pretty valuable things from this talk :)

  • @Baconator1368
    @Baconator1368 4 года назад

    This video was fantastic. I tried watching Doug Milford's video on lifetimes, and it seemed adequate, but he was essentially just reading the chapter on lifetimes from the book and writing code examples. The book did a good job introducing lifetimes to me, but this video really solidified some confusing concepts about them (especially the part where you covered multiple lifetimes and when they might be needed), and served as a *supplement* to the book rather than a simple reiteration of the book.

  • @arturh85
    @arturh85 4 года назад +8

    Thank you for this! Really good example that helped me understand lifetimes :)

  • @samirsaeedi74
    @samirsaeedi74 4 года назад +1

    Thank you very much. Intermediate level and shorter videos is exactly what I needed.

  • @bergercookie12
    @bergercookie12 4 года назад

    These tutorials are a real gem! Thanks for explaining all this

  • @orki974
    @orki974 2 года назад

    Amazing stuff, thank you for taking the time to rediscover the standard implementation. It's really helpful for the intermediate understanding of Rust. And you're right, Rust is not really that complicated to read compared to other language but, especially for the lifetime feature, things get completely crazy for a programmer coming from JavaScript ^^'

  • @tenzin1672
    @tenzin1672 3 года назад

    Thank you! Great video, more than half way through the Rust book and this was very good to keep the learning going!

  • @Gordolone
    @Gordolone 3 года назад

    I am seeing this from the future, omg, this is a gem. Thank you so much, I was really confused about managing lifetimes. Watching videos that explain lifetimes without going further away from the examples the BOOK shows is really not helpful. This has helped me a lot.

  • @jacobzuiderveen6047
    @jacobzuiderveen6047 4 года назад +1

    Thank you so much for this. An hour into the video, and I understand both how simple it can be to implement a custom iterator *and* cleared up a misconception of what lifetime annotations are doing. It's *not* saying that all struct StrSplit

  • @FelipeMenezesMachado
    @FelipeMenezesMachado 11 месяцев назад

    I’d like to have watched this video one year ago, it would have made my life much easier 😂
    This is definitely going into my list of recommended material for learning Rust! Thanks a lot!

  • @nilshaberstroh2705
    @nilshaberstroh2705 3 года назад +11

    This time I actually got lifetimes. I believe 😅
    Honestly, this is the best explanation I've seen. And I've seen quite a few.

    • @BboyKeny
      @BboyKeny Год назад +1

      Do you still know what lifetimes are?

  • @duncan-dean
    @duncan-dean 4 года назад

    Thoroughly enjoyed this! Great explanations.

  • @someoneelse6976
    @someoneelse6976 Год назад

    Thanks for the video, Jon! It's fun, pleasant and profitable to watch! : ))

  • @EnzoLuisStrongoli
    @EnzoLuisStrongoli 4 года назад

    love your videos Jon! I learned more here than using other resources

  • @jRsqILVOY
    @jRsqILVOY 4 года назад

    The explanation of why two lifetimes were needed (and the benefits of avoid String allocation) were great!
    I hit this exact issue when I wanted to implement string split with regex, that also returned the delimiter groups in between (i.e. so the regex could be like "+|-|(|)" etc. and I could see which one it was). It's a pain that isn't in the standard library like it is for regex in Python.

  • @knha
    @knha 3 года назад

    Thank Jon Gjengset. This is what i looking . Nice explain and the example is very good.

  • @alexandredamiao1365
    @alexandredamiao1365 10 месяцев назад +1

    This is just fantastic content! Thank you for your time!

  • @klaymanke
    @klaymanke 2 года назад

    Thanks man, very cool to see this types of tutorials.

  • @drewmakes9274
    @drewmakes9274 4 года назад

    Jon, I just set up arch and copied a lot of your config files :) What an eye opening rabbit hole! Also, this is the content for me, very accessible with a lot I still need to fully grasp. I feel intuition forming with content like this. THANK YOU!

    • @jonhoo
      @jonhoo  4 года назад +1

      I'm very glad to hear that! Yeah, config files are a rabbit hole for sure, hehe. Hopefully you'll find upcoming sessions educational as well :)

  • @thisisreallyme3130
    @thisisreallyme3130 2 месяца назад

    TY. So much of Rust is explained linear (here is how it works, just do this in order). But iterating on a project is so much more helpful. Cheers.

  • @maxterrain
    @maxterrain 6 месяцев назад

    This is a very helpful tutorial. Other than the length, everything about it is perfect.

  • @minirop
    @minirop Год назад

    Best learning material for lifetimes I found. Thanks.

  • @xeoneux
    @xeoneux 4 года назад

    Thanks, Jon! Fantastic video and explainations :)

  • @abdallahalsahhar9511
    @abdallahalsahhar9511 4 года назад

    Two of the things I struggled with in rust are references (like why we need *remainder) and dealing with Options especially ref mut , Thanks for your time and effort

    • @tsalVlog
      @tsalVlog 4 года назад +1

      I'm still struggling a bit with these myself, but it helps to think of refs like pointers, if you've ever worked in C / Go / Java. Options I think I am starting to understand, but still run into issues around generics.

  • @mrvectorhc7348
    @mrvectorhc7348 4 года назад

    Good stuff, thank you for the stream, it was really helpful!

  • @lafuenteposible
    @lafuenteposible Год назад

    Awesome content! Thank you for putting this out! 🎉🎉🎉

  • @carloslanderas
    @carloslanderas 4 года назад

    Amazing!!. Thank you very much for this content and keep up the good work!.

  • @MegaSeppHuber
    @MegaSeppHuber 4 года назад

    Awesome! Thanks a lot. This was well build up and really well done.

  • @Jesse_Carl
    @Jesse_Carl 7 месяцев назад +3

    Excellent! An hour ago, I didn't understand the problem lifetimes were trying to solve. After this example and explanation, I immediately see how I can use lifetimes to refactor my code to avoid a bunch of copies.

    • @Evan490BC
      @Evan490BC 4 месяца назад

      I think you meant to say "the problem lifetime *annotations* were trying to solve." Lifetimes exist whether we notice them or not. Also in C++.

    • @Jesse_Carl
      @Jesse_Carl 4 месяца назад

      @@Evan490BC This isn't actually true. Lifetimes are a self enforced rule about how memory can and can't be used. But memory is just 1s and 0s and a pointer is just a number. You can absolutely write a program which dereferences pointers after the memory has been deallocated or the stack frame has been popped. This is generally a bad idea because it will cause unpredictable behavior or segfaults. That is why rust chooses to impose lifetimes on pointers. But depending on the operating system, and the internals of the compiler, it is completely possible to write a deterministic program which ignores lifetime rules and dereferences a pointer after the memory has been deallocated.

    • @Evan490BC
      @Evan490BC 4 месяца назад

      @@Jesse_Carl I agree. I think you are confusing lifetimes, which is a property of an object with lifetime *annotations*, which are user-defined specifications and guarantees.

    • @Jesse_Carl
      @Jesse_Carl 4 месяца назад

      @@Evan490BCAn "object" is already a user defined specification. No such thing exists in assembly code or in memory. In the same way, no such thing as a lifetime existing, except for insofar as it is enforced by the language or enforced by the programmer. Lifetimes do exist in rust, but don't exist in C unless you choose to respect them. Lifetime annotations also exist in Rust, and don't exist in C.

    • @Evan490BC
      @Evan490BC 4 месяца назад

      @@Jesse_Carl The formal definition of "object" is as a formated area in memory; a bit sequence (see Stroustrup's books). It's different than the OO definition. We agree on the others.

  • @DiogoVKersting
    @DiogoVKersting 3 года назад

    This was so good I think I'm going to watch it again.

  • @benedyktjaworski9877
    @benedyktjaworski9877 4 года назад +2

    One nitpick to your explanations - IMO explaining 'static lifetime as ‘living to the end of the program’ is misleading - eg. all owned values not bound by other lifetimes will satisfy the 'static lifetime - eg. if you accept some generic type that is bound by a trait and a 'static lifetime, then you’ll be able to pass owned values there (even though they’re owned and will be deallocated at the end of the block).
    I think a much better explanation would be to say that 'static lifetime means that whatever you have that satisfies it will be valid *as long as you hold on to it* (but it might be deallocated later). If that thing is a reference (any &'static _) then it’s true it means that the memory behind it will be valid to the end of the program (because nobody can deallocate the memory pointed to by static references, it is always borrowed), but if you have T: AsRef + 'static, then you might have just owned String - you generally will deallocate the String when you go out of scope (you *might* as well leak it, making it valid to the end of the program but generally you won’t) - but as long as you hold on to the String, its memory is valid, and thus String indeed is valid type satisfying AsRef + 'static - and because of that actually satisfying AsRef + 'a for any 'a. So 'static on a variable means that if you hold on to that variable, you won’t see its memory deallocated, for as long as you wish (if it’s a reference, the memory will live forever, if it’s an owned value - it’ll get deallocated only after you drop it).
    This misunderstanding (that 'static always means ‘living to the end of the program’) lead to this soundness issue in Libra: github.com/libra/libra/pull/1949

    • @jonhoo
      @jonhoo  4 года назад +1

      Yup, that's a good point! I agree that phrasing it as "'static means you are allowed to hold on to it for as long as you wish" is better.

  • @ShyamBaskaranphi
    @ShyamBaskaranphi 4 года назад +2

    Awesome video.. Thank you so much. I am learning a lot from you.

  • @dogman_2748
    @dogman_2748 10 месяцев назад +1

    Thank you very much for making these videos!

  • @fnvtyjkusg
    @fnvtyjkusg 4 года назад

    Thanks for the tutorial, this was incredibly helpful!

  • @denispapin5421
    @denispapin5421 3 года назад +1

    What might be a little confusing for people, is that Rust does auto dereferencing in some cases. Jon explains things perfectly but keep in mind the Rust changes remainder[ ] into *remainder[ ] automatically, so if we follow step by step the type of the &remainder[ ] expression, we get : remainder (&mut &'a str) --> *remainder ( &'a str ) (auto deref) -> *remainder[ ] --> (str) --> & *remainder[ ] ( &'a str ). This is why Jon says that the type of the right side is &'a str
    On the left side, there is no auto defer, so we must use *remainder to get a &'a str

  • @user-yj7db8be6x
    @user-yj7db8be6x 2 года назад

    Perfectly fit my need during my Rust journey

  • @ComradeHarry
    @ComradeHarry 4 года назад +1

    Another great video 👏🏽, I really like the shorter format.

  • @mohamedgharbi7582
    @mohamedgharbi7582 4 года назад +1

    i really like this video format thanks

  • @pixel8x
    @pixel8x 4 года назад

    Also just regarding the comment about Rust being more difficult to read than other languages. I can see what the commenter means in that Rust does introduce some additional symbols that might make it look more "noisy" and this does take some getting used to and can take longer to parse. However, one of the things I like most about Rust is that it encodes so much more information than other languages do. As the programmer you get to encode your intent far more explicitly in Rust (if you want to), and as the reader of this code you get read access to this intent as well. I really liked your answer to the question. In practice reading Rust gets easier over time, and the expressiveness generally becomes more of a benefit than a cost.

  • @tsalVlog
    @tsalVlog 4 года назад +54

    I want to echo the request for common idiomatic structure implementations in Rust. :)

    • @jonhoo
      @jonhoo  4 года назад +3

      Could you elaborate a bit on what you mean by that?

    • @driedurchin
      @driedurchin 4 года назад +17

      @@jonhoo I think he's getting at the "rusty" way of doing things, so common tasks like error handling, destructuring, and stuff like that. In my experience there's often a few ways to go about most things, and in my early days I ended up doing things "wrong", meaning it worked, was safe, but was ugly and not the way an experience rust programmer would do it.

    • @pixel7038
      @pixel7038 3 года назад

      for a second i thought u we're talking about php

  • @toantruong9533
    @toantruong9533 Год назад

    Awesome stuff. Thank you for these videos.

  • @someperson9763
    @someperson9763 4 года назад

    I would love to see a video on how you mock external dependencies. Or maybe unit testing practices in general when you have an application that does impure things like read or write to a database

  • @barkanido
    @barkanido 4 года назад

    Excellent video! Thanks Jon.

  • @vikramdawesome
    @vikramdawesome 4 года назад

    Amazing helpful stream, keep up the good job👏👏👏👏👏

  • @karthiknedunchezhiyan1171
    @karthiknedunchezhiyan1171 3 года назад

    really nice explanations, keep going!

  • @arthurbelleville1366
    @arthurbelleville1366 7 месяцев назад

    Thanks a lot for this live, it's awesome 🤩

  • @TheLegendSpeaker
    @TheLegendSpeaker 3 года назад

    Thanks for this video! It was amazing!

  • @jeanielam4260
    @jeanielam4260 6 месяцев назад

    I am at 29:00 and scratching my head about why the E0312 error didn't show up for me. Looks like it's because I am on compiler version 1.74.1 but the error code has been marked as "no longer emitted by the compiler" since 1.63.0 from a PR called "Remove migrate borrowck mode". Not sure what's the implication there yet but just wanted to point it out in case anyone else is also confused.
    And thank you for creating all these wonderful content! I have only watched like

  • @TheSrishanbhattarai
    @TheSrishanbhattarai 4 года назад +4

    Thanks for streaming this, Jon. I missed it live but it was fun to watch this nonetheless.
    I do have a question if this is even the right place to ask - when you replaced the "&'a str" delimiter with the Delimiter trait, how is Rust able to infer lifetimes in that case? If I understand correctly, traits monomorphosize into individual implementations for each type they are implemented on. (&str and char in your case).
    After that happens, does the situation not reduce to the same issue of lifetimes as before you had the traits? What information does Rust have now that it did not have before, allowing us to elide lifetimes?

    • @jonhoo
      @jonhoo  4 года назад +4

      Think of it this way: once we have `D`, we never need to name the second lifetime. `D` captures the type of the delimiter _including any lifetimes it may hold_.

  • @rcurtis6175
    @rcurtis6175 4 года назад

    Really love the intermediate level stuff.

  • @haowenyu3573
    @haowenyu3573 2 года назад

    Thank you for such a great video!

  • @michael37799
    @michael37799 3 года назад

    Thank you for making this video.

  • @GoogleUser-id4sj
    @GoogleUser-id4sj Год назад

    This is very useful! Thanks much.

  • @Bob-nc5hz
    @Bob-nc5hz 3 года назад

    Around 23:00, the original statement was pretty much correct, you can write e.g. `Vec` to tell the compiler that you want a `Vec` and have it guess what the item type is, and that's basically what `'_` does as well.
    `_` in *patterns* is a completely different beast, the compiler doesn't really guess anything, it asserts that there's an item there then discards the item.
    Also at 1:06:20, memcpy is not free but it's pretty cheap and common, semantically Rust passes arguments using memcpy (whether Copy or !Copy). The copy overhead might be a factor for *very large* strings, but it's really the allocation itself which is deadly: some system memcpy will be faster than others, but odds are we're talking tens of GB/s, whereas allocations, we're probably talking millions in the very best case scenario (an allocator with threadlocal arenas and room in their size classes will probably need a few hundred cycles), and as low as a few tens of thousands.

  • @azriellector7757
    @azriellector7757 4 года назад

    Up until now, this video has 610 likes and 0 dislikes. That's quite amazing!

  • @adventuresinbytes
    @adventuresinbytes 2 года назад

    I had no idea until this video that you could put contraints on lifetimes relative to each other.

  • @ash2x3
    @ash2x3 3 года назад

    This really made lifetime annotations click for me, thank you :)

    • @jonhoo
      @jonhoo  3 года назад

      So glad to hear that! :D

  • @SczyPT
    @SczyPT 4 года назад

    Thank you! Awesome video!

  • @zsling
    @zsling 8 месяцев назад

    Thanks, bro. Great work!😉

  • @KevinDay
    @KevinDay 4 года назад +3

    Ironically, while you had a hard time finding an example where this was necessary, I ran into these problems in my very first rust program and had no idea how to fix them!

    • @jonhoo
      @jonhoo  4 года назад

      Huh, that's interesting. You had a case where multiple, independent lifetimes were necessary? Can you share some of the details of that API?

    • @KevinDay
      @KevinDay 4 года назад

      @@jonhoo Well, there may have been other ways to solve it; perhaps I should revisit it to see what I can do now. I was trying to write a FizzBuzz, but I wanted to see if I could get it faster than a Java version of the same program (never did btw). I realized that the console was affecting the speed drastically, so I decided to try to add all of the lines of output to a Vec instead of actually printing them. But I had the hardest time getting the str representations of the numbers to live as long as the Vec.

    • @jonhoo
      @jonhoo  4 года назад +4

      Ah, for that you'd probably need to use `String`, since you are _generating_ the strings, and then storing them for later. If you tried to use a reference there, then the strings you generated would be de-allocated as you moved on to later numbers, and those references would become invalid. I think in your example above, there should be _no_ references involved :p Of course, realizing that isn't always easy!

  •  3 года назад

    Thanks for sharing.
    It would be great if you can also cover "function pointers" in contrast with Fn, FnMut, and FnOnce traits.

  • @dantenotavailable
    @dantenotavailable 4 года назад

    It may sound kinda dumb, but i'd like to see something about common/conventional ways to break up a rust project possibly including multi-project workspaces. Also considerations for using CI/CD on a rust project.
    Things i (think i) know :-
    * examples directory - place to put source files showing how to use your library. I also use this in early stages to do micro-experiments that will eventually incorporate into the main project (e.g. how do i use libgit2 to clone a repository?). Not sure if there's a better way to handle this but this seems to work.
    * tests directory - not sure what the intended difference between this and #[test] is but i know it exists...
    * Workspaces - in a top level directory is a specially formatted Cargo.toml which references the child projects. Building in that directory builds all the projects.

  • @mikerodent3164
    @mikerodent3164 4 месяца назад

    Wow. This is just what I need at my stage of Rust. But in saying that I'm not saying I "now understand", as many commenters seemingly do. I grasp a bit more. `ref`! Wow, I'm not sure, in my fumblings, that I've ever had occasion to use that, despite having read The Book twice now.
    What's fascinating to me is that even Jon, who "usually does longer vids on more complex Rust" (!) takes blinkin' ages, and lots of mental effort, to find out how to accomplish this (pretty trivial) utility. He himself is, there is only one word for it, **wrestling** with the compiler, and since Rust's ownership, borrowing and lifetime arrangements are stringently NECESSARY (for safe code for the 21st century) he is **wrestling with algorithmic reality**. More of this!

  • @cuentadeyoutuization
    @cuentadeyoutuization 3 года назад

    amazing, this is gold!

  • @flyingsquirrel3271
    @flyingsquirrel3271 4 года назад +2

    1:21:22 Can't a single `char` in rust be longer than 1 byte? I think we would actually have to use the `len_utf8` function of the `char` here to be correct.
    EDIT: Yeahhh I should have watched a bit further before writing this. It get's addressed 2 minutes later :).
    You are an amazing teacher btw. Thanks a lot for making these videos!

  • @xrafter
    @xrafter 2 года назад

    I learned about how to Pattern

  • @Marlon-ld2jx
    @Marlon-ld2jx 2 года назад

    Very nice video!

  • @n.d.9796
    @n.d.9796 3 года назад

    Great video, thank you

  • @basix250
    @basix250 4 года назад

    Great resource!

  • @jiuneyp
    @jiuneyp 2 года назад

    Hi! In rust 1.61 nightly this code "let ref mut remainder = self.remainder?" not is a same "let remainder = self.remainder.as_mut()?;"
    The first option causes an infinite looping, end the second works fine.
    Thanks for the great work, for the great video, and the high-quality content.

  • @Mrgreatestfreakout
    @Mrgreatestfreakout 2 года назад

    whenever I'm finding myself bashing my head against a wall because of lifetime, I just come and watch this video again

  • @daverichardhadley
    @daverichardhadley 3 года назад

    Thanks. This has really helped my "spam 'a until the compiler shuts up" problem. If there is a follow up, it would be nice to also cover an example of traits with lifetime parameters.

  • @nickkallis8073
    @nickkallis8073 4 года назад +6

    Jon thank you for this great session and please keep them coming! One small question... can you explain why the program was hanging at 55:39? What was exactly going on? Why no panic or just exiting with wrong output? thank you!

    • @jonhoo
      @jonhoo  4 года назад +4

      Ah, yes, that one is a little finicky, and I should have articulated the problem out loud. The issue, which I _tried_ to, but I think failed to, articulate was that we never end up actually updating the remainder. So the program is just constantly finding the first part of the string, and never returning `None`.

    • @nickkallis8073
      @nickkallis8073 4 года назад

      @@jonhoo Oh that makes total sense! thank you

  • @jhscheer
    @jhscheer 4 года назад

    Great exercise, thanks!

  • @usercommon1
    @usercommon1 3 месяца назад

    Thank youuuu!!!❤

  • @darklajid
    @darklajid 3 месяца назад

    The series is awesome, I wish I'd have seen this earlier.
    (off-topic, but I would really like to know what WM/desktop setup that is, looks damn clean to me)