|
|
|
|
|
by pcwalton
4597 days ago
|
|
Go's "defer" is not equivalent to RAII. It is function-scoped rather than block-scoped and has semantics based on mutating hidden per-function mutable state at runtime. For example: func Foo() {
for i := 0; i < 5; i++ {
if Something() {
defer Whatever()
}
}
// ... the compiler can't tell how many
// Whatever()s run here ...
}
Compared to RAII as implemented in for example D with its "scope" statement, "defer" has much more complex semantics, inhibits refactoring since moving things to function bodies or inlining function bodies silently changes semantics, and cannot be optimized as easily, because of the dynamic aspects. IMHO, it has essentially no advantages over RAII and many disadvantages. |
|
As someone who has written and reviewed hundreds of thousands of lines of Go code, I haven't observed this to be the case in practice.
RAII doesn't fit into Go, philosophically, as it lets you trigger hidden functionality on the creation or destruction of data structures, whereas a deferred function can only be run if there's a defer statement there in the code (where you can see it).
In Go, the only way to execute a block of code is to make a function call. There are no constructors, destructors, or any other kind of side effect to allocating or deallocating data structures. This brings a huge benefit in terms of readability and transparency.
Anyway, I'm not sure why we're comparing defer and RAII, because they're generally used for different purposes.