mikä on sulkeminen?
sulkemisella tarkoitetaan funktionaalisen koodin lohkoa, jonka muuttujat ovat sidoksissa ympäristöön, johon sulkemista kutsutaan.
sululla on muutamia tärkeitä ominaisuuksia:
- se voidaan kiertää kuin objekti (mutta se ei välttämättä tarkoita, että se on objekti, kuten jäljempänä käsitellään),
- sulkemissuunnitelma voidaan määritellä yhdessä ulottuvuudessa ja sitä voidaan kutsua täysin eri laajuudessa,
- se muistaa laajuudessaan olevat muuttujat luomishetkellä; kun sitä kutsutaan, se voi käyttää näitä muuttujia, vaikka ne eivät ehkä ole nykyisen soveltamisalan—mikä tarkoittaa, että sulkeminen säilyttää tietoa sen leksikaalisen ympäristön aikaan, että se määriteltiin.
lohkot
lohkot ovat rubiinissa yksinkertainen sulkemismuoto. Toisin kuin periaatteessa kaikki muu Rubyssa, palikat eivät ole esineitä.
lohkot on rakennettu siten, että do...end
tai {}
.
palikoiden pitäisi olla tuttuja jo iteraattoreiden ja luetteloijien työskentelystä.
tässä kaksi tuttua esimerkkiä palikoista:
.each
luettelointimenetelmä hyväksyy argumentiksi lohkon ja kutsuu annettua lohkoa kerran kutakin kokoelman alkiota kohti.
array.each do |x| puts xend#orarray.each { |x| puts x }
olet saattanut havaita tämän Rspecetestissä; before(:each)
– menetelmälle on annettu lohko, johon se saa tuotoksen kussakin kokeessa samassa yhteydessä.
before(:each) do @language = "Ruby"end
Procs
Procs on rubiinissa esiintyvä sulkutyyppi, joka käyttäytyy hyvin samalla tavalla kuin lohkot, mutta jolla on muutamia keskeisiä eroja:
- paikalliselle muuttujalle voidaan antaa proc,
- proc-instanssi suoritetaan kutsumalla
call
– menetelmä sille ja - useampikin proc voidaan siirtää menetelmälle.
mutta pohjimmiltaan proc on lohko, joka on muutettu objektiksi siten, että se on annettu jollekin proc-luokan instanssille.
näin ollen proc: n luominen näyttää hyvin samanlaiselta kuin luokan instantiaatio.
tässä annetaan lohko proc-luokan instanssille ja se annetaan muuttujalle. Sitten kutsutaan menetelmää .call
sillä:
greeting = Proc.new { "Hello!" }greeting.call=> "Hello!"
Procs voi hyväksyä myös argumentteja, jotka siirtyvät .call
– menetelmään:
greeting = Proc.new { |name| "Hello, #{name}!" }greeting.call("Amanda")=> "Hello, Amanda!"
Lambdas
lambda ei ole kovin paljon erilainen kuin proc toiminnallisuudeltaan.
tässä on Lambda, joka siirretään luetteloijalle jokaiseen. &
ennen kuin se muuttaa sen lohkoksi, jota kukin odottaa argumenttina.
plus_one = lambda { |n| puts n + 1 }array = array.each(&plus_one)=> 2=> 3=> 4
lambda voidaan julistaa myös tällä hauskalla tavalla:
plus_one = ->(n) { puts n + 1 }
Lambdas ja procs käytetään lähes keskenään, mutta on olemassa muutamia eroja kahden:
- lambdat odottavat tiettyä määrää argumentteja ja tarkistavat ne; procs vain palauttaa
nil
puuttuvan argumentin, mutta älä heitä virhettä - he palaavat eri tavalla: lambdat palaavat soittotapaan ja procs palaavat välittömästi palaamatta soittajaan—pohjimmiltaan lambdat käyttäytyvät enemmän metodipuheluiden tapaan: voit ajatella niitä anonyymeinä funktioina
loppuhuomautukset
jos tämä hämmentää erityisesti procsia ja lambdaa, älä huoli! Procs ja lambdas ovat mahtavia ja voit kirjoittaa mielenkiintoinen, tehokas koodi. Kuitenkin, päivä päivältä et työskennellä heidän kanssaan paljon. Lohkot, kuitenkin, voit vuorovaikutuksessa joka päivä. Keskity siihen, että tutustut heihin parhaiten.