假设你有一个Person类,并通过扩展例如ArrayBuffer为它创建一个集合类:
class Persons extends ArrayBuffer[Person] {
// methods operation on the collection
}
Run Code Online (Sandbox Code Playgroud)
现在,使用ArrayBuffer,可以在随播对象上使用apply()方法创建一个集合,例如:
ArrayBuffer(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
您希望能够对人员做同样的事情,例如:
Persons(new Person("John", 32), new Person("Bob", 43))
Run Code Online (Sandbox Code Playgroud)
我的第一个直觉是扩展ArrayBuffer伴侣对象并免费获取apply()方法.但似乎你无法扩展对象.(我不太清楚为什么.)
接下来的想法是使用apply()方法创建一个Persons对象,该方法调用ArrayBuffer的apply方法:
object Persons {
def apply(ps: Person*) = ArrayBuffer(ps: _*)
}
Run Code Online (Sandbox Code Playgroud)
但是,这会返回一个ArrayBuffer [Person]而不是Persons.
在scaladoc和ArrayBuffer的源代码中进行了一些挖掘之后,我提出了以下内容,我认为这将使Persons对象从GenericCompanion继承apply():
编辑:
object Persons extends SeqFactory[ArrayBuffer] {
def fromArrayBuffer(ps: ArrayBuffer[Person]) = {
val persons = new Persons
persons appendAll ps
persons
}
def newBuilder[Person]: Builder[Person, Persons] = new ArrayBuffer[Person] mapResult fromArrayBuffer
}
Run Code Online (Sandbox Code Playgroud)
但是,它给出以下错误消息:
<console>:24: error: type mismatch;
found : (scala.collection.mutable.ArrayBuffer[Person]) => Persons …Run Code Online (Sandbox Code Playgroud) 我目前正在发现scala,我想知道我是否可以使用工厂的特性.
我试过这个:
abstract class Foo {
...
}
object Foo {
def apply() = new Bar
private class Bar extends Foo {
...
}
}
Foo() with MyTrait // Not working
我想这是因为with必须先于new.
有没有办法做到这一点?
谢谢
我在Scala中有以下课程:
class A {
def doSomething() = ???
def doOtherThing() = ???
}
class B {
val a: A
// need to enhance the class with both two functions doSomething() and doOtherThing() that delegates to A
// def doSomething() = a.toDomething()
// def doOtherThing() = a.doOtherThing()
}
Run Code Online (Sandbox Code Playgroud)
我需要一种在编译时使用与A相同的函数签名来增强类B的方法,该函数签名在B上调用时简单地委托给A。
在Scala中有什么好方法吗?
谢谢。
我是Scala新手,请原谅我,如果这是一个愚蠢的问题,但是这里......
想象一下,我希望创建一个包含其他方法的扩展Map类型.我可以看到几种方法来做到这一点.第一个是组成:
class Path[V](val m: Map[V, Int]) {
// Define my methods
}
Run Code Online (Sandbox Code Playgroud)
另一种是通过继承,例如
class Path[V] extends Map[V, Int] {
// Define my methods
}
Run Code Online (Sandbox Code Playgroud)
最后,我还考虑了"特质"路线,例如
trait Path[V] extends Map[V, Int] {
// Define my methods
}
Run Code Online (Sandbox Code Playgroud)
构图有点尴尬因为你经常不得不引用里面的东西.遗传是相当自然的,但我有一个皱纹(更多的是一秒).Traits看起来像是一种非常优雅的方式,并且使用"with"构造它非常好但它对我来说也有问题.
我遇到的皱纹是用像++这样的方法.他们返回一张新地图.所以让我们说上面提到的"我的方法"希望在地图上添加一些东西(只是一个例子,我知道地图已经有了这个),例如
trait Path[V] extends Map[V,Int] {
def addOne(v: V, i: Int): Path[V] = this + (v -> i)
}
Run Code Online (Sandbox Code Playgroud)
这会生成错误,因为返回类型不是Path [V].现在我知道我可以在新实例上使用"with"来添加Path [V]特征.但我不控制这里新地图的构造.有没有办法添加Path [V]特征?我考虑创建一个预先填充的新不可变映射,然后在"with Path [V]"上进行标记,但是没有这样的构造函数可以用来创建预先填充的映射.
我怀疑(虽然我还没有确认)我会有类似的问题使用继承.我可以添加一个新方法来向地图添加一个新条目,但我不会得到一个"Path [V]"这就是我想要的.组合方法似乎是走到这里的唯一方法.
我希望这很清楚.评论?