2016-07-08 16 views
2

In Scala ist es üblich, Klassenarten als Generika zu übergeben oder explizit weiterzugeben?Scala-Funktionsargumente: generischer Typ der Klasse vs Funktion, z.B. f (classOf [Foo], "bar") vs f [Foo] ("bar")

Zum Beispiel habe ich eine Hilfsfunktion erstellt, um ein Java-Objekt zu erstellen, das eine Quellausnahme, eine Zielausnahme und einen dritten Parameter aufnimmt (ich benutze nur eine Zeichenfolge für dieses Beispiel). Welche ist besser Praxis in Scala:

exceptionTranslation(classOf[FooException], classOf[BarException], "blah") 

def exceptionTranslation(sourceClazz: Class[_ <: Throwable], targetClazz: Class[_ <: Throwable], message: String) = new Translation() 
    .withSource(sourceClazz) 
    .withTarget(targetClazz) 
    .withMessage(message) 

Oder

exceptionTranslation[FooException, BarException]("blah") 

def exceptionTranslation[Source <: Throwable, Target <: Throwable](message: String)(
implicit source: ClassTag[Source], target: ClassTag[Target]) = new Translation() 
    .withSource(source.runtimeClass.asInstanceOf[Class[Source]]) 
    .withTarget(target.runtimeClass.asInstanceOf[Class[Target]]) 
    .withMessage(message) 
+1

ich die ersten besser gefällt als Sie implicits und Runtime-Casting nicht brauchen, aber es ist ein Angelegenheit der Präferenz. –

+0

Stimmen Sie mit @Tuval überein, der zweite ist absolut übertrieben – Chirlo

Antwort

1

Ich denke, ist nur eine Frage des Stils. Sie sind alle richtig. Persönlich würde ich mit demjenigen gehen, der intuitiver, kürzer und am wenigsten leistungsfähig ist.

Beispiel der Textnamen einer Klasse von extra:

import scala.reflect._ 
def bar[F](x: Class[F]) = x.getName 

def foo[X:ClassTag] = implicitly[ClassTag[X]].runtimeClass.getName 

def foobar[X](implicit ctag: ClassTag[X]) = ctag.runtimeClass.getName 

Verbrauch:

> bar(classOf[Double]) // This one has better Java interop 
res: String = "double" 

> foo[Double] // This looks slightly less verbose when calling 
res: String = "double" 

> foobar[Double] 
res: String = "double" 
+0

Die Funktion war privat und für mich fühlte es sich merkwürdig an, die generischen Typen der Funktion zu verwenden, um Parameter zu übergeben, aber viel sauberer beim Aufruf der Funktion (der "foo" oder " Foobar "Weg). Da die meisten Leute die Liste der Ausnahmeübersetzungen lesen würden und nie wirklich auf die private Hilfsfunktion schauen würden, dachte ich, es wäre wichtiger, die Aufrufe der Funktion zu vereinfachen. –