为什么不将函数定义为单例函数?
Why not define functions as singleton functions?
考虑在无形回购中找到的 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 = ???
}
注意 call-site 现在是如何变成的
isSatisfyingSomePredicate(foo)
而不是
UtilWithASingleMethod.isSatisfyingSomePredicate(foo)
或
import UtilWithASingleMethod._
isSatisfyingSomePredicate(foo)
就我个人而言,UtilWithASingleMethod
包似乎只是为了能够使用熟悉的 def
语法而被迫,但没有添加任何有用的信息。
除了不熟悉或与工厂模式中使用的 object+apply 样式混淆等主观缺点外,单例函数定义是否存在任何技术缺点?
他们必须在您链接的文件中创建单例对象的原因是这些不是函数,而是多态函数,也就是说,他们有一个 apply[T](a: F[T]): G[T]
方法,该方法由类型参数 T
普遍量化。这对于普通函数来说根本不需要,它所做的只是增加在单例对象 foo
上调用 apply
方法的开销,而不是直接调用 foo
方法。它对你 "avoid" 包和导入也没有帮助,因为无论如何你都想在某个包中拥有这个对象,你不想将它转储到默认的根包中。
如果你想避免"forced" UtilWithASingleMethod
命名空间,那么直接将isSatisfyingSomePredicate
添加到util
:
package object util {
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
一旦您导入此方法就可用 util._
。
Scala 3 (Dotty) 支持 toplevel definitions,而不是
package utils
object UtilWithASingleMethod {
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
我们可以去掉间接寻址然后写
package utils
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
这确实解决了我的问题。
考虑在无形回购中找到的 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 = ???
}
注意 call-site 现在是如何变成的
isSatisfyingSomePredicate(foo)
而不是
UtilWithASingleMethod.isSatisfyingSomePredicate(foo)
或
import UtilWithASingleMethod._
isSatisfyingSomePredicate(foo)
就我个人而言,UtilWithASingleMethod
包似乎只是为了能够使用熟悉的 def
语法而被迫,但没有添加任何有用的信息。
除了不熟悉或与工厂模式中使用的 object+apply 样式混淆等主观缺点外,单例函数定义是否存在任何技术缺点?
他们必须在您链接的文件中创建单例对象的原因是这些不是函数,而是多态函数,也就是说,他们有一个 apply[T](a: F[T]): G[T]
方法,该方法由类型参数 T
普遍量化。这对于普通函数来说根本不需要,它所做的只是增加在单例对象 foo
上调用 apply
方法的开销,而不是直接调用 foo
方法。它对你 "avoid" 包和导入也没有帮助,因为无论如何你都想在某个包中拥有这个对象,你不想将它转储到默认的根包中。
如果你想避免"forced" UtilWithASingleMethod
命名空间,那么直接将isSatisfyingSomePredicate
添加到util
:
package object util {
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
一旦您导入此方法就可用 util._
。
Scala 3 (Dotty) 支持 toplevel definitions,而不是
package utils
object UtilWithASingleMethod {
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
我们可以去掉间接寻址然后写
package utils
def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
这确实解决了我的问题。