Bevezetés a Clojure-ba

1. Bemutatkozás

A Clojure egy funkcionális programozási nyelv, amely teljes egészében a Java virtuális gépen fut, hasonló módon, mint a Scala és a Kotlin. A Clojure Lisp-származéknak tekinthető és mindenki számára ismerős lesz, aki tapasztalattal rendelkezik más Lisp nyelvekkel kapcsolatban.

Ez az oktatóanyag bemutatja a Clojure nyelvet, bemutatja, hogyan kell neki kezdeni, és néhány kulcsfontosságú fogalmat a működéséhez.

2. A Clojure telepítése

A Clojure telepítőként és kényelmi szkriptként érhető el, Linux és MacOS rendszereken történő használatra. Sajnos ebben a szakaszban a Windows nem rendelkezik ilyen telepítővel.

A Linux szkriptek azonban működhetnek olyanokban, mint a Cygwin vagy a Windows Bash. Van egy online szolgáltatás is, amely a nyelv tesztelésére használható, a régebbi verziók pedig önálló verzióval rendelkeznek.

2.1. Önálló letöltés

Az önálló JAR fájl letölthető a Maven Central oldalról. Sajnos az 1.8.0-nál újabb verziók már nem működnek így könnyen, mivel a JAR fájlt kisebb modulokra bontották.

Miután letöltötte ezt a JAR fájlt, interaktív REPL-ként használhatjuk, egyszerűen futtatható JAR-ként kezelve:

$ java -jar clojure-1.8.0.jar Clojure 1.8.0 felhasználó =>

2.2. Webes felület a REPL-hez

A Clojure REPL webes felülete a //repl.it/languages/clojure címen érhető el, hogy bármi letöltés nélkül próbálkozzunk. Jelenleg ez csak a Clojure 1.8.0-t támogatja, az újabb kiadásokat nem.

2.3. Telepítő MacOS rendszeren

Ha macOS-t használ, és telepítve van a Homebrew, akkor a Clojure legújabb kiadása egyszerűen telepíthető:

$ brew install clojure

Ez támogatni fogja a Clojure legújabb verzióját - 1.10.0 az íráskor. A telepítés után egyszerűen betölthetjük a REPL-t a clojure vagy clj parancsok:

$ clj Clojure 1.10.0 felhasználó =>

2.4. Telepítő Linuxra

Az eszközök Linuxra történő telepítéséhez egy önállóan telepítő shell szkript áll rendelkezésünkre:

$ curl -O //download.clojure.org/install/linux-install-1.10.0.411.sh $ chmod + x linux-install-1.10.0.411.sh $ sudo ./linux-install-1.10.0.411.sh

A macOS telepítőhöz hasonlóan ezek is elérhetők lesznek a Clojure legfrissebb kiadásaihoz, és a clojure vagy clj parancsokat.

3. Bevezetés a Clojure REPL-be

A fenti lehetőségek mindegyike hozzáférést biztosít a Clojure REPL-hez. Ez a JShell eszköz közvetlen Clojure megfelelője Java 9 és újabb verziókhoz, és lehetővé teszi számunkra, hogy beírjuk a Clojure kódot, és azonnal láthassuk az eredményt. Ez egy fantasztikus módszer a kísérletezésre és annak felfedezésére, hogy bizonyos nyelvi jellemzők hogyan működnek.

Miután betöltötte a REPL-t, kapunk egy utasítást, amelyen bármilyen szabványos Clojure kód beírható és azonnal végrehajtható. Ez magában foglalja az egyszerű Clojure-konstrukciókat, valamint a többi Java-könyvtárral való interakciót - bár a betöltéshez rendelkezésre kell állniuk az osztályúton.

A REPL felszólítása jelzi a jelenlegi névteret, amelyen dolgozunk. Munkánk nagy részében ez az felhasználó névtér, és így a felszólítás a következő lesz:

felhasználó =>

A cikk további részében feltételezzük, hogy hozzáférünk a Clojure REPL-hez, és mindez közvetlenül működik minden ilyen eszközben.

4. Nyelv alapjai

A Clojure nyelv nagyon különbözik sok más JVM alapú nyelvtől, és valószínűleg nagyon szokatlannak tűnik. Lisp nyelvjárásának tekintik, és nagyon hasonló szintaxissal és funkcionalitással rendelkezik, mint a többi Lisp nyelv.

Sok olyan kód, amelyet Clojure-ban írunk - csakúgy, mint más lisp nyelvjárások esetében - listák formájában van kifejezve. Ezután a listákat ki lehet értékelni, hogy eredményeket kapjanak - akár több lista, akár egyszerű értékek formájában.

Például:

(+ 1 2) ; = 3

Ez egy három elemből álló lista. A „+” szimbólum azt jelzi, hogy ezt a hívás-kiegészítést hajtjuk végre. A fennmaradó elemeket ezután felhasználjuk ezzel a hívással. Így ez „1 + 2” értéket jelent.

A List szintaxis itt történő használatával ez triviálisan kibővíthető. Például:

(+ 1 2 3 4 5) ; = 15

Ez pedig „1 + 2 + 3 + 4 + 5” értéket jelent.

Jegyezd meg a pontosvessző karaktert is. Ezt a Clojure-ban használják egy megjegyzés jelzésére, és nem ez a kifejezés vége, ahogy a Java-ban látnánk.

4.1. Egyszerű Típusok

A Clojure a JVM tetejére épül, és mint ilyen, ugyanolyan szabványos típusokhoz férünk hozzá, mint bármely más Java alkalmazáshoz. A típusokat általában automatikusan következtetik, és nem kell kifejezetten megadni.

Például:

123; Hosszú 1,23; Dupla "Hello"; Karakterlánc igaz; Logikai

Megadhatunk néhány bonyolultabb típust is, speciális előtagokkal vagy utótagokkal:

42N; clojure.lang.BigInt 3.14159M; java.math.BigDecimal 1/3; clojure.lang.Ratio # "[A-Za-z] +"; java.util.regex.Pattern

Vegye figyelembe, hogy a clojure.lang.BigInt típusú helyett java.math.BigInteger. Ez azért van, mert a Clojure típusnak vannak kisebb optimalizálásai és javításai.

4.2. Kulcsszavak és szimbólumok

A Clojure megadja nekünk mind a kulcsszavak, mind a szimbólumok fogalmát. A kulcsszavak csak magukra vonatkoznak, és gyakran használják olyan dolgokra, mint a térképkulcsok. A szimbólumok viszont más dolgokra utaló nevek. Például a változódefiníciók és a függvénynevek szimbólumok.

Összeállíthatjuk a kulcsszavakat kettőspont előtagú név használatával:

user =>: kw: kw user =>: a: a

A kulcsszavak közvetlen egyenlőséggel bírnak önmagukkal, és semmi mással nem:

felhasználó => (=: a: a) igaz felhasználó => (=: a: b) hamis felhasználó => (=: a "a") hamis

A Clojure-ban a legtöbb egyéb, nem egyszerű értéket szimbólumnak tekintik. Ezek bármit is értékelnek, amire hivatkoznak, míg egy kulcsszó mindig önmagát értékeli:

user => (def a 1) # 'user / a user =>: a: a user => a 1

4.3. Névterek

A Clojure nyelv a névterek fogalmával rendelkezik a kódunk rendezéséhez. Minden kódrész, amelyet írunk, névtérben él.

Alapértelmezés szerint a REPL a felhasználó névtér - amint azt a „user =>” kifejezés megadja.

A név használatával névtereket hozhatunk létre és változtathatunk meg ns kulcsszó:

felhasználó => (ns new.ns) nulla new.ns =>

Miután megváltoztattuk a névtereket, minden, ami a régiben van definiálva, már nem áll rendelkezésünkre, és az újban definiált minden elérhető.

Teljes körű minősítéssel férhetünk hozzá a névterek közötti definíciókhoz. Például a névtér clojure.húr meghatároz egy függvényt nagybetűs.

Ha a clojure.húr névtér, közvetlenül elérhetjük. Ha nem vagyunk, akkor minősítenünk kell clojure.húr / nagybetű:

user => (clojure.string / nagybetűs "szia") "HELLO" user => (nagybetűs "hello"); Ez nem látható a (felhasználói) névtér szintaxis hibában, amely a (REPL: 1: 1) fordításnál fordult le. Nem lehet feloldani a szimbólumot: ebben a kontextusban nagybetűk: user => (ns clojure.string) nil clojure.string => (nagybetűs "hello"); Ez azért látható, mert most a "HELLO" névtérben vagyunk.

Használhatjuk a megkövetelikkulcsszó hogy könnyebben elérhesse a definíciókat egy másik névtérből. Kétféle módon használhatjuk ezt: meghatározhatunk egy rövidebb névvel ellátott névteret, hogy az könnyebben használható legyen, és hogy egy másik névtér definícióihoz közvetlenül hozzáférhessünk előtag nélkül:

clojure.string => (megköveteli '[clojure.string: as str]) nulla clojure.string => (sztr / nagybetűs "Hello") "HELLO" felhasználó => (" lásd [nagybetűs]]) nil user => (nagybetűs "Hello") "HELLO"

Mindkettő csak az aktuális névteret érinti, ezért egy másikra váltáshoz újra lesz szükség igényel. Ez elősegíti a névterek tisztább megőrzését, és csak a szükséges hozzáférést biztosít számunkra.

4.4. Változók

Ha már tudjuk, hogyan definiálhatunk egyszerű értékeket, hozzárendelhetjük őket változókhoz. Ezt megtehetjük a kulcsszóval def:

user => (def a 123) # 'user / a

Miután ezt megtettük, használhatjuk a szimbólumot abárhol is képviselni akarjuk ezt az értéket:

felhasználó => a 123

A változó definíciók lehetnek olyan egyszerűek vagy olyan bonyolultak, mint szeretnénk.

Például egy változó számok összegeként történő meghatározásához a következőket tehetjük:

felhasználó => (def b (+ 1 2 3 4 5)) # 'user / b felhasználó => b 15

Figyeljük meg, hogy soha nem kell deklarálnunk a változót, vagy meg kell jelölnünk, hogy milyen típusú. A Clojure automatikusan meghatározza mindezt számunkra.

Ha megpróbálunk olyan változót használni, amelyet még nem definiáltunk, akkor hibaüzenetet kapunk:

user => ismeretlen Szintaxis hiba fordításkor (REPL: 0: 0). Nem sikerült feloldani a szimbólumot: ismeretlen ebben az összefüggésben user => (def c (+ 1 ismeretlen)) Szintaxis hiba fordításkor (REPL: 1: 8). Nem lehet feloldani a szimbólumot: ebben az összefüggésben ismeretlen

Figyeljük meg, hogy a def funkció kissé eltér a bemenettől. Változó meghatározása a karakterláncot ad vissza ’Felhasználó / a. Ennek oka, hogy az eredmény egy szimbólum, és ez a szimbólum az aktuális névtérben van meghatározva.

4.5. Funkciók

A Clojure-ban már láttunk pár példát a függvények meghívására. Létrehozunk egy listát, amely a meghívandó függvénnyel kezdődik, majd az összes paraméterrel.

Amikor ez a lista kiértékeli, akkor a függvény visszatérési értékét kapjuk. Például:

user => (java.time.Instant / now) #object [java.time.Instant 0x4b6690c0 "2019-01-15T07: 54: 01.516Z"] user => (java.time.Instant / parse "2019-01- 15T07: 55: 00Z ") #object [java.time.Instant 0x6b8d96d9" 2019-01-15T07: 55: 00Z "] user => (java.time.OffsetDateTime / of 2019 01 15 7 56 0 0 java.time. ZoneOffset / UTC) #object [java.time.OffsetDateTime 0xf80945f "2019-01-15T07: 56Z"]

Beágyazhatjuk a függvények hívásait is, mert amikor az egyik függvényhívás kimenetét paraméterként szeretnénk átadni egy másiknak:

felhasználó => (java.time.OffsetDateTime / 2018 01 15 7 57 0 0 (java.time.ZoneOffset / ofHours -5)) #object [java.time.OffsetDateTime 0x1cdc4c27 "2018-01-15T07: 57-05: 00 "]

Is, meghatározhatjuk a funkcióinkat is ha vágyunk. A függvények a fn parancs:

user => (fn [a b] (println "Számok hozzáadása" a "és" b) (+ a b)) #object [user $ eval165 $ fn__166 0x5644dc81 "[email protected]"]

Sajnálatos módon, ez nem adja meg a függvénynek a felhasználható nevet. Ehelyett meghatározhatunk egy szimbólumot, amely ezt a függvényt képviseli def, pontosan úgy, ahogy a változóknál láthattuk:

felhasználó => (def add (fn [a b] (println "Számok hozzáadása" a "és" b "(+ a b))) # 'user / add

Most, hogy definiáltuk ezt a függvényt, ugyanúgy hívhatjuk, mint bármely más függvényt:

user => (add 1 2) 1. és 2. szám hozzáadása 3

Kényelem érdekében A Clojure lehetővé teszi számunkra a felhasználást is defn hogy egy funkcióval meghatározzuk a nevét egyetlen menetben.

Például:

user => (defn sub [a b] (println "" b "kivonása" a "-ból (- a b)) # 'user / sub user => (sub 5 2) 2 kivonása 5 3-ból

4.6. Let és lokális változók

A def A call egy olyan szimbólumot határoz meg, amely globális az aktuális névtérben. Általában nem erre van szükség a kód futtatásakor. Helyette, A Clojure a hadd hívás egy blokkhoz lokális változók meghatározásához. Ez különösen akkor hasznos, ha belső funkciókban használják őket, ahol nem szeretné, hogy a változók a függvényen kívül szivárogjanak.

Például meghatározhatnánk az alfunkciónkat:

felhasználó => (defn al [a b] (def eredmény (- a b)) (println "Eredmény:" eredmény) eredmény) # 'felhasználó / al

Ennek azonban a következő váratlan mellékhatása van:

felhasználó => (1 2. rész) Eredmény: -1 -1 felhasználó => eredmény; A -1 függvényen kívül is látható

Ehelyett írjuk újra a használatával hadd:

felhasználó => (defn sub [ab] (legyen [eredmény (- ab)] (println "Eredmény:" eredmény) eredmény)) # 'felhasználó / alfelhasználó => (al 1 2) Eredmény: -1 -1 felhasználó = > eredmény Szintaxis hiba fordításkor (REPL: 0: 0). Nem sikerült feloldani a szimbólum: eredményt ebben az összefüggésben

Ezúttal a eredmény szimbólum a függvényen kívül nem látható. Vagy valóban a hadd blokk, amelyben használták.

5. Gyűjtemények

Eddig többnyire egyszerű értékekkel voltunk kölcsönhatásban. Láttunk listákat is, de semmi többet. A Clojure-nak van egy teljes gyűjteménye, amelyek felhasználhatók, azonban listákból, vektorokból, térképekből és halmazokból állnak:

  • A vektor egy rendezett értéklista - bármely tetszőleges érték beilleszthető egy vektorba, beleértve más gyűjteményeket is.
  • A halmaz nem rendezett értékgyűjtemény, és soha nem tartalmazhatja ugyanazt az értéket többször.
  • A térkép a kulcs / érték párok egyszerű halmaza. Nagyon gyakori, hogy kulcsszavakat használunk kulcsokként egy térképen, de tetszőleges értéket használhatunk, beleértve más gyűjteményeket is.
  • A lista nagyon hasonlít egy vektorhoz. A különbség hasonló az an közötti különbséggel Tömb lista és a LinkedList Java-ban. Jellemzően egy vektor előnyben részesítése, de egy lista jobb, ha elemeket akarunk hozzáadni a kezdethez, vagy ha csak sorrendben szeretnénk hozzáférni az elemekhez.

5.1. Gyűjtemények építése

Ezek mindegyike létrehozható rövidítéssel vagy függvényhívással:

; Vektor felhasználó => [1 2 3] [1 2 3] felhasználó => (1 2 3 vektor) [1 2 3]; Felhasználó listája => '(1 2 3) (1 2 3) felhasználó => (1 2 3 lista) (1 2 3); Set user => # {1 2 3} # {1 3 2} user => (hash-set 1 2 3) # {1 3 2}; Map user => {: a 1: b 2} {: a 1,: b 2} user => (hash-map: a 1: b 2) {: b 2,: a 1}

Figyeljük meg, hogy a Készlet és Térkép a példák nem adják vissza az értékeket ugyanabban a sorrendben. Ezek a gyűjtemények ugyanis eredendően rendezetlenek, és amit látunk, attól függ, hogy miként vannak ábrázolva a memóriában.

Azt is láthatjuk, hogy a lista létrehozásának szintaxisa nagyon hasonlít a kifejezések szabványos Clojure szintaxisához. A Clojure kifejezés valójában egy lista, amelyet kiértékelnek, míg az aposztróf karakter itt azt jelzi, hogy az értékelés helyett a tényleges értéklistát szeretnénk.

Természetesen a változóhoz ugyanúgy rendelhetünk gyűjteményt, mint bármely más értéket. Használhatunk egy gyűjteményt kulcsként vagy értékként egy másik gyűjteményen belül is.

A listákat a szekvencia. Ez azt jelenti, hogy az osztály végrehajtja a ISeq felület. Az összes többi gyűjtemény átalakítható a szekvencia használni a szekvencia funkció:

user => (seq [1 2 3]) (1 2 3) user => (seq # {1 2 3}) (1 3 2) user => (seq {: a 1 2 3}) ([: a 1] [2 3])

5.2. Hozzáférés a gyűjteményekhez

Ha van gyűjteményünk, akkor kölcsönhatásba léphetünk vele, hogy az értékek újra visszakaphassanak. Hogy ezt hogyan tudjuk megtenni, kissé a kérdéses gyűjteménytől függ, mivel mindegyiküknek más a szemantikája.

A vektorok az egyetlen gyűjtemény, amely lehetővé teszi tetszőleges értékek indexenkénti megszerzését. Ezt úgy végezzük, hogy kiértékeljük a vektort és az indexet mint kifejezést:

felhasználó => (my-vector 2); [1 2 3] 3

Ugyanezt megtehetjük, ugyanazt a szintaxist használva a térképekhez is:

felhasználó => (saját térképem: b) 2

A vektorok és listák elérésére szolgáló funkciók is vannak az első érték, az utolsó érték és a lista többi részének megszerzéséhez:

felhasználó => (első saját vektorom) 1 felhasználó => (utolsó listám) 3 felhasználó => (következő saját vektorom) (2 3)

A Maps további funkciókkal rendelkezik a kulcsok és értékek teljes listájának megszerzéséhez:

felhasználó => (kulcsok a saját térképemhez) (: a: b) felhasználó => (az én térképemet ellenőrzi) (1 2)

Az egyetlen valódi hozzáférés, amelyet beállítanunk kell, annak megnézése, hogy egy adott elem tagja-e.

Ez nagyon hasonlít bármely más gyűjtemény eléréséhez:

user => (saját-készlet 1) 1 felhasználó => (saját-készlet 5) nulla

5.3. Gyűjtemények azonosítása

Láttuk, hogy a gyűjtemény elérésének módja a gyűjtemény típusától függően változik. Van egy sor funkció, amelyek segítségével ezt meghatározhatjuk, mind specifikus, mind általánosabb módon.

Minden gyűjteményünknek van egy speciális funkciója annak meghatározására, hogy egy adott érték ilyen típusú-e - lista? listákhoz, készlet? készletekhez stb. Ezenkívül van seq? annak meghatározásához, hogy egy adott érték a szekvencia bármiféle, és asszociációs? annak meghatározása, hogy egy adott érték bármilyen típusú asszociatív hozzáférést engedélyez-e - ami vektorokat és térképeket jelent:

felhasználó => (vektor? [1 2 3]); A vektor egy vektor true user => (vektor? # {1 2 3}); Egy halmaz nem vektor hamis felhasználó => (list? '(1 2 3)); A lista egy lista true user => (lista? [1 2 3]); A vektor nem lista hamis felhasználó => (térkép? {: A 1: b 2}); A térkép egy igazi felhasználó => (térkép? # {1 2 3}); A halmaz nem térkép hamis felhasználó => (szekvencia? '(1 2 3)); A lista egy seq true user => (seq? [1 2 3]); A vektor nem seq hamis felhasználó => (seq? (Seq [1 2 3])); Egy vektort átalakíthatunk seq true user => (asszociatív? {: A 1: b 2}); A térkép asszociatív true user => (asszociatív? [1 2 3]); A vektor asszociatív igaz felhasználó => (asszociatív? '(1 2 3)); A lista nem asszociatív hamis

5.4. Mutáló gyűjtemények

A Clojure-ban, mint a legtöbb funkcionális nyelv esetében, minden gyűjtemény változhatatlan. Bármi, amit a gyűjtemény megváltoztatása érdekében teszünk, egy teljesen új kollekciót hoz létre, amely képviseli a változásokat. Ez óriási hatékonysági előnyökkel járhat, és azt jelenti, hogy nem áll fenn véletlen mellékhatások kockázata.

Arra is ügyelnünk kell azonban, hogy megértsük ezt, különben a kollekcióink várható változásai nem történnek meg.

Új elemek hozzáadása egy vektorhoz, listához vagy halmazhoz a köt. Ez mindegyik esetben másképp működik, de ugyanazzal az alapvető szándékkal:

felhasználó => (conj [1 2 3] 4); Hozzáadja a [1 2 3 4] végfelhasználót => (conj '(1 2 3) 4); Hozzáadja az elejéhez (4 1 2 3) user => (conj # {1 2 3} 4); Rendezetlen # {1 4 3 2} felhasználó => (conj # {1 2 3} 3); Már meglévő bejegyzés hozzáadása nem tesz semmit # {1 3 2}

A bejegyzéseket a készletből is eltávolíthatjuk disj. Vegye figyelembe, hogy ez nem működik egy listán vagy vektoron, mert szigorúan vannak rendezve:

felhasználó => (disj # {1 2 3} 2); Eltávolítja a (z) {1 3} user => bejegyzést (disj # {1 2 3} 4); Nem tesz semmit, mert a bejegyzés nem volt jelen # {1 3 2}

Új elemek hozzáadása a térképhez a asszociált. A bejegyzéseket a térkép segítségével is eltávolíthatjuk disszociáció:

felhasználó => (társított {: a 1: b 2}: c 3); Új kulcsot ad hozzá: {: a 1,: b 2,: c 3} user => (társított {: a 1: b 2}: b 3); Frissít egy meglévő kulcsot: {: a 1,: b 3} user => (dissoc {: a 1: b 2}: b); Eltávolít egy meglévő kulcsot: {: a 1} user => (dissoc {: a 1: b 2}: c); Nem tesz semmit, mert a kulcs nem volt jelen: {: a 1,: b 2}

5.5. Funkcionális programozási konstrukciók

A Clojure lényege funkcionális programozási nyelv. Ez azt jelenti számos hagyományos funkcionális programozási koncepcióhoz hozzáférünk - például térkép, szűrő, és csökkenteni. Ezek általában ugyanúgy működnek, mint más nyelveken. A pontos szintaxis azonban kissé eltérhet.

Pontosabban, ezek a függvények általában az első argumentumként alkalmazzák a függvényt, második argumentumként pedig a gyűjteményt, amelyre alkalmazzák:

felhasználó => (térkép növ. [1 2 3]); Növelje a vektor minden értékét (2 3 4) user => (térkép növekmény # {1 2 3}); Növelje a halmaz minden értékét (2 4 3) user => (páratlan szűrő? [1 2 3 4 5]); Csak a páratlan értékeket adja vissza (1 3 5) user => (távolítsa el a páratlan? [1 2 3 4 5]); Csak nem páratlan értékeket adjon vissza (2 4) user => (csökkentse + [1 2 3 4 5]); Az összes értéket összeadva adja vissza az 15 összeget

6. Vezérlő szerkezetek

Mint minden általános célú nyelv esetében, a Clojure is szabványos vezérlő struktúrákat igényel, például feltételeket és ciklusokat.

6.1. Feltételek

A feltételeket a ha nyilatkozat. Ehhez három paraméter szükséges: egy teszt, egy blokk végrehajtása, ha a teszt az igaz, és egy blokkot végrehajtani, ha a teszt hamis. Ezek mindegyike lehet egyszerű érték vagy standard lista, amelyet igény szerint értékelünk:

felhasználó => (ha igaz 1 2) 1 felhasználó => (ha hamis 1 2) 2

Tesztünk egyáltalán bármi lehet, amire szükségünk van - nem kell, hogy a igaz hamis érték. Ez is lehet egy blokk, amelyet kiértékelnek, hogy megadják a szükséges értéket:

felhasználó => (if (> 1 2) "Igaz" "Hamis") "Hamis"

Az összes szokásos ellenőrzés, beleértve a következőket: =, >, és <, itt használható. Van még egy sor predikátum is, amelyet különféle egyéb okokból is fel lehet használni - például a kollekciók megtekintésekor láttunk néhányat:

user => (if (páratlan? 1) "1 páratlan" "1 páros") "1 páratlan"

A teszt bármilyen értéket visszaadhat - nem csak annak kell lennie igaz vagy hamis. Úgy tartják azonban igaz ha az érték bármi más, kivéve hamis vagy nulla. Ez különbözik a JavaScript működésétől, ahol számos olyan érték áll rendelkezésre, amelyeket „igazság-y” -nek tekintenek, de nem igaz:

felhasználó => (ha 0 "Igaz" "Hamis") "Igaz" felhasználó => (ha [] "Igaz" "Hamis") "Igaz" felhasználó => (ha nulla "Igaz" "Hamis") "Hamis"

6.2. Hurok

A gyűjteményekkel kapcsolatos funkcionális támogatásunk a hurkolás nagy részét kezeli - ahelyett, hogy ciklust írnánk a gyűjtemény fölé, a standard függvényeket használjuk, és hagyjuk, hogy a nyelv végezze el az iterációt helyettünk.

Ezen kívül a hurkolás teljes egészében rekurzióval történik. Írhatunk rekurzív függvényeket, vagy használhatjuk a hurok és megismétlődni kulcsszavak a rekurzív stíluskör megírásához:

felhasználó => (hurok [akkumulátor [] i 0] (ha (= i 10) felhalmozódás (megismétlődik (köt. felh. i) (beleértve i)))) [0 1 2 3 4 5 6 7 8 9]

A hurok A call egy belső blokkot indít, amelyet minden iterációnál végrehajtanak, és néhány kezdeti paraméter beállításával indul. A ismételje meg A hívás ekkor visszahív a ciklusba, megadva az iterációhoz következő paramétereket. Ha ismételje meg nincs meghívva, akkor a hurok befejeződik.

Ebben az esetben hurkolunk minden alkalommal, amikor a én értéke nem egyenlő 10-vel, majd amint megegyezik 10-vel, ehelyett visszaadjuk a felhalmozott számvektort.

7. Összegzés

Ez a cikk bemutatta a Clojure programozási nyelvet, és bemutatja a szintaxis működését, valamint néhány dolgot, amit ezzel megtehet. Ez csak egy bevezető szint, és nem megy bele minden mélységébe, ami a nyelvvel elvégezhető.

Azonban miért ne venné fel, engedje meg és nézze meg, mit tehet vele.


$config[zx-auto] not found$config[zx-overlay] not found