Scala 中方法的条件调用
我在代码中多次发现这种模式:
if (doIt)
object.callAMethod
else
object
我想知道是否可以有一种语法上更令人愉悦的方式来编写上面的代码,特别是避免重复 object
变量。类似于:
// using the Scalaz "pipe" operator
// and "pimping" f: T => T with a `when` method
object |> (_.callAMethod).when(doIt)
不幸的是,上面的行失败了,因为类型推断需要 (_.callAMethod)
的参数类型。
我现在最好的方法是这样的:
implicit def doItOptionally[T](t: =>T) = new DoItOptionally(t)
class DoItOptionally[T](t: =>T) {
def ?>(f: T => T)(implicit doIt: Boolean = true) =
if (doIt) f(t) else t
}
implicit val doIt = true
object ?> (_.callAMethod)
不太好,因为我必须声明一个隐式 val ,但是如果有多个链式调用,这会得到回报:
object ?> (_.callAMethod) ?> (_.callAnotherMethod)
有人有更好的主意吗?我在这里错过了一些 Scalaz 魔法吗?
I've found this pattern quite a few times in my code:
if (doIt)
object.callAMethod
else
object
I'm wondering if there could be a syntactically more pleasing way to write the code above, especially to avoid the repetition of the object
variable. Something like:
// using the Scalaz "pipe" operator
// and "pimping" f: T => T with a `when` method
object |> (_.callAMethod).when(doIt)
Unfortunately the line above fails because the type inference requires a parameter type for (_.callAMethod)
.
My best approach for now is this:
implicit def doItOptionally[T](t: =>T) = new DoItOptionally(t)
class DoItOptionally[T](t: =>T) {
def ?>(f: T => T)(implicit doIt: Boolean = true) =
if (doIt) f(t) else t
}
implicit val doIt = true
object ?> (_.callAMethod)
Not great because I have to declare an implicit val
but this pays off if there are several chained calls:
object ?> (_.callAMethod) ?> (_.callAnotherMethod)
Does anyone have a better idea? Am I missing some Scalaz magic here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
例子:
Example:
我无法评论您的答案@Rex Kerr,但更简洁的方法是:
只需将
implicit
放在类之前就可以完全省略隐式函数。I can't comment on your answer @Rex Kerr but a more concise way to do that would be:
Just putting the
implicit
before the class allows you to omit the implicit function entirely.如果您将
callAMethod
表示为自同态,那么您可以使用幺半群功能。类似于:(可能需要
Endo
上的类型参数)If you represent your
callAMethod
as an endomorphism then you can use the monoid functionality. Something like:(might need a type parameter on the
Endo
)