Scala中的Trait,FunctionN或trait-inheriting-FunctionN?

Wil*_*urn 8 scala

我在Scala中有一个具有单一方法的特征.称之为Computable,单个方法是compute(input:Int):Int.我无法弄清楚我是否应该这样做

  • 使用单一方法将其保留为独立特征.
  • 继承自(Int => Int)并将"compute"重命名为"apply".
  • 只需摆脱Computable并使用(Int => Int).

支持它成为特征的一个因素是我可以有用地添加一些额外的方法.但是当然,如​​果它们都是根据计算方法实现的,那么我可以将它们分解为一个单独的对象.

支持仅使用函数类型的一个因素是简单性以及匿名函数的语法比匿名Computable实例的语法更简洁.但是,我无法区分实际上是Computable实例的对象与将Int映射到Int的其他函数,但不打算在与Computable相同的上下文中使用.

其他人如何处理这类问题?这里没有对错的答案; 我只是在寻求建议.

Mir*_*ker 8

如果你使它成为Trait并且仍然希望能够使用轻量级函数语法,你还可以在你想要它们的地方另外添加一个隐式转换:

scala> trait Computable extends (Int => Int)
defined trait Computable

scala> def computes(c: Computable) = c(5)
computes: (c: Computable)Int

scala> implicit def toComputable(f: Int => Int) = new Computable { def apply(i: Int) = f(i) }
toComputable: (f: (Int) => Int)java.lang.Object with Computable

scala> computes( (i: Int) => i * 2 )
res0: Int = 10
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用一种非常类似的方法.我有特征`Curve extends(Double => Double)`和`Surface extends((Double,Double)=> Double)`,带有提升正常scala函数的含义.如果在特性`Computable`的伴随对象中定义转换,则在从任何类型`T`到`Computable`搜索视图时,它自动处于隐式范围内. (2认同)

Ken*_*oom 3

创建从函数类型扩展的特征可能很有用,原因有几个。

  1. 您的函数对象会执行一些特殊且不明显(并且难以键入)的操作,并且您可以在构造函数中参数化细微的变化。例如,假设您正在编写一个特征来对 XML 树执行 XPath 查询。apply 函数会隐藏构建 XPath 查询机制时的多种工作,但实现该接口仍然是值得的,以便您可以使用orFunction1从一大堆不同的节点开始查询。mapflatMap

  2. 作为 #1 的扩展,您想要在构造时进行一些处理(例如解析 XPath 表达式并编译它以快速运行),您可以在对象的构造函数中提前执行一次(而如果您只是柯里化Functions如果没有子类化,编译只能在运行时发生,因此每个查询都会重复编译。)

  3. 您希望将加密函数( 的类型Function1[String,String])作为隐式传递,但并非所有Function1[String,String]s 都执行加密。通过派生Function1[String,String]并命名子类/特征EncryptionFunction,您可以确保仅隐式传递正确子类的函数。(声明时这不是真的Type EncryptionFunction = String => String。)

我希望这是清楚的。