2010-10-23 10 views
9

Me gustaría tener un FileWriter abierto durante todo el tiempo que exista una instancia de clase. Entonces necesito cerrarlo en un destructor. Pero, ¿cómo especificar un destructor en Scala?¿Cómo escribir un destructor de clase en Scala?

+2

Dado que no se destruyen objetos en Scala (o Java), y no hay garantía de que el objeto alguna vez se desasignara, ¿cuál sería el uso de especificar un destructor? –

+0

Sugiero que vincular la duración de la transmisión a una instancia es conceptualmente incorrecta desde el principio. Debería tener la duración del recurso vinculada a los ámbitos de ejecución. Es decir. siempre debe cerrar el recurso en el mismo ámbito en el que está abierto. –

Respuesta

7

Scala no tiene destructores. Tiene finalizadores, como Java, pero no son lo mismo en absoluto. También hay una serie interesante blog en emular using palabra clave C# 's en Scala aquí:

+1

Consulte también la interfaz ['Closeable'] (http://download.oracle.com/javase/7/docs/api/java/io/Closeable.html) (específicamente para IO) y la próxima (Java 7) más general ['AutoCloseable'] (http://download.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html). –

+0

@Matthew: ¿No crees que es más una respuesta alternativa que un comentario sobre mi respuesta? –

+0

@ matthew-flaschen ¿quiere decir que un objeto FileWriter se cerrará automáticamente cuando sea GCd? – Ivan

8

también te pueden interesar de revisar el proyecto Scala-brazo de Josh Suereth , que proporciona administración de recursos basada en continuación monadic y delimitada para esta fuente de uso: http://github.com/jsuereth/scala-arm

Si realmente crees que necesitas un destructor (es decir porque cree que necesita crear el objeto y luego entregarlo y no volver a verlo nunca más) Le recomiendo reconsiderar la arquitectura de su aplicación en su lugar ... simplemente no hay forma de hacer que esto funcione de manera confiable en la JVM.

2

Como mencioné anteriormente, Java tiene una interfaz existente Closeable específicamente para IO, que usted podría adoptar. Esto no proporciona azúcar, pero ayudará a las personas a usar su clase correctamente.

En Java 7, Closeable será una subinterfaz de AutoCloseable. AutoCloseable es una interfaz más general para cualquier recurso que debe cerrarse después de su uso, mientras que potencialmente arroja una excepción. es parte del soporte Automatic Resource Management planificado en Java 7. Menos relevante para su pregunta (ya que está usando Scala), también se supone que es el nuevo Java syntax (una extensión de los bloques try existentes) para este escenario.

5

Este es un práctico método de utilidad que uso con frecuencia. Me parece que despeja mi código muy bien.

def closer [T, C <: Closeable] (c : C) (f : C => T) : T = 
    try f (c) 
    finally c.close 

Usarlo es muy simple. El ejemplo, a continuación, consume un flujo de entrada de una URLConnection. En lugar de connection.getInputStream, puedes crear cualquier flujo arbitrario, por supuesto (o, de manera más general, cualquier objeto arbitrario que se pueda cerrar).

val bytes = closer (connection.getInputStream) { istream => 
     val bytes = new ByteArrayOutputStream() 
     val buffer : Array [Byte] = new Array (1024) 
     Iterator.continually (istream read buffer).takeWhile (_ > 0).foreach (bytes write (buffer, 0, _)) 
     bytes.toByteArray 
    } 

Esta versión funcionará en cualquier cosa con un método cercano (no es necesario implementar Cerrar o cualquier otra cosa).

def autoClose[R <: {def close()}, T](resource: R)(use: R => T): T = { 
    try use(resource) 
    // Don't want an NPE here masking an exception from use. 
    finally Option(resource).foreach(_.close()) 
} 

Aquí hay algunas clases implícitas para hacer el trabajo.

implicit class AutoCloseBracket[R <: Closeable](resource: R) { 
    def autoClose[V](use: R => V): V = try use(resource) finally resource.close() 
} 
implicit class AutoCloseableBracket[R <: AutoCloseable](resource: R) { 
    def autoClose[V](use: R => V): V = try use(resource) finally resource.close() 
} 
Cuestiones relacionadas