2012-09-11 19 views
5

Tôi đang cố gắng để tránh biến mutables, nhưng vấn đề là tôi phải truy cập một val mà tôi cần phải khởi tạo bên trong thử (đó là một hoạt động db mà migth fail) và tôi cần điều đó var trong khối finallyscala: làm thế nào để tránh mutables bên trong cố gắng bắt khối

tôi đã cố gắng với một số lựa chọn thay thế:

tuyên bố val bên trong khối try

try { 
    val resultSet = SQL(sql).resultSet 
    return ColumnInfo(resultSet.getMetaData) 
} catch { 
    case e => throw new ColumnInfoException("Error getting metadata") 
} finally { 
    resultSet.close 
} 

error: not found: value resultSet 

tuyên bố val ngoài khối try mà không cần khởi tạo nó

val resultSet: java.sql.ResultSet 
try { 
    resultSet = SQL(sql).resultSet 
    return ColumnInfo(resultSet.getMetaData) 
} catch { 
    case e => throw new ColumnInfoException("Error getting metadata") 
} finally { 
    resultSet.close 
} 

error: only classes can have declared but undefined members 

sử dụng một var, mà dường như làm việc

var resultSet: java.sql.ResultSet = null 
try { 
    resultSet = SQL(sql).resultSet 
    return ColumnInfo(resultSet.getMetaData) 
} catch { 
    case e => throw new ColumnInfoException("Error getting metadata") 
} finally { 
    resultSet.close 
} 

và cuối cùng làm tổ khối try-catch, mà dường như khá bẩn

try { 
    val resultSet = SQL(sql).resultSet 
    try { 
    return ColumnInfo(resultSet.getMetaData) 
    } catch { 
    case e => throw new ColumnInfoException("Error getting metadata") 
    } finally { 
    resultSet.close 
    } 
} catch { 
    case e => throw new ColumnInfoException("Error opening resultSet") 
} 

Có một số cách tiếp cận tốt hơn tôi có thể làm để tránh sử dụng các vars và làm tổ các khối try-catch?

Trả lời

0

Loại bỏ các khối catch đầu tiên:

try { 
    val resultSet = SQL(sql).resultSet 
    try { 
    ColumnInfo(resultSet.getMetaData) 
    } finally { 
    resultSet.close 
    } 
} catch { 
    case e => throw new ColumnInfoException("Error opening resultSet") 
} 
+0

Hãy giải thích để bỏ phiếu xuống? – nilskp

+0

bắt thứ hai cũng sẽ bắt bất kỳ ngoại lệ từ lần thử đầu tiên, phải không? (upvoted, làm cho nó cải thiện phiên bản của riêng tôi ...) – opensas

+0

Có, nó sẽ đóng bộ kết quả, nhưng để lại đánh bắt đến khối thử bên ngoài. – nilskp

3
import scala.util.control.Exception._ 

allCatch.either(SQL(sql).resultSet).right.flatMap{ resultSet => 
    val ans = allCatch.either(ColumnInfo(resultSet.getMetaData)) 
    resultSet.close 
    ans 
}.fold(e => throw e, identity) 

hoặc bạn có thể bỏ qua fold và giữ (các) ngoại lệ được đóng gói trong Left.

1

Trong Scala, try khối là an expression. Trong trường hợp của bạn, nó có thể đánh giá một bộ chứa cả hai số val s:

val res: (java.sql.ResultSet, ColumnInfo) = try { 
    val rs = SQL(sql).resultSet 
    (rs, ColumnInfo(rs.getMetaData)) 
} catch { 
    case _: Throwable => throw new Exception("Error getting metadata") 
} finally { 
    res._1.close 
} 
val columnInfo = res._2 
Các vấn đề liên quan