Skip to main content

RAII

· 3 min read

本文总结了不同语言实现 RAII 的方式。

构造器-析构器

#include <cstdio>

struct Locker {
Locker() {
puts("lock");
}
~Locker() {
puts("unlock");
}
};

int main() {
Locker locker;
}

控制块

class Locker implements AutoCloseable {
public Locker() {
System.out.println("lock");
}

@Override
public void close() {
System.out.println("unlock");
}

public static void main(String[] args) {
try (Locker locker = new Locker()) {

}
}
}

defer 语句

import "fmt"

func main() {
defer fmt.Println("unlock")
fmt.Println("lock")
}

思考题

这样写实现 RAII 有什么问题:

var r1 = open("r1");
var r2 = open("r2");
try {
// ...
} finally {
r1.close();
r2.close();
}

正确的写法应该是:

try (var r1 = open("r1"); var r2 = open("r2")) {
// ...
}

这种写法语前面的写法不同,而是等价于下面的写法:

var r1 = open("r1");
try {
var r2 = open("r2");
try {
// ...
} finally {
r2.close();
}
} finally {
r1.close();
}

因此这个语法糖相当于是把嵌套结构变成并列结构了,大大简化了代码编写。