cratosw

资源管理

资源管理

内存管理 章节已经介绍了 .NET 与 Rust 在 GC、所有权、终结器等方面的差异, 建议先阅读该章节。

本节只给出一个简化的“数据库连接”示例,用于说明 SQL 连接在两种语言中 如何被正确关闭/释放(dispose/drop)。

{
    using var db1 = new DatabaseConnection("Server=A;Database=DB1");
    using var db2 = new DatabaseConnection("Server=A;Database=DB2");

    // ...code using "db1" and "db2"...
}   // "Dispose" of "db1" and "db2" called here; when their scope ends

public class DatabaseConnection : IDisposable
{
    readonly string connectionString;
    SqlConnection connection; //this implements IDisposable

    public DatabaseConnection(string connectionString) =>
        this.connectionString = connectionString;

    public void Dispose()
    {
        //Making sure to dispose the SqlConnection
        this.connection.Dispose();
        Console.WriteLine("Closing connection: {this.connectionString}");
    }
}
struct DatabaseConnection(&'static str);

impl DatabaseConnection {
    // ...functions for using the database connection...
}

impl Drop for DatabaseConnection {
    fn drop(&mut self) {
        // ...closing connection...
        self.close_connection();
        // ...printing a message...
        println!("Closing connection: {}", self.0)
    }
}

fn main() {
    let _db1 = DatabaseConnection("Server=A;Database=DB1");
    let _db2 = DatabaseConnection("Server=A;Database=DB2");
    // ...code for making use of the database connection...
} // "Dispose" of "db1" and "db2" called here; when their scope ends

在 .NET 中,对已调用 Dispose 的对象继续使用,通常会在运行时抛出 ObjectDisposedException。在 Rust 中,这类问题会在编译期被规则拦截, 从而避免进入运行时。

On this page