Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Take private class instance as constructor argument

Tags:

scala

In a Scala class with an inner class, how can you declare a constructor that takes an instance of that class as an argument?

i.e. this works

class Element[T](val v : T, val next : Element[T])

class MyStack[T] private (private val first : Element[T]) {
    def this() = this(null)
    def push(v : T) = new MyStack[T](new Element[T](v,first))
    def pop() = new MyStack[T](first.next)
    def top() = first.v
}

this doesn't.

class MyStack[T] private (private val first : Element) {
    private class Element(val v : T, val next : Element)
    def this() = this(null)
    def push(v : T) = new MyStack[T](new Element(v,first))
    def pop() = new MyStack[T](first.next)
    def top() = first.v
}
like image 812
Cubic Avatar asked May 03 '26 04:05

Cubic


2 Answers

Since Element can not be seen from outside, you should refer to it in context of outer class

class MyStack[T] private (first: MyStack[T]#Element) {
  class Element(val v: T, val next: MyStack[T]#Element)
  def this() = this(null)
  def push(v: T) = new MyStack[T](new Element(v, first))
  def pop() = new MyStack[T](first.next)
  def top() = first.v
}
like image 118
4e6 Avatar answered May 04 '26 19:05

4e6


I don't know why you want to do this (you should maybe add some information about that), but it is possible, just not with a private inner class. The parameter itself has to be a call by name and it has to be assigned to a lazy val, so that it only gets evaluated, after the outer instance is ready.

class Foo[A](_x: => Foo[A]#Bar) {
  lazy val x = _x
  class Bar
}

scala> lazy val x: Foo[Int] = new Foo[Int](new x.Bar)
x: Foo[Int] = <lazy>

scala> x.x
res8: Foo[Int]#Bar = Foo$Bar@76ba819c
like image 33
drexin Avatar answered May 04 '26 18:05

drexin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!