我正在尝试学习Scala,所以我决定用它来实现数据结构。我已经开始使用Stack了。我创建了以下Stack类。
class Stack[A : Manifest]() {
var length:Int = -1
var data = new Array[A](100)
/**
* Returns the size of the Stack.
* @return the size of the stack
*/
def size = {length}
/**
* Returns the top element of the Stack without
* removing it.
* @return Stacks top element (not removed)
*/
def peek[A] = {data(length)}
/**
* Informs the developer if the Stack is empty.
* @return returns true if it is empty else false.
*/
def isEmpty = {if(length==0)true else false}
/**
* Pushes the specified element onto the Stack.
* @param The element to be pushed onto the Stack
*/
def push(i: A){
if(length+1 == data.size) reSize
length+=1
data(length) = i;
}
/**
* Pops the top element off of the Stack.
* @return the pop'd element.
*/
def pop[A] = {
length-=1
data(length)
}
/**
* Increases the size of the Stack by 100 indexes.
*/
private def reSize{
val oldData = data;
data = new Array[A](length+101)
for(i<-0 until length)data(i)=oldData(i)
}
}
然后尝试使用以下
在我的Java类中初始化此类Stack<Integer> stack = new Stack<Integer>();
但是,我被告知构造函数不存在,我应该添加一个参数来匹配Manifest。为什么会发生这种情况,我该如何解决?
答案 0 :(得分:18)
Alexey给了你正确的解释,但绝对可以在你的代码中创建清单(你只需要一个java.lang.Class
对象,你可以用Java轻松创建它。)
首先,您应该将一个java友好的工厂方法添加到Stack的伴随对象:
object Stack {
def ofType[T]( klass: java.lang.Class[T] ) = {
val manifest = new Manifest[T] {
def erasure = klass
}
new Stack()(manifest)
}
}
此方法将生成相应的清单(来自java类),并将显式传递给Stack
构造函数。然后,您可以毫不费力地从Java中使用它:
Stack<String> stack = Stack.ofType( String.class );
stack.push( "Hello" );
stack.push( "World" );
System.out.println( stack.size() );
System.out.println( stack.peek() );
答案 1 :(得分:9)
这是因为像[A : Manifest]
这样的上下文绑定只是隐式构造函数参数的简写。所以你的班级“真的”被宣称为class Stack[A]()(implicit m: Manifest[A]) {
。因此,创建Manifest
的唯一方法是编译器魔术(据我所知),你不能用Java来做,也不能在那里构造Stack
。
您可以更改设计以避免显示,也可以在Scala代码中创建Stack
的实例,并仅在Java中使用它们。
答案 2 :(得分:2)
跟进范式答案,您还可以为您的班级创建构造函数:
class Stack[A](implicit m: Manifest[A]) {
def this(clazz : Class[A]) {
this()(new Manifest[A] {
def erasure = clazz
})
}
然后可以从Java调用:
Stack<Integer> s = new Stack<Integer>(Integer.class);
s.push(1);
System.out.println(s.peek());
然而,问题在于泛型类型,比如堆栈的字符串堆栈。为此,您应该查看此主题:http://www.scala-lang.org/node/7267