Eh, I get why people often don't like things like defer, but I like how versatile it is. In general, my ideal language would have both something like defer as well as proper RAII. In addition to being easier to write one-off cleanup statements, defer can be more readable if the cleanup is simple since it doesn't require looking at any data structure's code.
Finally, defer can be advantageous in certain scenarios since, at least in Go, it is somewhat dynamically scoped. Therefore, you can defer something in an if statement or in the middle of a loop and the defer will still be executed at the end of the function. This can also be a disadvantage with loops since if you do something like "defer C.free(tempMem)", the memory won't actually be freed until the end of the function.
The thing is, you can trivially implement a form of defer with RAII. Where I work we have a decades old C++ macro called ON_BLOCK_EXIT that people use to clean up C-style things that don't have a destructor. Today it's much better with C++ having lambdas.
It won't be "function-scoped" like Go, but (IMO) that's fairly useless feature if you have destructors anyways (you could just collect everything in a vector at function-scope, if you really want that behavior).
Finally, defer can be advantageous in certain scenarios since, at least in Go, it is somewhat dynamically scoped. Therefore, you can defer something in an if statement or in the middle of a loop and the defer will still be executed at the end of the function. This can also be a disadvantage with loops since if you do something like "defer C.free(tempMem)", the memory won't actually be freed until the end of the function.