Структурна система типів (або система типів, заснована на властивостях) — це один із головних класів систем типів, у якому сумісність і еквівалентність типів визначаються фактичною структурою або визначенням типу, а не іншими характеристиками, такими як ім'я або місце оголошення. Структурні системи використовуються для визначення, чи є типи еквівалентними і чи є один тип підтипом іншого. Це контрастує з , де порівняння базуються на назвах типів або явних оголошеннях, і типізацією качки, в якій перевіряється лише та частина структури, що використовується під час виконання для сумісності.
Опис
У структурній типізації елемент вважається сумісним з іншим, якщо для кожної характеристики у типі другого елемента існує відповідна ідентична характеристика у типі першого елемента. Деякі мови можуть відрізнятися деталями, наприклад, чи повинні характеристики збігатися за назвою. Це визначення не є симетричним і включає сумісність підтипів. Два типи вважаються ідентичними, якщо кожен з них сумісний з іншим.
Наприклад, OCaml використовує структурну типізацію методів для сумісності типів об'єктів. Go використовує структурну типізацію методів для визначення сумісності типу з інтерфейсом. Функції демонструють структурну типізацію для аргументів типу. Haxe використовує структурну типізацію, але класи не мають структурного підтипування.
У мовах, що підтримують , може бути сформована подібна дихотомія, заснована на тому, як визначається відношення підтипу. Один тип є підтипом іншого, якщо і лише якщо він містить усі характеристики базового типу або їх підтипи. Підтип може містити додаткові характеристики, такі як члени, яких немає в базовому типі, або сильніші інваріанти.
Існує відмінність між структурною заміною для поліморфізму з виведенням типів і без нього. Деякі мови, такі як Haskell, не замінюють структуру у випадку, коли очікуваний тип оголошено (тобто не виведений), наприклад, заміна виконується лише для функцій, які є поліморфними на основі сигнатури через виведення типів. Таким чином, неможливо випадково зробити підтип для типу, що не виводиться, хоча може залишитися можливість забезпечити явне перетворення до невиведеного типу, яке викликається неявно.
Структурне підтипування вважається більш гнучким, ніж , оскільки воно дозволяє створювати ad hoc типи та інтерфейси; зокрема, воно дозволяє створювати тип, що є супертипом існуючого типу, без модифікації визначення останнього. Однак це може бути небажаним, коли програміст хоче створити закриті абстракції.
Недолік структурної типізації порівняно з номінативною полягає в тому, що два окремо визначені типи, призначені для різних цілей, але випадково мають однакові властивості (наприклад, обидва складаються з пари цілих чисел), можуть вважатися однаковими типами системою типів лише тому, що вони мають ідентичну структуру. Один зі способів уникнути цього — створювати окремий алгебраїчний тип даних для кожного випадку використання.
У 1990 році Кук та інші довели, що успадкування не є підтипуванням у мовах з об'єктно-орієнтованою структурною типізацією.
Перевірка сумісності двох типів на основі структурної типізації є нетривіальною операцією, наприклад, вимагає підтримки стека раніше перевірених типів.
Приклад
Об'єкти в OCaml мають структурну типізацію за іменами та типами їхніх методів.
Об'єкти можуть бути створені безпосередньо (негайні об'єкти) без необхідності проходження через номінативний клас. Класи слугують лише функціями для створення об'єктів.
# let x = object val mutable x = 5 method get_x = x method set_x y = x <- y end;; val x : < get_x : int; set_x : int -> unit > = <obj>
Тут інтерактивне середовище виконання OCaml виводить тип об'єкта для зручності. Його тип (< get_x : int; set_x : int -> unit >
) визначається лише його методами. Іншими словами, тип x визначається типами методів "get_x : int" і "set_x : int -> unit", а не за якимось ім'ям.
Для визначення іншого об'єкта, який має ті ж методи і типи методів:
# let y = object method get_x = 2 method set_x y = Printf.printf "%d\n" y end;; val y : < get_x : int; set_x : int -> unit > = <obj>
OCaml вважає їх одним і тим самим типом. Наприклад, оператор рівності типізований так, щоб приймати лише два значення одного і того ж типу:
# x = y;; - : bool = false
Отже, вони повинні бути одного типу, інакше це навіть не пройшло б перевірку типів. Це показує, що еквівалентність типів є структурною.
Можна визначити функцію, яка викликає метод:
# let set_to_10 a = a#set_x 10;; val set_to_10 : < set_x : int -> 'a; .. > -> 'a = <fun>
Виведений тип для першого аргументу (< set_x : int -> 'a; .. >
) цікавий. ..
означає, що перший аргумент може бути будь-яким об'єктом, який має метод "set_x", що приймає ціле число як аргумент.
Отже, його можна використовувати на об'єкті x
:
# set_to_10 x;; - : unit = ()
Можна створити інший об'єкт, який має такий самий метод і тип методу; інші методи не мають значення:
# let z = object method blahblah = 2.5 method set_x y = Printf.printf "%d\n" y end;; val z : < blahblah : float; set_x : int -> unit > = <obj>
Функція "set_to_10" також працює для нього:
# set_to_10 z;; 10 - : unit = ()
Це показує, що сумісність для викликів методів визначається структурою.
Визначимо синонім типу для об'єктів, що мають лише метод "get_x" і не мають інших методів:
# type simpler_obj = < get_x : int >;; type simpler_obj = < get_x : int >
Об'єкт x
не є цього типу; але структурно x
є підтипом цього типу, оскільки x
містить надмножину його методів. Тому x
можна привести до цього типу:
# (x :> simpler_obj);; - : simpler_obj = <obj> # (x :> simpler_obj)#get_x;; - : int = 10
Але об'єкт z
ні, оскільки він не є структурним підтипом:
# (z :> simpler_obj);; Цей вираз не можна привести до типу simpler_obj = < get_x : int >; його тип < blahblah : float; set_x : int -> unit >, але він використовується з типом < get_x : int; .. > У першого типу об'єкта немає методу get_x
Це показує, що сумісність для розширювальних приведень є структурною.
Примітки
- Signature-based polymorphism.
- Кук, В.Р.; Гілл, В.Л.; Кеннінг, П.С. (Січень 1990). Inheritance is not subtyping. Proceedings of the 17th ACM SIGPLAN-SIGACT symposium on Principles of programming languages - POPL '90. Сан-Франциско, Каліфорнія. с. 125—135. doi:10.1145/96709.96721. ISBN . S2CID 8225906.
- Type compatibility: name vs structural equivalence.
- Object types.
- Pierce, Benjamin C. (2002). 19.3. . MIT Press. ISBN .
Зовнішні посилання
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Nemaye perevirenih versij ciyeyi storinki jmovirno yiyi she ne pereviryali na vidpovidnist pravilam proektu Strukturna sistema tipiv abo sistema tipiv zasnovana na vlastivostyah ce odin iz golovnih klasiv sistem tipiv u yakomu sumisnist i ekvivalentnist tipiv viznachayutsya faktichnoyu strukturoyu abo viznachennyam tipu a ne inshimi harakteristikami takimi yak im ya abo misce ogoloshennya Strukturni sistemi vikoristovuyutsya dlya viznachennya chi ye tipi ekvivalentnimi i chi ye odin tip pidtipom inshogo Ce kontrastuye z de porivnyannya bazuyutsya na nazvah tipiv abo yavnih ogoloshennyah i tipizaciyeyu kachki v yakij pereviryayetsya lishe ta chastina strukturi sho vikoristovuyetsya pid chas vikonannya dlya sumisnosti OpisU strukturnij tipizaciyi element vvazhayetsya sumisnim z inshim yaksho dlya kozhnoyi harakteristiki u tipi drugogo elementa isnuye vidpovidna identichna harakteristika u tipi pershogo elementa Deyaki movi mozhut vidriznyatisya detalyami napriklad chi povinni harakteristiki zbigatisya za nazvoyu Ce viznachennya ne ye simetrichnim i vklyuchaye sumisnist pidtipiv Dva tipi vvazhayutsya identichnimi yaksho kozhen z nih sumisnij z inshim Napriklad OCaml vikoristovuye strukturnu tipizaciyu metodiv dlya sumisnosti tipiv ob yektiv Go vikoristovuye strukturnu tipizaciyu metodiv dlya viznachennya sumisnosti tipu z interfejsom Funkciyi shabloniv u C demonstruyut strukturnu tipizaciyu dlya argumentiv tipu Haxe vikoristovuye strukturnu tipizaciyu ale klasi ne mayut strukturnogo pidtipuvannya U movah sho pidtrimuyut mozhe buti sformovana podibna dihotomiya zasnovana na tomu yak viznachayetsya vidnoshennya pidtipu Odin tip ye pidtipom inshogo yaksho i lishe yaksho vin mistit usi harakteristiki bazovogo tipu abo yih pidtipi Pidtip mozhe mistiti dodatkovi harakteristiki taki yak chleni yakih nemaye v bazovomu tipi abo silnishi invarianti Isnuye vidminnist mizh strukturnoyu zaminoyu dlya polimorfizmu z vivedennyam tipiv i bez nogo Deyaki movi taki yak Haskell ne zaminyuyut strukturu u vipadku koli ochikuvanij tip ogolosheno tobto ne vivedenij napriklad zamina vikonuyetsya lishe dlya funkcij yaki ye polimorfnimi na osnovi signaturi cherez vivedennya tipiv Takim chinom nemozhlivo vipadkovo zrobiti pidtip dlya tipu sho ne vivoditsya hocha mozhe zalishitisya mozhlivist zabezpechiti yavne peretvorennya do nevivedenogo tipu yake viklikayetsya neyavno Strukturne pidtipuvannya vvazhayetsya bilsh gnuchkim nizh oskilki vono dozvolyaye stvoryuvati ad hoc tipi ta interfejsi zokrema vono dozvolyaye stvoryuvati tip sho ye supertipom isnuyuchogo tipu bez modifikaciyi viznachennya ostannogo Odnak ce mozhe buti nebazhanim koli programist hoche stvoriti zakriti abstrakciyi Nedolik strukturnoyi tipizaciyi porivnyano z nominativnoyu polyagaye v tomu sho dva okremo viznacheni tipi priznacheni dlya riznih cilej ale vipadkovo mayut odnakovi vlastivosti napriklad obidva skladayutsya z pari cilih chisel mozhut vvazhatisya odnakovimi tipami sistemoyu tipiv lishe tomu sho voni mayut identichnu strukturu Odin zi sposobiv uniknuti cogo stvoryuvati okremij algebrayichnij tip danih dlya kozhnogo vipadku vikoristannya U 1990 roci Kuk ta inshi doveli sho uspadkuvannya ne ye pidtipuvannyam u movah z ob yektno oriyentovanoyu strukturnoyu tipizaciyeyu Perevirka sumisnosti dvoh tipiv na osnovi strukturnoyi tipizaciyi ye netrivialnoyu operaciyeyu napriklad vimagaye pidtrimki steka ranishe perevirenih tipiv PrikladOb yekti v OCaml mayut strukturnu tipizaciyu za imenami ta tipami yihnih metodiv Ob yekti mozhut buti stvoreni bezposeredno negajni ob yekti bez neobhidnosti prohodzhennya cherez nominativnij klas Klasi sluguyut lishe funkciyami dlya stvorennya ob yektiv let x object val mutable x 5 method get x x method set x y x lt y end val x lt get x int set x int gt unit gt lt obj gt Tut interaktivne seredovishe vikonannya OCaml vivodit tip ob yekta dlya zruchnosti Jogo tip lt get x int set x int gt unit gt viznachayetsya lishe jogo metodami Inshimi slovami tip x viznachayetsya tipami metodiv get x int i set x int gt unit a ne za yakimos im yam Dlya viznachennya inshogo ob yekta yakij maye ti zh metodi i tipi metodiv let y object method get x 2 method set x y Printf printf d n y end val y lt get x int set x int gt unit gt lt obj gt OCaml vvazhaye yih odnim i tim samim tipom Napriklad operator rivnosti tipizovanij tak shob prijmati lishe dva znachennya odnogo i togo zh tipu x y bool false Otzhe voni povinni buti odnogo tipu inakshe ce navit ne projshlo b perevirku tipiv Ce pokazuye sho ekvivalentnist tipiv ye strukturnoyu Mozhna viznachiti funkciyu yaka viklikaye metod let set to 10 a a set x 10 val set to 10 lt set x int gt a gt gt a lt fun gt Vivedenij tip dlya pershogo argumentu lt set x int gt a gt cikavij oznachaye sho pershij argument mozhe buti bud yakim ob yektom yakij maye metod set x sho prijmaye cile chislo yak argument Otzhe jogo mozhna vikoristovuvati na ob yekti x set to 10 x unit Mozhna stvoriti inshij ob yekt yakij maye takij samij metod i tip metodu inshi metodi ne mayut znachennya let z object method blahblah 2 5 method set x y Printf printf d n y end val z lt blahblah float set x int gt unit gt lt obj gt Funkciya set to 10 takozh pracyuye dlya nogo set to 10 z 10 unit Ce pokazuye sho sumisnist dlya viklikiv metodiv viznachayetsya strukturoyu Viznachimo sinonim tipu dlya ob yektiv sho mayut lishe metod get x i ne mayut inshih metodiv type simpler obj lt get x int gt type simpler obj lt get x int gt Ob yekt x ne ye cogo tipu ale strukturno x ye pidtipom cogo tipu oskilki x mistit nadmnozhinu jogo metodiv Tomu x mozhna privesti do cogo tipu x gt simpler obj simpler obj lt obj gt x gt simpler obj get x int 10 Ale ob yekt z ni oskilki vin ne ye strukturnim pidtipom z gt simpler obj Cej viraz ne mozhna privesti do tipu simpler obj lt get x int gt jogo tip lt blahblah float set x int gt unit gt ale vin vikoristovuyetsya z tipom lt get x int gt U pershogo tipu ob yekta nemaye metodu get x Ce pokazuye sho sumisnist dlya rozshiryuvalnih priveden ye strukturnoyu PrimitkiSignature based polymorphism Kuk V R Gill V L Kenning P S Sichen 1990 Inheritance is not subtyping Proceedings of the 17th ACM SIGPLAN SIGACT symposium on Principles of programming languages POPL 90 San Francisko Kaliforniya s 125 135 doi 10 1145 96709 96721 ISBN 978 0897913430 S2CID 8225906 Type compatibility name vs structural equivalence Object types Pierce Benjamin C 2002 19 3 MIT Press ISBN 978 0 262 16209 8 Zovnishni posilannyaNominativeAndStructuralTyping na WikiWikiWeb