Swift 在离开函数之前执行代码
我目前正在为Swift 在离开函数之前执行代码,swift,sqlite,Swift,Sqlite,我目前正在为sqlite数据库编写一些代码。我注意到,在准备查询之后,我总是需要在退出函数之前完成查询(sqlite3\u finalize(statementPointer))。除了填上所有的可能性,还有别的方法吗 例如: func updateColumn(db: COpaquePointer, name: String, x: sqlite3_int64, y: String!=nil) -> Bool { var statement = "UPDATE MY_TABLE S
sqlite
数据库编写一些代码。我注意到,在准备查询之后,我总是需要在退出函数之前完成查询(sqlite3\u finalize(statementPointer)
)。除了填上所有的可能性,还有别的方法吗
例如:
func updateColumn(db: COpaquePointer, name: String, x: sqlite3_int64, y: String!=nil) -> Bool {
var statement = "UPDATE MY_TABLE SET X=?"
var statementPointer: COpaquePointer = nil
if y != nil {
statement += ", Y=?"
}
statement += " WHERE NAME=?"
if sqlite3_prepare_v2(db, statement, -1, &statementPointer, nil) != SQLITE_OK {
return false
} else if sqlite3_bind_int64(statementPointer, 1, x) != SQLITE_OK {
// Note this code here
sqlite3_finalize(statementPointer)
return false
}
if y != nil {
if sqlite3_bind_text(statementPointer, 2, y, -1, nil) != SQLITE_OK {
// Note this repetition
sqlite3_finalize(statementPointer)
return false
}
}
if sqlite3_step(statementPointer) != SQLITE_DONE {
// Note this repetition
sqlite3_finalize(statementPointer)
return false
}
// Note this repetition
sqlite3_finalize(statementPointer)
return true
}
当然,这只是我用来说明这一点的。在真正的代码中,有许多其他的if
子句需要我完成它们的语句
我知道swift中的类类似于deinit
,但是函数也有deinit
s吗
例如(我希望它像但不起作用的代码):
如何使用关键字
是的,有一个“函数的Denit”-它被称为:
defer
语句用于在将程序控制转移到出现defer
语句的范围之外之前执行代码
请注意,与假设的示例不同,defer
语句必须出现在任何可能导致其执行清理的事件之前,而不是在封闭范围的末尾。一般来说,它是这样工作的:
func doStuff() {
let resource = acquireResource()
defer {
cleanup(resource)
}
if something { return }
doOtherStuff()
}
func updateColumn(db: COpaquePointer, name: String, x: sqlite3_int64, y: String!=nil) -> Bool {
var statementPointer: COpaquePointer = nil
//... Other stuff...
guard sqlite3_prepare_v2(db, statement, -1, &statementPointer, nil) == SQLITE_OK
else { return false }
// after this you want any possible exit to do finalize, so put the defer here
defer { sqlite3_finalize(statementPointer) }
// every `return` after here, true or false, will execute the `defer` clause
guard sqlite3_bind_int64(statementPointer, 1, x) == SQLITE_OK
else { return false }
guard y != nil && sqlite3_bind_text(statementPointer, 2, y, -1, nil) == SQLITE_OK
else { return false }
guard sqlite3_step(statementPointer) == SQLITE_DONE
else { return false }
return true
}
在这里,cleanup(resource)
将被调用,而不管函数是否因为if something
或因为它到达其作用域的末尾(在doOtherStuff()之后)而退出
你不能像你所问的那样把一个延迟放在if
里面——它只会延迟到它所在范围的出口,所以它会在if
主体的末尾执行。但是,defer
与guard
配合得很好。。。在您的情况下,您可能需要以下内容:
func doStuff() {
let resource = acquireResource()
defer {
cleanup(resource)
}
if something { return }
doOtherStuff()
}
func updateColumn(db: COpaquePointer, name: String, x: sqlite3_int64, y: String!=nil) -> Bool {
var statementPointer: COpaquePointer = nil
//... Other stuff...
guard sqlite3_prepare_v2(db, statement, -1, &statementPointer, nil) == SQLITE_OK
else { return false }
// after this you want any possible exit to do finalize, so put the defer here
defer { sqlite3_finalize(statementPointer) }
// every `return` after here, true or false, will execute the `defer` clause
guard sqlite3_bind_int64(statementPointer, 1, x) == SQLITE_OK
else { return false }
guard y != nil && sqlite3_bind_text(statementPointer, 2, y, -1, nil) == SQLITE_OK
else { return false }
guard sqlite3_step(statementPointer) == SQLITE_DONE
else { return false }
return true
}