代码之家  ›  专栏  ›  技术社区  ›  Scott Deerwester

如何创建空的sql.rows实例?

go
  •  0
  • Scott Deerwester  · 技术社区  · 6 年前

    我有一个函数返回 (*sql.Rows, error) 进去。在某些情况下,没有要返回的内容,但也没有错误。选择似乎是:

    if (...) {
        return nil, nil
    }
    

    然后,在呼叫者中:

    rows, err := fn()
    if err != nil {
        return nil, err
    }
    
    if rows == nil {
       ...
    } else {
        for rows.Next() {
        ...
        }
    }
    

    或者返回一个我随后检查的特殊错误。我认为如果我能返回一个有效的行实例,它会更加优雅,但是当它 Next() 调用方法,如下所示:

    if (...) {
        return EmptyRows(), nil
    }
    

    在呼叫者中:

    rows, err := fn()
    if err != nil {
        return nil, err
    }
    
    for rows.Next() {
        ...
    }
    

    我可以做如下的事情:

    if (...) {
        return db.QueryRows("select * from something where true=false"), nil
    }
    

    但这看起来很愚蠢。有什么建议吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   dave    6 年前

    我将以不同的方式处理这个问题,并将处理程序传递给您的函数。因此,如果您当前的功能是:

    func YourFunc() (*sql.Rows, error) {
        // ...
        if (...) {
            return nil, nil
        }
        return rows, nil
    }
    

    它应该是:

    func yourFunc() (*sql.Rows, error) {
        // ...
        if (...) {
            return nil, sql.ErrNoRows
        }
        return rows, nil
    }
    
    func YourFunc(cb func(*sql.Rows)) error {
        rows, err := yourFunc()
        if err == sql.ErrNoRows {
            return nil
        }
        if err != nil {
            return err
        }
        cb(rows)
        return nil
    }
    

    然后在您的呼叫者中:

    err := YourFunc(func(row *sql.Rows) {
        for rows.Next() {
            // ...
        }
    })
    

    这个函数只有在有行的情况下才会被调用,如果您关心的是错误的话会得到错误,并且调用方的语法非常干净。