Lua Academy · Oppitunti

Syvä ja pinnallinen kopio

Toteuttakaa rekursiivinen syväkopio ja perehtykää viitesemantiikkaan.

Oppitunti 3/413 vaihetta

Syvä ja pinnallinen kopio on ilmainen Lua Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Lua Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Lua Academy-kurssilla on yhteensä 4 oppituntia.

Viitesemantiikka Luassa

Luassa taulukon sijoittaminen toiseen muuttujaan kopioi viitteen, ei dataa. Molemmat muuttujat osoittavat samaan taulukkoon.

local a = {1, 2, 3}
local b = a
b[1] = 99
print(a[1])  -- 99, a is affected!

Pinnallinen kopio

Pinnallinen kopio luo uuden taulukon, jossa on samat ylimmän tason avaimet ja arvot. Sisäkkäiset taulukot ovat edelleen jaettuja.

local function shallowCopy(t)
  local copy = {}
  for k, v in pairs(t) do copy[k] = v end
  return copy
end

Pinnallisen kopion rajoitus

Sisäkkäisen taulukon muuttaminen pinnallisessa kopiossa vaikuttaa alkuperäiseen taulukkoon.

local orig = {data = {1, 2, 3}}
local sc = shallowCopy(orig)
sc.data[1] = 99
print(orig.data[1])  -- 99 (shared!)

Syvä kopio rekursion avulla

Syvä kopio monistaa rekursiivisesti jokaisen sisäkkäisen taulukon ja poistaa kaikki jaetut viitteet.

local function deepCopy(orig)
  local copy
  if type(orig) == "table" then
    copy = {}
    for k, v in pairs(orig) do
      copy[deepCopy(k)] = deepCopy(v)
    end
    setmetatable(copy, getmetatable(orig))
  else
    copy = orig
  end
  return copy
end

Syvä kopio käytännössä

Syvän kopion jälkeen kopion sisäkkäisten taulukoiden muuttaminen ei vaikuta alkuperäiseen.

local orig = {data = {1, 2, 3}}
local dc = deepCopy(orig)
dc.data[1] = 99
print(orig.data[1])  -- 1 (independent!)

Syklien käsittely

Yksinkertainen syvä kopiointi epäonnistuu syklisillä taulukoilla. Seuraa käsiteltyjä taulukoita muistiinpanotaulukossa, jotta syklit voidaan käsitellä.

local function deepCopyMemo(orig, memo)
  memo = memo or {}
  if type(orig) ~= "table" then return orig end
  if memo[orig] then return memo[orig] end
  local copy = {}
  memo[orig] = copy
  for k, v in pairs(orig) do
    copy[deepCopyMemo(k, memo)] = deepCopyMemo(v, memo)
  end
  setmetatable(copy, getmetatable(orig))
  return copy
end

Metataulukoiden kopiointi

Syvän kopion tulisi siirtää myös metataulukko komennolla setmetatable(copy, getmetatable(orig)), jotta olio-ohjelmoinnin toiminta säilyy.

Pinnallinen kopio table.move-funktiolla

Peräkkäisille taulukoille nopea pinnallinen klooni voidaan tehdä table.move-funktiolla.

local function arrayCopy(t)
  return table.move(t, 1, #t, 1, {})
end

Milloin kutakin käytetään

  • Pinnallinen: yksinkertaiset litteät taulukot ja suorituskykyä vaativa kloonaus.
  • Syvä: sisäkkäiset rakenteet, sarjallistaminen ja muuttumattomat tilannevedokset.

Funktioarvot

Funktioita ei koskaan kopioida — sekä pinnallinen että syvä kopio jakavat saman funktioviitteen. Tämä on yleensä toivottu toimintatapa.

Suorituskykynäkökohdat

Syvän kopion aikavaativuus on O(n) solmujen määrän suhteen. Erittäin suurissa puissa kannattaa harkita sen sijaan rakenteiden jakamista tai copy-on-write-malleja.

Kopiotyyppiä koskeva kysymys

Mitä tapahtuu, kun muutat kopion sisäkkäistä taulukkoa pinnallisen kopioinnin jälkeen?

Kertaus: syvä ja pinnallinen kopio

Pinnallinen kopio monistaa vain ylimmän tason avaimet; sisäkkäiset taulukot ovat jaettuja. Syvä kopio monistaa kaiken rekursiivisesti. Käsittele syklit muistiinpanotaulukon avulla, jotta rekursio ei jatku loputtomasti.

Aloita maksutta

Opi Lua tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
40
Oppitunnit
159

Usein kysytyt kysymykset

Onko oppitunti ”Syvä ja pinnallinen kopio” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Lua Academy-oppimispolun 3 oppituntia, myös oppitunnin “Syvä ja pinnallinen kopio”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Lua Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Syvä ja pinnallinen kopio”?

Toteuttakaa rekursiivinen syväkopio ja perehtykää viitesemantiikkaan. Harjoittelet Lua Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Lua Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Lua Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Syvä ja pinnallinen kopio”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Lua Academy-oppitunnilla?

Kyllä. Jokainen Lua Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. table.sort ja vertailufunktiot
  2. table.concat ja table.move
  3. Syvä ja pinnallinen kopio
  4. Taulukoiden muuntaminen: map, filter, reduce
← Takaisin: Lua Academy