Кіріспе

Бағдарламалау тілінің түсінігі

Көптеген бағдарламалау тілдерінің типтік жүйелері субтиптеуді қолдайды. Мысалы, егер тип – түрінің субтипі болса, онда түрінің өрнегі түрінің өрнегі қолданылатын кез келген жерде алмастырылуы тиіс. Варианс – күрделі типтер арасындағы субтиптеу олардың құрауыштары арасындағы субтиптеумен қалай байланысты екенін көрсетеді. Мысалы, s тізімі s тізімімен қалай байланысуы керек? Немесе қайтарым типі – түріндегі функция, қайтарым типі – түріндегі функциямен қалай байланысуы керек? Тип конструкторының вариантына байланысты, қарапайым типтердің субтиптеу қатынасы күрделі типтер үшін сақталуы, кері айналуы немесе ескерілмеуі мүмкін. Мысалы, OCaml бағдарламалау тілінде "Мысық тізімі" "Жануар тізімі" түрінің кіші түрі болып табылады, себебі тізім түрінің конструкторы ковариантты. Бұл қарапайым типтердің субтиптеу қатынасы күрделі типтер үшін сақталады дегенді білдіреді. Екінші жағынан, "Жануардан Стрингке функция" "Мысықтан Стрингке функция" түрінің кіші түрі болып табылады, себебі функция түрінің конструкторы параметр түрі бойынша контравариантты. Мұнда қарапайым типтердің субтиптеу қатынасы күрделі типтер үшін кері айналады. Бағдарламалау тілін жасаушы массивтер, мұрагерлік және жалпы дерек типтері сияқты тіл мүмкіндіктері үшін типтеу ережелерін жасау кезінде вариансты ескереді. Типтік конструкторларды инвариант емес, ковариант немесе контравариант ету арқылы, дұрыс типтелген бағдарламалардың саны артады. Екінші жағынан, бағдарламашылар контравариансты көбінесе түсініксіз деп санайды, ал орындалу кезінде типтік қателерге жол бермеу үшін варианстың дұрыс қадағалануы күрделі типтеу ережелеріне әкелуі мүмкін. Типтік жүйені қарапайым ұстау және пайдалы бағдарламаларға рұқсат беру үшін, тіл типтік конструкторды, оны вариантты деп қарастыру қауіпсіз болса да, инвариант ретінде қарастыруы мүмкін, немесе бұл типтік қауіпсіздікті бұзуы мүмкін болса да, оны ковариант ретінде қарастыруы мүмкін.

Варианс пен мұрагерліктің қысқаша сипаттамасы

Келесі кесте жоғарыда талқыланған тілдерде әдістерді қайта жазу ережелерін жинақтайды. Параметр түрі Қайтару түрі C++ (1998 жылдан бері), Java (J2SE 5.0-ден бері), D, C# (C# 9-дан бері) Тұрақты Ковариант C# (C# 9-дан бұрын) Тұрақты Тұрақты Scala, Sather Контравариант Ковариант Eiffel Ковариант Ковариант

Жалпы типтері

Жалпыламаларды қолдайтын бағдарламалау тілдерінде (әлде параметрлік полиморфизм деп те аталады), бағдарламашы типтік жүйені жаңа конструкторлармен кеңейте алады. Мысалы, C# интерфейсі сияқты жаңа типтерді құруға мүмкіндік береді, мысалы немесе . Содан кейін осы типтік конструкторлардың дисперсиясы қандай болуы керек деген сұрақ туындайды. Екі негізгі тәсіл бар. Декларация орнында дисперсияны көрсету мүмкіндігі бар тілдерде (мысалы, C#), бағдарламашы жалпы типтің анықтамасын оның типтік параметрлерінің күтілетін дисперсиясымен бірге көрсетеді. Пайдалану орнында дисперсияны көрсету мүмкіндігі бар тілдерде (мысалы, Java), бағдарламашы жалпы типті инстанцияланған жерлерді көрсетеді.

Декларация-сайты бойынша ауытқулар туралы түсініктемелер

Декларация орнындағы вариациялық белгілемелермен ең көп қолданылатын тілдер – C# және Kotlin ( және кілт сөздерін пайдаланып), Scala және OCaml ( және кілт сөздерін пайдаланып). C# тек интерфейс түрлері үшін ғана вариациялық белгілемелерге рұқсат береді, ал Kotlin, Scala және OCaml оларды интерфейс түрлері мен нақты дерек түрлері үшін де қолдануға мүмкіндік береді.

Этимология

Бұл терминдер категориялар теориясындағы ковариантты және контравариантты функторлар ұғымынан туындайды. Объектілері типтер, ал морфизмдері ≤ кіші тип қатынасын көрсететін санатты қарастырайық. (Бұл кез келген ішінара реттелген жиынның категория ретінде қарастырылуының мысалы.) Содан кейін, мысалы, функция түрінің конструкторы екі типті – p және r – қабылдап, жаңа p → r типін жасайды; демек, ол нысандарды нысандарға түрлендіреді. Функция типтері үшін кіші типтеу ережесіне сәйкес, бұл операция бірінші параметр үшін ≤ белгісін керітеді, ал екіншісі үшін сақтайды, сондықтан ол бірінші параметрде контравариантты функтор, ал екіншісінде ковариантты функтор болып табылады.