Как я могу получить доступ к неявному неявному, т.е. def a [A: B] или def a [A ‹% B]?

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


person yura    schedule 27.02.2012    source источник
comment
Вы всегда можете объявить метод с меньшим именем, но вы не должны не полагаться на магические имена, генерируемые Scalac.   -  person Daniel C. Sobral    schedule 28.02.2012


Ответы (2)


В Predef есть три предопределенных метода, которые будут делать это для Manifests, ClassManifests и OptManifests: 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
person Jean-Philippe Pellet    schedule 27.02.2012
comment
В качестве изящного трюка: если вы назовете неявный получатель apply и поместите его в сопутствующий объект UsefulTypeclass, вы можете использовать UsefulTypeclass [T] в качестве значения, представляющего экземпляр класса типов для T, без необходимости импортировать ничего, кроме самого класса типов. - person RM.; 28.02.2012
comment
@RM Хороший трюк. Думаю, тогда это должно быть UsefulTypeclass[T]() (с дополнительным ()). - person Jean-Philippe Pellet; 28.02.2012
comment
На самом деле это не нуждается в паренах. Если у вас есть (простите за отсутствие форматирования) объект TC {def apply [T] (implicit x: TC [T]) = x}, вы можете буквально вызвать его только с помощью TC [SomeClass], потому что apply определяется как метод без параметров с неявным списком параметров, и [SomeClass] устраняет неоднозначность от простой ссылки на объект TC. Он обессахаривает TC.apply [SomeClass] (theImplicitValue) - person RM.; 28.02.2012
comment
@RM О, хорошо. Спасибо за объяснение. - person Jean-Philippe Pellet; 28.02.2012

скальп спешит на помощь!

Я взял такой код:

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

и пробежал через скальп. Вот что у меня получилось:

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. Итак ... вот как вы относитесь к манифестам.

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

person Destin    schedule 27.02.2012
comment
Конечно, эти имена должны быть внутренней деталью реализации, а не на них полагаться! - person Ben; 28.02.2012
comment
Вот почему вы используете _1 _... попытки использовать evidence$1 и т. Д. В своем коде не компилируются. - person Luigi Plinge; 28.02.2012
comment
@LuigiPlinge На самом деле он компилируется ... достаточно пугающе. - person Destin; 28.02.2012