(Scala beginner question)
I am trying to write a program in Scala that does a number of checks on C++ source files, and I want to implement optional logging of checks.
The following works fine for a single check:
val headerFiles = files.filter(_.matches(".*?\\.h$"))
val headerGuardChecker = if(options.contains('verbose)) {
new HeaderGuard with LoggingFileCheckerTrait
} else {
new HeaderGuard
}
headerFiles.foreach(h => if (! headerGuardChecker.check(new File(h))) println(h + " doesn't have a header guard"))
however when I try to generalize this using generics:
def checker[T] = if(options.contains('verbose)) {
new T with LoggingFileCheckerTrait
} else {
new T
}
val headerFiles = files.filter(_.matches(".*?\\.h$"))
headerFiles.foreach(h => if (! checker[HeaderGuard].check(new File(h))) println(h + " doesn't have a header guard"))
I get compile errors on the two new statements, claiming that T isn't a type. I believe this caused by type erasure, but I haven't found a way of working round this. Is there a way of doing what I want to do?
One way to do that in Scala is to define some factory that knows how to produce instances of our types and evidence that allows that factory to return our specific types. This is a version of the code above introducing such construct and using ContextBounds to obtain the right factory instance of the type we want.
To use a generic class, put the type in the square brackets in place of A . The instance stack can only take Ints. However, if the type argument had subtypes, those could be passed in: Scala 2.
Generic MethodsAll generic method declarations have a type parameter section delimited by angle brackets (< and >) that precedes the method's return type ( < E > in the next example). Each type parameter section contains one or more type parameters separated by commas.
Take a look at Scala "manifests". They often allow you to circumvent type erasure on the JVM.
scala> def instantiate[T](implicit m:Manifest[T]) = m.erasure.newInstance().asInstanceOf[T]
instantiate: [T](implicit m: Manifest[T])T
scala> instantiate[String]
res0: String = ""
Here's a good intro for manifests in Scala
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With