7 Deadly Mistakes Beginner Go Developers Make (and how to fix them)

Поделиться
HTML-код
  • Опубликовано: 30 июн 2024
  • 7 Deadly Mistakes Beginner Go Developers Make (and how to fix them) -
    We will be talking about 7 common mistakes Golang beginner often make when working on their first few Golang beginner projects. At the end, there'll be a quick Golang tip to help prevent these Golang beginner mistakes for Golang beginners.
    --
    Golang Dojo is all about becoming Golang Ninjas together. You can expect all kinds of Golang tutorials, news, tips & tricks, and my daily struggles as a Golang developer. Make sure to subscribe if you look forward to such content!
    Get Your Golang Cheat Sheet! - golangdojo.com/cheatsheet
    Git repos & notes - golangdojo.com/resources
    --
    Timestamps
    0:00 Overview
    0:29 Mistake 1
    2:53 Mistake 2
    5:16 Mistake 3
    6:05 Mistake 4
    7:28 Mistake 5
    8:39 Mistake 6
    10:10 Mistake 7
    11:08 Bonus tip!
    --
    #golang #goprogramming #golangdojo
  • НаукаНаука

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

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

    Get your *FREE Golang Cheat Sheet* -
    golangdojo.com/cheatsheet

  • @ezikhoyo
    @ezikhoyo Год назад +55

    At 8:40 there is actually a mistake in your code. On the third panel you would need to do "go func(local int) { // code }(i)", and you forgot to pass i to the func, leaving it as "}()".

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

      Eagle eyes

    • @touringtim7313
      @touringtim7313 День назад +2

      I'm glad someone wrote that because I paused the video and had no idea how the third statement worked

  • @luizhp
    @luizhp 4 месяца назад +5

    8:22 I think they fixed it on 1.22
    package main
    import (
    "fmt"
    "time"
    )
    func example01() {
    s := []int{1, 2, 3}
    for _, i := range s {
    go func() {
    fmt.Println(i)
    }()
    }
    time.Sleep(time.Second)
    }
    func example02() {
    s := []int{1, 2, 3}
    for _, i := range s {
    localI := i
    go func() {
    fmt.Println(localI)
    }()
    }
    time.Sleep(time.Second)
    }
    func example03() {
    s := []int{1, 2, 3}
    for _, i := range s {
    go func(localI int) {
    fmt.Println(localI)
    }(i)
    }
    time.Sleep(time.Second)
    }
    func main() {
    fmt.Println("Example 01")
    example01() // 3 2 1
    // fmt.Println("Press enter to proceed to next example...")
    // fmt.Scanln()
    fmt.Println("Example 02")
    example02() // 3 2 1
    // fmt.Println("Press enter to proceed to next example...")
    // fmt.Scanln()
    fmt.Println("Example 03")
    example03() // 3 2 1
    // fmt.Println("Press enter to exit...")
    // fmt.Scanln()
    }

  • @njengathegeek
    @njengathegeek Год назад +12

    The mistakes are well pointed out, thumbs up Wallace 👍

  • @user-de3yz4lr9x
    @user-de3yz4lr9x Год назад +15

    8:19 forgot to pass i to the function call in the third example

    • @touringtim7313
      @touringtim7313 День назад +1

      I'm glad someone wrote that because I paused the video and had no idea how the third statement worked

  • @codelinx
    @codelinx Год назад +2

    Love the format and clean layout for this go content

  • @dineshr93
    @dineshr93 Год назад +8

    At 8:32 , 3rd rightmost tile, shouldn't we require to pass the loop variable i to anonymous func's invoking braces }(i) ?

  • @eastquack3342
    @eastquack3342 Год назад +2

    great vid Wallace; I used to forget passing the local var to the goroutine too

  • @PaulSmith-qr1iy
    @PaulSmith-qr1iy Год назад +2

    Priceless! Thanks so much

  • @Levelord92
    @Levelord92 Год назад +5

    about fourth mistake, just replace assert with require and you'll get the same result

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

      "require" is from the native module?

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

      @@mti2fw It's from the testify package.

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

    Yup, I've made pretty much all of them. Thanks for sharing.

  • @GoWithAndy-cp8tz
    @GoWithAndy-cp8tz 3 месяца назад +2

    I think there is a little misunderstanding with pointers. Structures' names are pointers itself so making pointer to pointer will be slower as expected. Using pointers with structs is pointless.Cheers!

    • @Egzvorg
      @Egzvorg 19 дней назад

      What? If that were true the struct's fields modified inside a function that received the struct as a value would change outside the function too.

  • @ssengalanto-vv6jo
    @ssengalanto-vv6jo Год назад +3

    testify library has ‘require’ package that does fatal on error

  • @ruicraveiro842
    @ruicraveiro842 Год назад +28

    I think you made a mistake. You are stating that passing a struct by pointer can have worse performance than by value, and then you prove that returning a struct via pointer has worse performance than returning it by value. The problem with your approach is that you are using that benchmark to demonstrate, correctly, that returning by pointer is worse, as an extension of the concept of receiving by pointer vs by value. I am arguing that one is not an extension of the other and that receiving parameters is in fact a very different scenario from returning values, not an extension of the concept. And, because of that, proving that it is more expensive to return a struct by pointer doesn't prove at all that it is more expensive to receive a struct by pointer. Correct me if I'm wrong, but if the caller created and assigned the struct to a local variable and passed the address of that variable to a sub-function, that subfunction will receive a pointer to a variable on the stack, not on the heap. So, when I am receiving a struct by pointer, the memory where that pointer points to depends only on how the caller created that struct and not on the fact that we received it by pointer. This is different from returning by pointer, where the struct will necessarily need to be in the heap for that to be possible. Am I understanding this wrong?

    • @ForeverZer0
      @ForeverZer0 5 месяцев назад +1

      This is the nuance that too many Go developers omit with the "passing by value in Go is faster" statement that is constantly repeated in the community. The concept isn't even unique to Go, the language design simply abstracts memory management away to make it less obvious. While the statement about passing by value might be generally good to tell someone coming from higher level languages and dipping their toe into pointers, memory management, and stack/heap allocations for the first time, it is bad advice and repeated without further explanation way too often, as if it is some rule of thumb that can safely be relied upon for most use cases, when that is anything by true.

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

      Not necessarily. You don’t control where the allocation happens; the runtime does that for you. The fact is that value copies are pretty fast, but if you are copying many primitive values, that will be slower at some point than following a reference to some distant memory.
      Frankly, there are usually better reasons to pass a copy vs a pointer.

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

      From where I stand and with my knowledges about memory allocation, it's just like you said. The fixed problem here is to RETURN a pointer, because when you return an address to a variable from an inner context to an outer one, the variable has to be stored in the heap because it's not known anymore its lifecycle. When you pass the pointer as a parameter, it continues to be in the stack just because, according to de LIFO architecture, the variable is just going to an inner context and its lifecycle continues to be known.
      In case of structs and more complexes variables the question about heap x stack will be its size and other problems, not the fact it's being passed as a pointer or not.

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

    Regarding mistake 1: 17ns vs 43ns is not much of a difference efficiency wise, but what about memory consumption? If you keep passing values around wouldn't that lead to extensive memory usage? Especially in a microservice or serverless environment you want to avoid high memory consumption because otherwise you will need more instances and each instance of a service or function will cost you money.

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

    Another important argument for mistake 1: The stack and it's variables will stay longer in the processors L1 & L2 cache than heap-variables that have a costly long lookup-time in the RAM

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

    At 8:38, the last example closure should have i passed in as argument. i.e.
    func main(){
    s := []int{1,2,3}
    for _, i := range s {
    go func(localI int){
    fmt.Println(localI)
    }(i) // this is required
    }
    time.Sleep(time.Second)
    }

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

    Great video! Does Golang Dojo have a discord channel or something? it would be nice!

  • @yueguan7128
    @yueguan7128 7 месяцев назад +1

    the first mistake pass the paramter with (previous Ninja) and return with ¤t is faster?

  • @Simon-xi8tb
    @Simon-xi8tb 4 месяца назад

    thanks for the sheet-sheet

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

    2:48 extra benefit of stack: stack size is known at compile time, so the memory is allocated once per function call for all the variables, so it also doesn't require extra actions for allocating, because the stack is allocated every time you call a function. Vice versa, heap memory is allocated for every value separately, which is less efficient.
    7:00 c'mon, man. Are you kidding? You took the simplest example to show that there is no difference between "idiomatic" way and third-party library. When your assert will require more comparison, you "idiomatic" way will become an unreadable garbage. One of the benefits of unit testing is being the closest to the documentation, so it should be readable.
    10:23 that's your code in real tests, if you use "idiomatic" way)

  • @jamshidbekyuldoshev7542
    @jamshidbekyuldoshev7542 10 месяцев назад

    Which Go frameworks do you recommend to learn?

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

    But you should compare having a function with a input pointer and returning a copy not a pointer.. or only make the example with returning a pointer VS a copy. Will only allocate to the heap if you are returning, no if you pass it as a param

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

    Here are my own "7 Deadly Mistakes Beginner Go Developers Make", just for fun:
    1. Don't discard errors using the blank identifier _
    2. Don't misuse goroutines and channels
    3. Don't use nil maps or slices
    4. Don't neglect testing
    5. Don't ignore error values in tests
    6. Don't misuse defer
    7. Don't use global variables unnecessarily

  • @winfle
    @winfle 5 месяцев назад

    Interface values are store in a Heap, so be aware of it

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

    how come i did not see your channel

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

    I've made them all at some point)

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

    i made 3 tip in this video

  • @beofonemind
    @beofonemind 2 дня назад

    your ssl is toast

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

    i need subtitle in spanish xd

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

    Well, the deadliest mistake a beginner can make is to pickup GO in the first place

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

      Hello Rustacean

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

      @@ElderSnake90 No, I just did some GO and realized how bad a language it is

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

      @@parlor3115 You likely didn't do enough to see the beauty in it. ;-) My first instinct about Go was that a language that doesn't have exceptions, classes or inheritance must not be from this century. But then I actually used the language a lot more and realised just how wrong my initial impressions were.

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

      @@ruicraveiro842 If you're unable to migrate to the new version (which is always) You'd have to implement the same function 2+ times because your fav library have it's own custom string type / write some hack code / use source generators. There are no facility array / slice functions for common operations like map, reduce, filter, includes, ... . The module system is abhorrent being limited to a single module per directory. Unnecessary style guidelines enforced by the compiler (not being able to write "else" on a new line).
      The only advantage GO brings is that the runtime is shipped along with the binary and I think if MS manages to achieve the same thing with C# or if a subset of Rust is created without all the added complexity, then GO will definitely go out of scope.

    • @ruicraveiro842
      @ruicraveiro842 Год назад +2

      @@parlor3115 I am aware of all the facts you point out and my opinion is unchanged.

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

    first mistake is learning go