• Orygin@sh.itjust.works
    link
    fedilink
    English
    arrow-up
    1
    ·
    2 days ago

    Not sure if that’s what you are referring to as destructors, but they added a new way to have code run at resource collection in go 1.24

    • sugar_in_your_tea@sh.itjust.works
      link
      fedilink
      English
      arrow-up
      1
      ·
      2 days ago

      I assume you’re talking about runtime. AddCleanup()? That’s certainly nice, but it’s not the same as a destructor since it only runs at GC time. It’s useful for cleaning up data used by a shared library or something (e.g. something malloc’d by a C lib), but it only solves part of the problem.

      I’m talking about scope guards. In Rust, here’s how you deal with mutexes:

      {
          let value = mutex.Lock();
          ... use value ...
          // mutex.Unlock() automatically called
      } 
      

      The closest thing in Go is defer():

      mutex.Lock()
      defer mutex.Unlock()
      

      That works most of the time, but it doesn’t handle more complex use cases, like selectively unlocking a mutex early while still guaranteeing it eventually gets unlocked.

      Rust fixes this with the Drop trait, so basically I can drop something early conditionally, but it’ll get dropped automatically when going out of scope. For example:

      struct A(String);
      
      impl Drop for A {
          fn drop(&mut self) {
              println!("dropping {}", self.0)
          }
      }
      
      fn main() {
          let a = A("a".into());
          let b = A("b".into());
          let c = A("c".into());
          drop(b);
      }
      

      Without the last line, this prints c, b, a, i.e. stack order. With the last line, it instead prints b, c, a, because I drop b early.

      This is incredibly useful when dealing with complex logic, especially with mutexes, because it allows you to cleanly and correctly handle edge cases. Things are dropped at block scope too, giving even more control of semantically releasing things like locks.

      That said, 1.24 added WASM, which is really cool, so thanks for encouraging me to look at the release notes.

      • Orygin@sh.itjust.works
        link
        fedilink
        English
        arrow-up
        2
        ·
        2 days ago

        Thanks for taking the time to explain it. Indeed the new runtime method does not guarantee when the resource will be cleaned, so something like that Drop trait would be quite useful