2012-02-27 11 views
5

por ejemplo, necesito acceder al manifiesto en la función def a[A:ClassManifest] para obtener la clase de borrado. Puedo usar la función Predef.implicitly pero en ese caso mi código será tan largo como si utilizo el formulario completo def a[A](implicit b:ClassManifest[A]). Entonces, ¿hay nombres generados convenientes para esos argumentos implícitos?¿Cómo puedo acceder a "implícito" implícito, es decir, def a [A: B] o def a [A <% B]?

+1

Siempre puede declarar un método con un nombre más pequeño, pero _no_ debería depender de los nombres mágicos generados por Scalac. –

Respuesta

5

Hay tres métodos predefinidos en Predef que lo hará por Manifest s, ClassManifest s y OptManifest s: manifest[T], classManifest[T] y optManifest[T], respectivamente. Puede escribir sus propios "captadores implícitos" para otras clases de tipos de acuerdo con el mismo patrón. Aquí es por ejemplo manifest[T]:

def manifest[T](implicit m: Manifest[T]) = m 

Así que aquí está cómo se podría escribir su propia:

trait UsefulTypeclass[A] { 
    def info = 42 // sample method 
} 

// the “implicit getter” 
def usefulTypeclass[A](implicit tc: UsefulTypeclass[A]) = tc 

// a method that uses the implicit getter 
def foo[A: UsefulTypeclass] = 
    usefulTypeclass[A].info 
+2

Como un buen truco: si nombra el getter implícito "apply" y lo coloca en el objeto complementario de UsefulTypeclass, puede usar "UsefulTypeclass [T]" como un valor que representa la instancia de la clase de tipo para T sin tener que importar nada más que la clase de tipo en sí. –

+0

@RM Buen truco. Supongo que tendría que ser 'UsefulTypeclass [T]()' (con el extra '()') entonces. –

+0

En realidad, no necesita los parens. Si tiene (perdone la falta de formato) el objeto TC {def apply [T] (implícita x: TC [T]) = x} puede invocarlo literalmente con solo "TC [SomeClass]" porque se está definiendo "apply" como un método sin parámetros con una lista de parámetros implícita, y [SomeClass] lo desambigua de solo una referencia al objeto TC. Desagea a TC.aplicar [SomeClass] (theIlicitValue) –

0

scalap al rescate!

Tomé este código:

object TestThing extends App { 
    def one { println("one") } 
    def two[T] { println("two") } 
    def three[T : Manifest] { println("three") } 
    def four[T: Manifest, U : Manifest] { println("four") } 
} 

y se lo pasó por scalap. Aquí es lo que tengo:

object TestThing extends java.lang.Object with scala.App with scala.ScalaObject { 
    def this() = { /* compiled code */ } 
    def one : scala.Unit = { /* compiled code */ } 
    def two[T] : scala.Unit = { /* compiled code */ } 
    def three[T](implicit evidence$1 : scala.Predef.Manifest[T]) : scala.Unit = { /* compiled code */ } 
    def four[T, U](implicit evidence$2 : scala.Predef.Manifest[T], evidence$3 : scala.Predef.Manifest[U]) : scala.Unit = { /* compiled code */ } 
} 

Como se puede ver, el primer Manifiesto implícita se llama evidence$1. ¡El segundo y tercero: aunque en un alcance diferente! -se llaman evidence$2 y evidence$3. Entonces ... así es como haces referencia a Manifiestos.

A pesar de eso, me parece un poco aterrador que eliminar un Manifiesto que está más arriba en la clase cambie el nombre de un Manifiesto que se encuentra más abajo en el archivo. Del mismo modo, tampoco ayuda que el complemento de sintaxis del complemento IntelliJ Scala parezca pensar que las variables de Manifiesto en el alcance en four() son evidence$1 y evidence$2, y no cree que evidence$3 sea una variable válida allí (aunque sí lo es, y evidence$1 no). En general, tal vez estas cosas deberían ser consideradas como señales de advertencia sobre jugar con variables de Manifiesto implícitas.

+2

¡Seguramente esos nombres deberían ser un detalle de implementación interna y no se debe confiar en ellos! – Ben

+0

@Ben No obtendrás ninguna oposición mía allí ... – Destin

+1

Es por eso que usas 'implícitamente' ... tratando de usar' evidence $ 1' etc. en tu código no compilará. –

Cuestiones relacionadas