متى تكون هناك حاجة إلى @uncheckedVariance في Scala، ولماذا يتم استخدامه في GenericTraversableTemplate؟

StackOverflow https://stackoverflow.com/questions/2454281

سؤال

@uncheckedVariance يمكن استخدامها لسد الفجوة بين التعليقات التوضيحية لتباين موقع إعلان Scala والأدوية العامة الثابتة في Java.

scala> import java.util.Comparator    
import java.util.Comparator

scala> trait Foo[T] extends Comparator[T]
defined trait Foo

scala> trait Foo[-T] extends Comparator[T]     
<console>:5: error: contravariant type T occurs in invariant position in type [-T]java.lang.Object with java.util.Comparator[T] of trait Foo
       trait Foo[-T] extends Comparator[T]
             ^

scala> import annotation.unchecked._    
import annotation.unchecked._

scala> trait Foo[-T] extends Comparator[T @uncheckedVariance]    
defined trait Foo

هذا يعني أن java.util.Comparator هو متغير عكسي بشكل طبيعي، وهذا هو معلمة النوع T يظهر في المعلمات ولا يظهر أبدًا في نوع الإرجاع.

وهذا يطرح السؤال:لماذا يتم استخدامه أيضًا في مكتبة مجموعات Scala التي لا تمتد من واجهات Java؟

trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance]

ما هي الاستخدامات الصحيحة لهذا الشرح؟

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

المحلول

تكمن المشكلة في استخدام GenericTraversableTemplate مرتين:مرة واحدة للمجموعات القابلة للتغيير (حيث يجب أن تكون معلمة النوع ثابتة)، ومرة ​​واحدة للمجموعات غير القابلة للتغيير (حيث يكون التباين هو الملك دائمًا).

تفترض عمليات التحقق من النوع GenericTraversableTemplate إما التباين المشترك أو الثبات لمعلمة النوع A.ومع ذلك، عندما نرثها في سمة قابلة للتغيير، علينا أن نختار الثبات.على العكس من ذلك، نود التغاير في فئة فرعية غير قابلة للتغيير.

نظرًا لأننا لا نستطيع تلخيص التعليق التوضيحي للتباين (حتى الآن ؛-)) في GenericTraversableTemplate، حتى نتمكن من إنشاء مثيل له لأي منهما اعتمادًا على الفئة الفرعية، يتعين علينا اللجوء إلى الإرسال (@uncheckVariance هو في الأساس نوع من النوع) .لمزيد من القراءة، أوصي بأطروحتي (آسف؛-)) أو أطروحتنا الأخيرة ورق البتروت

نصائح أخرى

في أطروحتي ، أصف حساب التفاضل والتكامل ، Scalina ، الذي يحتوي على تعليقات وشروط التباين كجزء من اللغة الرقيقة (إصدار سابق متاح أيضًا كملف ورقة ورشة). إن الأهمية على هذه المناقشة هي الخطوة التالية التي أريد أن أتخذها في تطوير هذا التفاضل والتكامل: قم ببناء طبقة أخرى على رأس ذلك حتى تتمكن من تجريد الحدود (السهلة) والتعليقات التوضيحية للتباين (يجعل رأسي يدور). في الواقع ، لن تقم فقط بتصوير طبقة إضافية على هناك ، بل تعميم بنيات الأشكال الخاصة بك بحيث تعمل على جميع المستويات ، وجعل "سماتك" (الحدود ، تعليقات التباين ، الحجج الضمنية المطلوبة ، ...) في أنواع عادية مع أنواع خاصة ، والتي تخضع جميعها للتجريد.

يتم شرح فكرة "السمات هي أنواع" بشكل جيد من قبل إدسكو دي فريس في سياق أنواع التفرد.

تفرد الكتابة مبسطة, ، Edsko de Vries ، Rinus plasmeijer ، وديفيد أبراهامسون. في Olaf Chitil و Zoltán Horváth و Viktória Zsók (Eds.): IFL 2007 ، LNCS 5083 ، pp. 201-218 ، 2008.

الخلاصة: نقدم نظامًا تفردًا أبسطًا من نظام التفرد في Clean والنظام الذي اقترحناه مسبقًا. نظام النوع الجديد واضح ومباشر للتنفيذ وإضافته إلى المجمعين الحاليين ، ويمكن تمديده بسهولة مع ميزات متقدمة مثل أنواع المرتبة العليا والتقييم. وصفنا تنفيذنا في مورو ، وهي لغة وظيفية تجريبية مع كلتا هذه الميزات. أخيرًا ، نثبت سلامة نظام النوع الأساسي فيما يتعلق بحساب Lambda Call-By-Baded.

لقد وجدت وقتًا آخر حيث يتم استخدام uncheckedVariance - الطريقة الاصطناعية التي تُرجع القيمة الافتراضية لمعلمة من النوع التجريدي:

M:\>scala -Xprint:typer -e "class C { def p[T >: Null](t: T = null) = t }"
[[syntax trees at end of typer]]// Scala source: (virtual file)
package <empty> {
  final object Main extends java.lang.Object with ScalaObject {
    def this(): object Main = {
      Main.super.this();
      ()
    };
    def main(argv: Array[String]): Unit = {
      val args: Array[String] = argv;
      {
        final class $anon extends scala.AnyRef {
          def this(): anonymous class $anon = {
            $anon.super.this();
            ()
          };
          class C extends java.lang.Object with ScalaObject {
            <synthetic> def p$default$1[T >: Null <: Any]: Null @scala.annotation.unchecked.uncheckedVariance = null;
            def this(): this.C = {
              C.super.this();
              ()
            };
            def p[T >: Null <: Any](t: T = null): T = t
          }
        };
        {
          new $anon();
          ()
        }
      }
    }
  }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top