LINUX.ORG.RU

История изменений

Исправление korvin_, (текущая версия) :

Ну проверишь вызовы внутри finally как сейчас вы делаете, в чем проблема?

Сейчас мы не делаем, потому что есть try-with-resources:

try (
    Connection conn = ...;
    Statement stmt = ...;
    ResultSet rs = ...;
) {
    // do something
}

Я же не исключения предлагаю, а другой синтаксис для предложенного драфта.
И не вижу ничего зазорного в приведенном примере. Вся логика финализации в одном блоке, а не разбросана по телу функции.

Видимо, ты не сталкивался с проблемами такого подхода. Почитай про RAII в C++, try-with-resources в Java или using в C#.

Если уж тебя беспокоит наличие новых ключевых слов (check/handle), то можно было бы сделать как-то так, например:

func itemById(id uint64) (*Item, error) {
    conn, err := sql.Open(...)
    // return nil, err if err != nil
    // defer conn.Close() otherwise
    defer(err) conn.Close()
    
    stmt, err := conn.Stmt(...)
    stmt = defer(err) stmt.Close()
    
    stmt.SetUint64(1, id)
    
    rs, err := stmt.Exec()
    defer(err) {
        // additional error handling if needed
        log.Error(err)
    } rs.Close()

    name, err := rs.String(2)
    // just return nil, err if err != nil
    defer(err)
    
    // no need to specify nil error
    return &Item{id, name}
}

Исходная версия korvin_, :

Ну проверишь вызовы внутри finally как сейчас вы делаете, в чем проблема?

Сейчас мы не делаем:

try (
    Connection conn = ...;
    Statement stmt = ...;
    ResultSet rs = ...;
) {
    // do something
}

Я же не исключения предлагаю, а другой синтаксис для предложенного драфта.
И не вижу ничего зазорного в приведенном примере. Вся логика финализации в одном блоке, а не разбросана по телу функции.

Видимо, ты не сталкивался с проблемами такого подхода. Почитай про RAII в C++, try-with-resources в Java или using в C#.

Если уж тебя беспокоит наличие новых ключевых слов (check/handle), то можно было бы сделать как-то так, например:

func itemById(id uint64) (*Item, error) {
    conn, err := sql.Open(...)
    // return nil, err if err != nil
    // defer conn.Close() otherwise
    defer(err) conn.Close()
    
    stmt, err := conn.Stmt(...)
    stmt = defer(err) stmt.Close()
    
    stmt.SetUint64(1, id)
    
    rs, err := stmt.Exec()
    defer(err) {
        // additional error handling if needed
        log.Error(err)
    } rs.Close()

    name, err := rs.String(2)
    // just return nil, err if err != nil
    defer(err)
    
    // no need to specify nil error
    return &Item{id, name}
}