1

考虑在无形回购中找到的单例函数的定义:

/** Polymorphic function selecting an arbitrary element from a non-empty `Set`. */
object choose extends (Set ~> Option) {
  def apply[T](s : Set[T]) = s.headOption 
}

def将其与以下示例中的传统语法进行对比:

package utils

object UtilWithASingleMethod {
  def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}

相对

package utils

object isSatisfyingSomePredicate extends (Foo => Boolean) {
  def apply(foo: Foo): Boolean = ???
}

请注意呼叫站点现在如何变为

isSatisfyingSomePredicate(foo)

代替

UtilWithASingleMethod.isSatisfyingSomePredicate(foo)

或者

import UtilWithASingleMethod._

isSatisfyingSomePredicate(foo)

就个人而言,UtilWithASingleMethodpackage 似乎只是为了能够使用熟悉的def语法而没有添加任何有用的信息。

除了诸如不熟悉或与工厂模式中使用的对象+应用样式混淆等主观缺点外,单例函数定义是否有任何技术缺点?

4

2 回答 2

6

他们必须在您链接的文件中创建单例对象的原因是那些不是函数,而是多态函数,即它们有一个apply[T](a: F[T]): G[T]由类型参数普遍量化的方法T。这对于普通函数来说根本不需要,它所做的只是增加了apply在单例对象上调用方法的开销,foo而不是foo直接调用方法。它也不能帮助你“避免”包和导入,因为无论如何你都希望在某个包中拥有这个对象,你不想将它转储到默认的根包中。

如果你想避免“强制”UtilWithASingleMethod命名空间,那么isSatisfyingSomePredicate直接添加到util

package object util {
  def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}

此方法在您导入后立即可用util._

于 2019-06-30T19:38:11.503 回答
1

Scala 3 (Dotty) 支持顶层定义,所以

package utils

object UtilWithASingleMethod {
  def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}

我们可以删除间接并写

package utils

def isSatisfyingSomePredicate(foo: Foo): Boolean = ???

这确实解决了我的问题。

于 2020-06-01T16:08:48.523 回答