在scala中,有多种方法可以使用一种方法声明特征
trait OneMethod extends (A => B)
trait OneMethod {
def myMethod(a: A) : B
}
每种解决方案的优点和缺点是什么?
答案 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
这为您提供了灵活性和描述性,因为您可以将其用作函数和经典方式。