2011-01-24 1 views
3

J'essaye d'écrire une méthode d'assistance simple qui reçoit quelque chose qui peut être fermé et une fonction qui reçoit le premier et qui s'assure que le "fermable" est fermé après l'exécution de la fonction.Pourquoi ce type de structure lié ne fonctionne pas comme prévu?

Par exemple, je veux l'utiliser comme ceci:

closing(new FileOutputStream("/asda"))(_.write("asas")) 

Mon impl est

object Helpers { 

    def closing[T <: { def close }](closeable: T)(action: T => Unit): Unit = 
    try action apply closeable finally closeable close 

} 

Mais en essayant de compiler ce test simple:

object Test { 

    import Helpers._ 

    closing(new FileOutputStream("/asda"))(_.write("asas")) 

} 

Le compilateur se plaint de:

arguments de type inférées [java.io.FileOutputStream] ne pas sont conformes au type limites des paramètres de fermeture de la méthode [T <: AnyRef {def fermé: Unité}]

Toutes les idées pourquoi?

Répondre

11

Vous devez écrire

def closing[T <: { def close() }] 

il y a une différence entre les méthodes de Scala avec des parenthèses vides et des méthodes sans parenthèses du tout.

+0

Et 'FileOutputStream.write' ne peut apparemment pas prendre de chaîne. Appelez 'getBytes()' sur la chaîne. – Malvolio

7

Les limites de type sont difficiles. En particulier, Scala suit le nombre de listes de paramètres en plus des paramètres eux-mêmes. Essayez-les!

class A { def f = 5 } 
class B { def f() = 5 } 
class C { def f()() = 5 } 
def useA[X <: { def f: Int }](x: X) = x.f 
def useB[X <: { def f(): Int }](x: X) = x.f 
def useC[X <: { def f()(): Int}](x: X) = x.f 

useA(new A) // This works, but what other combinations do? 

Dans votre cas, vous voulez

def closing[T <: { def close() }] ... 

post-scriptum Si vous prévoyez vraiment sur l'utilisation de ce lot, vous devriez probablement jouer avec

class D extends B { override def f = 6 } 
class E extends A { override def f() = 6 } 

et voir quels use vous devez utiliser dans chaque cas.

Questions connexes