Hacker News new | past | comments | ask | show | jobs | submit login

Yes, but look at the example in the blog post of this thread- "stat" depends on "file", "file" depends on "path". You can call defer in any order in your code, the language syntactically doesn't enforce you to call defer right after resource acquisition. "try-with-resources" in Java (or "using" in c#) will always call "finalizers" in order opposite to how resources where created. Following the syntax I inveted above, for someone used to Java it would be easier to read than to think how defers are called:

  try std.fmt.allocPrint(allocator, "problems/{}", .{ id }) |path| : allocator.free(path) {
    try std.fs.cwd().openFile(path, .{}) |file| : file.close() {
      try file.stat() |stat| {
        try allocator.alloc(u8, stat.size) |contents| : allocator.free(contents) {
          // do something with 'contents'
        }
      }
    }
  }
In Zig you can write this, and mess everything up:

  const path = try std.fmt.allocPrint(allocator, "problems/{}", .{ id });
  var file = try std.fs.cwd().openFile(path, .{});
  const stat = try file.stat();
  var contents = try allocator.alloc(u8, stat.size);
  defer allocator.free(contents);
  defer file.close();
  defer allocator.free(path);



That's what errdefer is for.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: