2012-02-27 4 views
5

например, мне нужно получить доступ к манифесту в функции def a[A:ClassManifest], чтобы получить класс стирания. Я могу использовать функцию Predef.implicitly, но в этом случае мой код будет таким, как если бы я использовал полную форму def a[A](implicit b:ClassManifest[A]). Так есть ли сгенерированные имена для этих неявных аргументов?Как я могу получить доступ к неявному «неявному», т. Е. Def a [A: B] или def a [A <% B]?

+1

Вы всегда можете объявить метод с меньшим именем, но вы не должны зависеть от магических имен, созданных Scalac. –

ответ

5

Есть три предопределенные методы Predef, которые будут делать это за Manifest с, ClassManifest s и s OptManifest: manifest[T], classManifest[T] и optManifest[T] соответственно. Вы можете написать свои собственные «неявные геттеры» для других классов типов в соответствии с одним и тем же шаблоном. Вот, например manifest[T]:

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

Так вот, как вы могли бы написать свой собственный:

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

Как аккуратный трюк: если вы назовете неявный геттер «применить» и поместите его на сопутствующий объект «Полезный», вы можете использовать «ПолезныйТипец [Т]» в качестве значения, представляющего экземпляр класса типов для Т, не импортируя ничего больше, чем сам класс. –

+0

@RM Отличный трюк. Я предполагаю, что это должно быть «ПолезноТипец [T]()» (с дополнительным «()»). –

+0

На самом деле он не нуждается в parens. Если у вас есть (простить отсутствие форматирования) объект TC {def apply [T] (неявный x: TC [T]) = x}, вы можете буквально вызывать его только с помощью «TC [SomeClass]», потому что «apply» определяется как беспараметрированный метод с неявным списком параметров, а [SomeClass] однозначно устраняет его только из ссылки на объект TC. Это desugars для TC.apply [SomeClass] (theImplicitValue) –

0

scalap на помощь!

Я взял этот код:

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") } 
} 

и побежал через scalap. Вот что я получил:

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 */ } 
} 

Как вы можете видеть, первый неявный манифеста называется evidence$1. Второй и третий - , хотя в другом объеме! - можно назвать evidence$2 и evidence$3. Итак ... так вы ссылаетесь на Manifests.

Несмотря на это, мне кажется немного страшным, что удаление манифеста, которое выше в классе, изменит имя манифеста, расположенного ниже в файле. Точно так же это не помогает, что подсветка синтаксиса плагина IntelliJ Scala кажется, что переменные Manifest в области в four(): evidence$1 и evidence$2, и не считает, что evidence$3 является допустимой переменной (хотя это, и evidence$1 нет). В целом, может быть, эти вещи следует учитывать как предупреждающие знаки о игре с неявными переменными манифеста?

+2

Несомненно, эти имена должны быть внутренней реализацией и не опираться! – Ben

+0

@Ben Вы не получите от меня никакого сопротивления .... – Destin

+1

Вот почему вы используете 'неявно' ... пытающийся использовать' доказательство $ 1' и т. Д. В вашем коде не будет компилироваться. –