например, мне нужно получить доступ к манифесту в функции def a[A:ClassManifest], чтобы получить класс стирания. Я могу использовать функцию Predef. Неявно, но в этом случае мой код будет таким же длинным, как если бы я использовал полную форму def a[A](implicit b:ClassManifest[A]). Так есть ли удобные сгенерированные имена для этих неявных аргументов?
Вопрос
Как я могу получить доступ к неявному неявному, т.е. def a [A: B] или def a [A ‹% B]?
- Вы всегда можете объявить метод с меньшим именем, но вы не должны не полагаться на магические имена, генерируемые Scalac. Daniel C. Sobral 28.02.2012
Ответы
Ответ 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.
Похожие материалы
- Декодирование структурированных массивов JSON с помощью Circe в Scala
- Переполнение стека в классе типов с неявным преобразованием
- Заархивируйте универсальный HList со статическим Nat HList
- Как косвенно передать неявный аргумент
- Почему неявное преобразование не рассматривается в этом случае с универсальными параметрами?
- Как сделать неявное преобразование типов, используемых в моем интерпретаторе