Vienos motinos ir dviejų sūnų istorija: vertės tipas palyginti su „Swift“ tipu

„Swift“ yra motina ir ji turi du sūnus.

  • Vertės tipas
  • Nuorodos tipas

Bet kokios jų savybės?

Ar jie elgiasi vienodai ar priešingai vienas kitam?

„Swift“ yra daugiaparadiminė programavimo kalba, kurią sukūrė „Apple“ „iOS“, „MacOS“, „watchOS“, „tvOS“, „Linux“ ir „z / OS“ .

Kaip ir kitos į objektą orientuotos programavimo kalbos, „Swift“ turi klases kaip sudedamąsias dalis, kurios gali apibrėžti metodus, savybes, iniciatorius ir atitikti protokolus, palaikyti paveldėjimą ir polimorfizmą.

Bet palauk palauk palauk…

„Swift“ taip pat turi konstrukcijas, kurios gali apibrėžti metodus, savybes, iniciatorius ir gali atitikti protokolus tik su viena paveldėjimo išimtimi.

Ką? Dabar aš sumišęs !!!

Dabar paįvairinkime jūsų painiavą: „Swift“ struktūros yra ne tik vertybių rūšys. „Tuples“ ir „Enums“ taip pat yra vertės tipai. Klasės taip pat nėra vienintelės, naudojamos kaip atskaitos tipas. Funkcijos ir uždarymai taip pat yra etaloniniai tipai. Tačiau kaip palengvėjimo ženklą mes bent jau žinome, koks yra šių tipų naudojimo pagrindinis dėmesys ir specializacija.

Taigi iki šiol mums liko tik viena didžiulė painiava dėl konstrukcijų ir klasių naudojimo.

Taigi, paleiskime ir pašalinkime painiavą.

Sandėliavimo vietos

Yra trys saugyklų tipai:

  • Registruotis
  • Kamino
  • Krūva

Objektai, kurių eksploatavimo trukmė trumpesnė, yra kaupiami registruose arba krūve, o tie, kurių eksploatavimo laikas ilgesnis, kaupiami krūvos viduje.

Vertės tipas savo turinį saugo krūvoje skirtoje atmintyje, todėl galime pasakyti, kad vertės tipai yra skiriami krūvoje „Swift“.

Tačiau yra paplitęs klaidingas požiūris į vertybių rūšis, ar girdėjote?

Klaidinga nuomonė yra ta, kad dauguma žmonių mano, kad vertybių rūšys visada saugomos krūvoje.

Palaukite minutę - ne visada taip yra.

Vertių tipai gali būti saugomi krūvoje, kai jie yra laikini arba vietiniai kintamieji. O kas, jei vertės tipą sudaro atskaitos tipas?

Esant tokiai situacijai, ją galima laikyti krūvos atmintyje.

Oho ... tai šaunu !!!

Taigi vertės tipus galima laikyti registre, krūve ar krūvoje priklausomai nuo jų gyvenimo trukmės, nesvarbu, ar jie trumpalaikiai, ar ilgaamžiai. Jei tai yra vietinis kintamasis, jis gali gyventi krūvoje, o jei tai yra klasės dalis, tada jis gali gyventi ir krūvos atmintyje. inside

Kita vertus, nuorodos tipas savo turinį kaupia atmintyje, paskirstytoje krūvos atmintyje, o kintamasis turi tik nuorodą į tą atminties vietą, kurioje buvo saugomi faktiniai duomenys.

Kaip tai veikia atskaitos tipui?

Taigi etaloninio tipo atveju gana dažna situacija, kai gali būti keli kintamieji, laikantys nuorodą į tą pačią atminties vietą.

Kai vertės tipo egzempliorius priskiriamas kintamajam arba perduodamas funkcijai, egzempliorius nukopijuojamas ir priskiriamas tam kintamajam. Tačiau naudojant nuorodos tipą, tik nuoroda nukopijuojama, o naujasis kintamasis turi tą pačią nuorodą į tą pačią atminties vietą.

Keičiamumo skirtumai

Kintamajam gali būti dvi būsenos:

  • ‍♀ ️Mutavusis ‍♀
  • Nekeičiamas

Jei vertės tipo egzempliorius priskiriamas nekintamam kintamajam, tada egzempliorius taip pat tampa nekintamas. Dėl to mes negalime atlikti jokių pakeitimų toje instancijoje.

Jei vertės tipo egzempliorius priskiriamas keičiamajam kintamajam, tada tik jis daro egzempliorių keičiamą.

Tačiau referencinių tipų atveju viskas yra visiškai kitaip. Kintamasis ir instancija, kuriai jis priskirtas, yra visiškai skirtingi. Jei deklaruojame nekintantį kintamąjį, turintį nuorodą į klasę, tai reiškia, kad jo turima nuoroda niekada nepasikeis. Negalime pakeisti nuorodos ir ji visada nurodys tą pačią nuorodą.

Konstrukcijų tipai

Lyginami struktūrinių tipų vertės, atsižvelgiant į jų požymių ar elementų lygybę. Galime pasakyti, kad vertės tipas yra lygus kitam, jei ir tik tada, jei visi atitinkami požymiai yra lygūs.

Umm ... per daug stiprių žodžių ... ką turi omenyje ??

Tarkime, turime „Person“ vertės tipą, kuriam būdingi atributai, pvz., Vardas ir pavardė.

struct Asmuo {
   var firstName: eilutė
   var pavardė: eilutė
}
var person1 = Asmuo (vardasPavadinimas: „foo“, pavardė: „bar“)
var person2 = Asmuo (vardasPavadinimas: „foo“, pavardė: „bar“)

Čia tiek asmens1, tiek asmens2 egzemplioriai turi tą pačią reikšmę „firstName“ („foo“) ir „lastName“ („bar“). Taigi, kaip suprantame, galime pasakyti, kad abu egzemplioriai yra lygūs vienas kitam, nes jų atributai (vardas ir pavardė) turi tas pačias reikšmes.

Tačiau tai neapsiriboja tuo: ateityje visi du egzemplioriai, turintys tas pačias vardo ir pavardės reikšmes, bus lygūs vienas kitam.

Taigi, atsižvelgiant į mūsų supratimą iki šios dienos, mes galime pasakyti:

Vertių tipai neturi tapatybės, todėl negali būti jokių nuorodų į juos. Vertybių tipai yra beveidžiai.

Ką? Kaip tu gali tai pasakyti?

var myAge: Int = 21
var friendAge: Int = 21

Ir „myAge“, ir „friendAge“ yra sveikų skaičių kintamieji, kurių vertė 21.

Ar galime atskirti vienas nuo kito? 🥺

Ne, nes jie turi tą pačią vertę.

Sveikasis kintamasis, kurio vertė 21, negali skirtis nuo kito sveikojo kintamojo, kurio vertė taip pat yra 21. Taip paprasta

Tapatybės neturėjimas suteikia vertės tipams dar vieną pranašumą: jei praktiškai mąstote, tada galite įsivaizduoti, jei neturite tapatybės, tada jus pakeisti ar pakeisti gali bet kuris asmuo, turintis tokias pačias savybes.

Tą patį galime galvoti ir apie mus, kaip apie žmones. Jei neturiu tapatybės, mane gali pakeisti bet kuris asmuo, turintis tas pačias savybes. Mums gerai, kad turime tapatybę, kitaip tai galėtų sukelti didelę riziką mūsų egzistavimui.

Tačiau vertybių tipai neturi tapatybės ir tai yra jų pranašumas.

Kokie yra vertės tipų naudojimo pranašumai?

Nėra lenktynių sąlygų ir aklaviečių:

Jei reikšmių tipai yra daugiapakopėje aplinkoje, neįmanoma, kad viena gija mutuotų egzemplioriaus būseną, kol ją naudoja kita gija. Taigi galime pasakyti, kad nebus lenktynių sąlygų ar aklavietės.

Neatlieka ciklų:

Kai yra du referencinio tipo egzemplioriai, turintys tvirtas nuorodas vienas į kitą ir neleidžiantys vienas kitam išsiskirti iš atminties, jis vadinamas išlaikymo ciklu. Kadangi vertės tipai neveikia kaip nuorodos, todėl galime pasakyti, kad vertės tipams nebus išlaikymo ciklų.

Automatinis atskaitos skaičiavimas:

Nurodymo tipui „Swift“ naudoja automatinį nuorodų skaičiavimą, kad galėtų sekti visus gyvus ar aktyvius objektus, ir nagrinėja egzempliorių tik tada, kai nėra daugiau stiprių nuorodų į jį. Jei šiek tiek pagalvokime, tada galime pasakyti, kad tai yra sunki operacija, nes „Swift runtime“ visada turi sekti objektus. Bet kadangi vertės tipai yra paskirstomi krūvoje, jam nereikia ARC. Taigi pigiau ir greičiau.

Bet palaukite ... Kaip ji tvarko masyvo, žodyno ir styginių atmintį?

Kadangi negalime žinoti, koks bus tikrasis masyvo, žodyno ir eilutės dydis kompiliavimo metu, jų paskirstymo kompiliavimo metu nėra galimybių. Nors jie yra vertės tipai viduje, jų negalima paskirstyti krūvoje. Juos reikia paskirstyti krūvos atmintyje, o norint tai valdyti, „Swift“ sugalvoja kopiją rašyti.

Bet kas tai?

Kai sakome, kad viena instancija yra kitos egzemplioriaus kopija, tai iš tikrųjų reiškia, kad jie yra tie patys, kad juose yra tos pačios vertės. Tačiau „Swift“ šių aukščiau išvardytų tipų (masyvas, žodynas, eilutė ir tt) faktinė kopija buvo padaryta krūvoje tik tada, kai egzistuoja mutacija. Tai vadinama vertės tipų našumo optimizavimo technika.

Išvada

Nėra griežtos taisyklės, apibrėžiančios, kada naudoti vertės tipą, o kada naudoti atskaitos tipą. Vertių tipai turi keletą unikalių pranašumų, palyginti su etaloniniais tipais, ir atvirkščiai. Jie abu yra savaip unikalūs. Tai tikrai priklauso nuo jūsų poreikių ir to, ką bandote pasiekti. Turėtumėte žinoti savo kodo semantiką, nes geriausiai žinote tik savo kodą, todėl jūs turite pasirinkti. Jūs turite visišką laisvę.

Taigi, užuot kovoję su vertės tipu ir palyginimo tipu, naudokitės jais protingai.

Sveiki !!! Ačiū, kad skaitėte!!

Galite mane rasti „Twitter“ .