Scala 中方法的条件调用

发布于 2024-12-03 05:26:18 字数 903 浏览 0 评论 0原文

我在代码中多次发现这种模式:

  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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你好,陌生人 2024-12-10 05:26:18
class When[A](a: A) {
  def when(f: A => Boolean)(g: A => A) = if (f(a)) g(a) else a
}
implicit def whenever[A](a: A) = new When(a)

例子:

scala> "fish".when(_.length<5)(_.toUpperCase)
res2: java.lang.String = FISH
class When[A](a: A) {
  def when(f: A => Boolean)(g: A => A) = if (f(a)) g(a) else a
}
implicit def whenever[A](a: A) = new When(a)

Example:

scala> "fish".when(_.length<5)(_.toUpperCase)
res2: java.lang.String = FISH
-小熊_ 2024-12-10 05:26:18

我无法评论您的答案@Rex Kerr,但更简洁的方法是:

implicit class When[A](a: A) {
  def when(f: A => Boolean)(g: A => A) = if (f(a)) g(a) else a
}

只需将 implicit 放在类之前就可以完全省略隐式函数。

I can't comment on your answer @Rex Kerr but a more concise way to do that would be:

implicit class When[A](a: A) {
  def when(f: A => Boolean)(g: A => A) = if (f(a)) g(a) else a
}

Just putting the implicit before the class allows you to omit the implicit function entirely.

旧时模样 2024-12-10 05:26:18

如果您将 callAMethod 表示为自同态,那么您可以使用幺半群功能。类似于:(

object |> valueOrZero(doIt, Endo(_.callAMethod))

可能需要 Endo 上的类型参数)

If you represent your callAMethod as an endomorphism then you can use the monoid functionality. Something like:

object |> valueOrZero(doIt, Endo(_.callAMethod))

(might need a type parameter on the Endo)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文