如何声明单方法特征

时间:2015-03-12 20:19:43

标签: scala traits

在scala中,有多种方法可以使用一种方法声明特征

trait OneMethod extends (A => B)

trait OneMethod {
  def myMethod(a: A) : B
}

每种解决方案的优点和缺点是什么?

2 个答案:

答案 0 :(得分:6)

通过扩展(A => B),您说OneMethod 是一个函数,可以直接使用:

trait TraitA extends (Int => String)
class ClassA extends TraitA { def apply(i: Int) = i.toString }

val a = new ClassA
(1 to 5).map(a)      // IndexedSeq[String] = Vector(1, 2, 3, 4, 5)

如果你不延长(A => B),你就无法做到;相反,您必须明确告诉它方法名称是什么:

trait TraitB { def myMethod(i: Int): String }
class ClassB extends TraitB { def myMethod(i: Int) = i.toString }

val b = new ClassB
(1 to 5).map(b)              // error, required: Int => ?
(1 to 5).map(b.myMethod)     // IndexedSeq[String] = Vector(1, 2, 3, 4, 5)

所以:扩展(A => B)使你的课程在使用方面更加灵活,而且冗长程度更低。另一方面,如果您想要一个比apply更具描述性的名称,则可以使用版本B.

另外值得注意的是:两个版本都没有将特征限制为只有一种方法;你可以添加额外的方法。

答案 1 :(得分:0)

您可以使用以下方法获得两种解决方案的专业人员:

trait Transformer[A, B] extends (A => B) {
  override def apply(a: A): B = transform(a)
  def transform(a: A): B
}

object FooTransformer extends Transformer[String, String] {
  override def transform(a: String): String = a + ", world"
}

val transformer = FooTransformer

// "classic" usage
val foo = "hello"
// "hello, world"
val transformedFoo = transformer.transform(foo) 

// functional usage
val fooList = List("foo", "bar", "baz")
// List("foo, world", "bar, world", "baz, world")
val transformedFooList = fooList map transformer 

这为您提供了灵活性和描述性,因为您可以将其用作函数和经典方式。