سؤال

وأنا أحاول أن أكتب بعض التعليمات البرمجية سكالا التي تحتاج إلى القيام بشيء ما مثل:

class Test[Type] { 
   def main {
       SomeFunc classOf[Type]
       val testVal: Type = new Type()
    }
 }

ووانها فاشلة. أنا بالطبع لا تفهم شيئا عن المعلمات العامة سكالا. ومن الواضح أن سوء الفهم هو أنه في C ++، قوالب تعمل أساسا مثل استبدال سلسلة، بحيث جديد نوع ستعمل () طالما أن الطبقة التي مرت في لديها منشئ افتراضي. ومع ذلك، في سكالا، وأنواع وأنواع مختلفة من الكائنات.

هل كانت مفيدة؟

المحلول

وكما ذكرتم، C ++ ديه القوالب. باختصار، C ++ يقول "هناك تجارب لجميع أنواع T بحيث اختبار يجمع". وهذا يجعل من السهل إضافة ضمنا القيود على T، ولكن على الجانب السلبي انهم الضمني وقد يكون من الصعب للمستخدم من صفك لفهم دون قراءة التعليمات البرمجية.

وتعدد الأشكال سكالا حدودي (ويعرف أيضا باسم الوراثة) عمل أكثر من ذلك بكثير مثل ML، هاسكل، جافا، وC #. في سكالا، عند كتابة "فئة اختبار [T]" أنت تقول "لجميع T هناك وجود نوع الاختبار [T]" بدون قيود. هذا هو أبسط لسبب حول رسميا، لكنه يعني أن عليك أن تكون واضحة حول القيود. على سبيل المثال، في سكالا يمكنك أن تقول "فئة اختبار [T <: فو]" إلى القول بأن T يجب أن يكون نوع فرعي من فو.

وC # لديه وسيلة لإضافة القيد إلى T بشأن الصانعين، ولكن للأسف لا سكالا.

وهناك عدة طرق لحل مشكلتك في سكالا. واحد هو typesafe لكن مواطنه أكثر مطول. الآخر لم typesafe.

والطريقة typesafe يشبه

class Test[T](implicit val factory : () => T) {
  val testVal = factory
}

وبعد ذلك يمكن أن يكون مجموعة من المصانع لأنواع مفيدة في النظام الخاص بك

object Factories {
  implicit def listfact[X]() = List[X]()
  implicit def setfact[X]() = Set[X]()
  // etc
}

import Factories._
val t = new Test[Set[String]]

إذا مستخدمي المكتبة تحتاج المصانع الخاصة بها ثم يمكنهم إضافة ما يعادل الخاصة بهم من كائن المصانع. ميزة واحدة لهذا الحل هو أن أي شيء مع مصنع يمكن استخدامها، سواء كان أو لم يكن هناك من منشئ عدم وسيطة.

والطريقة ليست بهذه typesafe يستخدم التفكير وميزة في سكالا دعا كشوف التي هي وسيلة للالتفاف على القيود جافا بشأن نوع محو

 class Test[T](implicit m : Manifest[T]) {
   val testVal = m.erasure.newInstance().asInstanceOf[T]
 }

ومع هذا الإصدار الذي لا يزال كتابة

class Foo
val t = new Test[Foo]

ولكن، اذا لم يكن هناك عدم ARG منشئ متاح تحصل على استثناء وقت التشغيل بدلا من خطأ ثابت نوع

scala> new Test[Set[String]] 
java.lang.InstantiationException: scala.collection.immutable.Set
at java.lang.Class.newInstance0(Class.java:340)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top