考虑在无形回购中发现的singleton function的定义:
/** 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)
就个人而言,UtilWithASingleMethod
软件包似乎只是为了能够使用熟悉的def
语法而被强制使用,而没有添加任何有用的信息。
除了主观的缺点(如不熟悉或与工厂模式中使用的对象+应用样式混淆)之外,单例函数定义是否还有技术方面的缺点?
答案 0 :(得分:5)
他们必须在您链接的文件中创建单例对象的原因是,这些对象不是函数,而是多态函数,即它们具有一个{{1} }方法,该方法通常由类型参数apply[T](a: F[T]): G[T]
量化。普通函数根本不需要这样做,它所要做的只是增加在单例对象T
上调用apply
方法的开销,而不是直接调用方法foo
。它也无助于您“避免”打包和导入,因为无论如何您都希望将此对象放在某个打包中,所以您不想将其转储到默认的根包中。
如果要避免使用“强制” foo
名称空间,则将UtilWithASingleMethod
直接添加到isSatisfyingSomePredicate
:
util
此方法在您导入package object util {
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
后就可以使用。
答案 1 :(得分:1)
Scala 3(Dotty)支持toplevel definitions,因此代替
package utils
object UtilWithASingleMethod {
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
我们可以删除间接写入并写
package utils
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
这确实解决了我的问题。