如何使调用代码与幕后传递的隐式参数无关?
How to make calling code agnostic of implicit parameter passed under the hood?
我希望能够用交易包围一段代码。调用代码应该像这样简单:
transactional {
save("something")
}
我想像这样制作 transactional
函数:
def transactional(block: => Unit): Unit = {
implicit val conn: Connection = ???
conn.begin()
try {
block
conn.commit()
} catch {
case ex: Exception =>
conn.rollback()
throw ex
} finally {
conn.close()
}
}
现在 save
方法将需要对 Connection 做一些事情,但我想让调用代码对此不可知(见上文)。我天真地实现了它:
def save(operation: String)(implicit conn: Connection): Unit = {
println(s"saving $operation using $conn")
}
当然我得到一个编译错误,找不到连接。我缺少什么部分来将连接从 transactional
函数连接到 save
函数?
更改您的 transactional
函数,如下所示(查看交易代码片段)。这里的问题是事务连接可用,但它必须隐式地达到保存功能。因此,一旦您获得连接对象,就将其交给在事务内部运行的函数,然后此代码 (f) 就可以访问该连接。一旦 f 可以访问连接,我们就可以使用 implicit 关键字使它成为 implicit
。现在可以在事务内部无缝调用像保存这样隐式连接的函数。
交易的重要变化
1) 不传递代码块 (block: => Unit) 而是传递 f (f: Connection => Unit)
2) 内部事务将 f 应用于连接对象并授予 f 访问连接对象的权限。
def transactional(f: Connection => Unit): Unit = {
val conn = getConnectionFromDatabase()
conn.begin()
try {
f(conn)
conn.commit()
} catch {
case ex: Exception =>
conn.rollback()
throw ex
} finally {
conn.close()
}
}
现在你可以这样使用了
transactional { implicit conn =>
save("something")
}
如果你的保存功能是这样的
def save(str: String): Connection => Unit = ???
那你可以不连线
transactional(save("foo"))
如果 save
returns 函数需要一个连接:
def transactional(block: Connection => Unit): Unit = {
val conn: Connection = ???
// stuff..
block(conn)
// stuff..
}
def save(operation: String): Connection => Unit = { conn =>
println(s"saving $operation using $conn")
}
transactional {
save("something")
}
我希望能够用交易包围一段代码。调用代码应该像这样简单:
transactional {
save("something")
}
我想像这样制作 transactional
函数:
def transactional(block: => Unit): Unit = {
implicit val conn: Connection = ???
conn.begin()
try {
block
conn.commit()
} catch {
case ex: Exception =>
conn.rollback()
throw ex
} finally {
conn.close()
}
}
现在 save
方法将需要对 Connection 做一些事情,但我想让调用代码对此不可知(见上文)。我天真地实现了它:
def save(operation: String)(implicit conn: Connection): Unit = {
println(s"saving $operation using $conn")
}
当然我得到一个编译错误,找不到连接。我缺少什么部分来将连接从 transactional
函数连接到 save
函数?
更改您的 transactional
函数,如下所示(查看交易代码片段)。这里的问题是事务连接可用,但它必须隐式地达到保存功能。因此,一旦您获得连接对象,就将其交给在事务内部运行的函数,然后此代码 (f) 就可以访问该连接。一旦 f 可以访问连接,我们就可以使用 implicit 关键字使它成为 implicit
。现在可以在事务内部无缝调用像保存这样隐式连接的函数。
交易的重要变化
1) 不传递代码块 (block: => Unit) 而是传递 f (f: Connection => Unit)
2) 内部事务将 f 应用于连接对象并授予 f 访问连接对象的权限。
def transactional(f: Connection => Unit): Unit = {
val conn = getConnectionFromDatabase()
conn.begin()
try {
f(conn)
conn.commit()
} catch {
case ex: Exception =>
conn.rollback()
throw ex
} finally {
conn.close()
}
}
现在你可以这样使用了
transactional { implicit conn =>
save("something")
}
如果你的保存功能是这样的
def save(str: String): Connection => Unit = ???
那你可以不连线
transactional(save("foo"))
如果 save
returns 函数需要一个连接:
def transactional(block: Connection => Unit): Unit = {
val conn: Connection = ???
// stuff..
block(conn)
// stuff..
}
def save(operation: String): Connection => Unit = { conn =>
println(s"saving $operation using $conn")
}
transactional {
save("something")
}