У Scala ми можемо використовувати принаймні два методи для модернізації існуючих або нових типів. Припустимо, ми хочемо висловити, що щось можна кількісно визначити за допомогою Int. Ми можемо визначити наступну рису.
Неявне перетворення
trait Quantifiable{ def quantify: Int }
І тоді ми можемо використовувати неявні перетворення для кількісної оцінки, наприклад, рядків та списків.
implicit def string2quant(s: String) = new Quantifiable{
def quantify = s.size
}
implicit def list2quantifiable[A](l: List[A]) = new Quantifiable{
val quantify = l.size
}
Після імпортування ми можемо викликати метод quantifyу рядках та списках. Зауважте, що кількісно визначений список зберігає його довжину, тому він уникає дорогого обходу списку під час наступних дзвінків на quantify.
Класи типу
Альтернативою є визначення "свідка", Quantified[A]який стверджує, що деякий тип Aможе бути визначений кількісно.
trait Quantified[A] { def quantify(a: A): Int }
Потім ми надаємо екземпляри цього класу типу для Stringі Listдесь.
implicit val stringQuantifiable = new Quantified[String] {
def quantify(s: String) = s.size
}
І якщо ми тоді пишемо метод, який повинен кількісно визначити свої аргументи, ми пишемо:
def sumQuantities[A](as: List[A])(implicit ev: Quantified[A]) =
as.map(ev.quantify).sum
Або за допомогою синтаксису, пов’язаного з контекстом:
def sumQuantities[A: Quantified](as: List[A]) =
as.map(implicitly[Quantified[A]].quantify).sum
Але коли застосовувати який метод?
Тепер постає питання. Як я можу вибрати між цими двома поняттями?
Те, що я помітив досі.
типові класи
- класи дозволяють мати приємний синтаксис, пов'язаний з контекстом
- з класами типів я не створюю новий об'єкт-обгортку при кожному використанні
- контекстний синтаксис більше не працює, якщо клас типу має кілька параметрів типу; уявіть, я хочу кількісно оцінити речі не тільки цілими числами, але і значеннями якогось загального типу
T. Я хотів би створити клас типуQuantified[A,T]
неявне перетворення
- оскільки я створюю новий об'єкт, я можу кешувати там значення або обчислювати краще представлення; але чи слід уникати цього, оскільки це може відбуватися кілька разів, і явне перетворення, мабуть, буде викликане лише один раз?
Чого я очікую від відповіді
Наведіть один (або більше) випадків використання, коли різниця між обома поняттями має значення, та поясніть, чому я віддав би перевагу одному перед іншим. Також було б непогано пояснити суть двох понять та їх відношення один до одного, навіть без прикладу.