如何声明单一方法特征
How to declare a one-method trait
在 scala 中,有多种方法可以仅用一种方法声明特征
trait OneMethod extends (A => B)
trait OneMethod {
def myMethod(a: A) : B
}
每种解决方案的优缺点是什么?
通过扩展 (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)
使您的 class 在使用上更灵活一些,并且不那么冗长。另一方面,如果你想要一个比 apply
更具描述性的名称,你可以做版本 B.
同样值得注意的是:两个版本都没有将 trait 限制为只有一种方法;您可以向其中任何一个添加额外的方法。
您可以使用以下方法获得两种解决方案的优点:
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
这为您提供了灵活性和描述性,因为您既可以将其用作函数,也可以经典 方式使用。
在 scala 中,有多种方法可以仅用一种方法声明特征
trait OneMethod extends (A => B)
trait OneMethod {
def myMethod(a: A) : B
}
每种解决方案的优缺点是什么?
通过扩展 (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)
使您的 class 在使用上更灵活一些,并且不那么冗长。另一方面,如果你想要一个比 apply
更具描述性的名称,你可以做版本 B.
同样值得注意的是:两个版本都没有将 trait 限制为只有一种方法;您可以向其中任何一个添加额外的方法。
您可以使用以下方法获得两种解决方案的优点:
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
这为您提供了灵活性和描述性,因为您既可以将其用作函数,也可以经典 方式使用。