Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: yuraОтветов: 2

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

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

scalaimplicitimplicit-conversion

Ответы

Ответ 1 · рейтинг 5 · Jean-Philippe Pellet

В 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

Ответ 2 · Destin

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

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

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 нет). В целом, может быть, эти вещи следует рассматривать как предупреждающие знаки об игре с неявными переменными манифеста?

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы