2012-07-23 12 views
5

Estaba escribiendo una clase de matriz en Scala, y pensé que la mejor forma de implementar una operación de transposición sería simplemente devolver una interfaz con todas las operaciones "transpuestas". Entonces, si matrix.apply(i, j) devuelve el elemento (i, j) th, entonces matrix.transpose devuelve una interfaz (pero no una copia de los datos) que contiene un método de aplicación que devuelve la matriz (j, i). Y escribí esa interfaz algo así como esto (lo que realmente escribí es mucho más desordenado):En Scala, ¿qué sucede cuando un objeto interno extiende la clase que lo incluye?

abstract class Matrix { 
    def apply(i : Int, j : Int) : Double 
    //other matrixy operations 
    private def outer = this //so the inner can see the enclosing instance 
    object TransposedInterface extends Matrix { 
     def apply(i :Int, j : Int) = outer(j, i) 
    } 
} 

Cuál es lindo, supongo, pero ahora TransposedInterface también tiene un objeto en su interior llama TransposedInterface, y así sucesivamente, de forma recursiva , y donde termina todo?

He intentado lo siguiente en el intérprete:

class Outer(val i : Int) { 
    object Inner extends Outer(i + 1) 
} 

val o = new Outer(1) 
o.Inner.Inner.Inner.Inner.i 

que se ejecuta y evalúa a 5, como debe ser, supongo.

Entonces, ¿qué está pasando realmente? ¿El objeto interno es evaluado perezosamente? ¿Es basura recolectada cuando no se está usando inmediatamente, y luego se vuelve a instanciar la próxima vez externa? ¿Se llama interna? ¿Es algún vudú en el que no he pensado?

Respuesta

3

Se crea una instancia de forma perezosa y no se recolectará basura hasta que se recolecte la clase externa, ya que la clase externa contiene una referencia.

En general, object Foo { ... } actúa de forma muy similar a lazy val Foo = { ... }. Como los objetos no pueden ser nulos cuando son válidos, pero son ciertamente objetos, son más eficientes (verificación más rápida de la existencia; solo ve si el campo es nulo) en este contexto, pero tienen el inconveniente de requerir un segundo archivo .class. (Por lo general, no te importa cuántos archivos de clase hay, por lo que probablemente no sea un gran problema.)

+0

¡Gracias! Y resulta que conocer la respuesta hace que sea mucho más fácil encontrar [la respuesta] (http://stackoverflow.com/questions/3448691/val-and-object-inside-a-scala-class). –

Cuestiones relacionadas