gpt4 book ai didi

Scala:为什么在函数参数上使用隐式?

转载 作者:行者123 更新时间:2023-12-02 03:05:15 27 4
gpt4 key购买 nike

我有以下功能:

def getIntValue(x: Int)(implicit y: Int ) : Int = {x + y}

我到处都能看到上述声明。我明白上面的函数在做什么。它是一个带有两个参数的柯里化(Currying)函数。如果省略第二个参数,它将调用返回 int 的隐式定义。所以我认为这与定义参数的默认值非常相似。

implicit val temp = 3

scala> getIntValue(3)
res8: Int = 6

我想知道上述声明有什么好处?

最佳答案

这是我的“务实”答案:您通常将柯里化(Currying)更多地用作“约定”,而不是其他任何有意义的东西。当您的最后一个参数恰好是“按名称调用”参数时(例如:: => Boolean),它会非常方便:

def transaction(conn: Connection)(codeToExecuteInTransaction : => Boolean) = {

conn.startTransaction // start transaction

val booleanResult = codeToExecuteInTransaction //invoke the code block they passed in

//deal with errors and rollback if necessary, or commit
//return connection to connection pool
}

这句话的意思是“我有一个名为transaction的函数,它的第一个参数是一个连接,第二个参数是一个代码块”。

这允许我们像这样使用这个方法(使用“我可以使用大括号而不是括号规则”):

transaction(myConn) {

//code to execute in a transaction
//the code block's last executable statement must be a Boolean as per the second
//parameter of the transaction method

}

如果您没有柯里化(Currying)该事务方法,那么这样做看起来会很不自然:

transaction(myConn, {

//code block

})

隐式怎么样?是的,它看起来像是一个非常模糊的构造,但是一段时间后你就会习惯它,隐式函数的好处是它们有作用域规则。因此,这意味着对于生产,您可以定义一个隐式函数来从 PROD 数据库获取数据库连接,但在集成测试中,您将定义一个隐式函数来取代 PROD 版本,并将用于获取连接来自 DEV 数据库,而不是在您的测试中使用。

举个例子,我们在事务方法中添加一个隐式参数怎么样?

def transaction(implicit conn: Connection)(codeToExecuteInTransaction : => Boolean) = {

}

现在,假设我的代码库中有一个返回 Connection 的隐式函数某处,如下所示:

def implicit getConnectionFromPool() : Connection = { ...}

我可以像这样执行交易方法:

transaction {
//code to execute in transaction
}

Scala 会将其翻译为:

transaction(getConnectionFromPool) {
//code to execute in transaction
}

总而言之,隐式是一种非常好的方法,当您在使用该函数的任何地方该参数 99% 的情况下都是相同的时,开发人员不必为所需参数提供值。在那 1% 的情况下,您需要不同的连接,您可以通过传入一个值来提供您自己的连接,而不是让 Scala 找出哪个隐式函数提供该值。

关于Scala:为什么在函数参数上使用隐式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23546097/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com