Mar*_*lic 1 singleton scala package shapeless function-definition
考虑在无形状回购中找到的单例函数的定义:
/** Polymorphic function selecting an arbitrary element from a non-empty `Set`. */
object choose extends (Set ~> Option) {
def apply[T](s : Set[T]) = s.headOption
}
Run Code Online (Sandbox Code Playgroud)
def
在以下示例中,将其与传统语法进行对比:
package utils
object UtilWithASingleMethod {
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
Run Code Online (Sandbox Code Playgroud)
与
package utils
object isSatisfyingSomePredicate extends (Foo => Boolean) {
def apply(foo: Foo): Boolean = ???
}
Run Code Online (Sandbox Code Playgroud)
注意呼叫站点现在如何变成
isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)
代替
UtilWithASingleMethod.isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)
要么
import UtilWithASingleMethod._
isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)
就个人而言,UtilWithASingleMethod
软件包似乎只是为了能够使用熟悉的def
语法而没有添加任何有用的信息。
除了主观的缺点(例如不熟悉或与工厂模式中使用的对象+应用样式混淆)之外,单例函数定义还有其他技术缺点吗?
他们之所以必须在链接的文件中创建单例对象,是因为它们不是函数,而是多态函数,即它们具有一种apply[T](a: F[T]): G[T]
可以通过类型参数进行通用量化的方法T
。普通函数根本不需要这样做,它所做的只是增加了apply
在单例对象上调用方法的开销,foo
而不是foo
直接调用该方法。它也无助于“避免”软件包和导入,因为无论如何您都希望将此对象包含在某个软件包中,所以您不想将其转储到默认的根软件包中。
如果要避免使用“强制” UtilWithASingleMethod
命名空间,则将isSatisfyingSomePredicate
直接添加到util
:
package object util {
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
Run Code Online (Sandbox Code Playgroud)
导入后即可使用此方法util._
。