Clojure-퀵 가이드

Clojure는 높은 수준의 동적 함수 프로그래밍 언어입니다. Clojure는 LISP 프로그래밍 언어를 기반으로 설계되었으며 Java 및 .Net 런타임 환경에서 실행되는 컴파일러가 있습니다.

Clojure에 대해 이야기하기 전에 LISP 프로그래밍 언어에 대해 간단히 설명하겠습니다. LISP에는 작은 언어 코어, 거의 구문이 없으며 강력한 매크로 기능이 있습니다. 이러한 기능을 사용하면 다른 방법 대신 LISP를 구부려 설계에 맞출 수 있습니다. LISP는 1958 년으로 거슬러 올라가 오랫동안 그곳에있었습니다.

Common LISP는 표현식을 읽고 평가 한 다음 결과를 인쇄합니다. 예를 들어 4 + 6의 간단한 수학 식의 값을 계산하려면 입력합니다.

USER(1) (+ 4 6)

Clojure는 프로그래밍 언어로서 다음과 같은 높은 수준의 핵심 목표를 가지고 있습니다.

  • 이는 기존 프로그래밍 언어보다 코드 문을 작게 만드는 LISP 프로그래밍 언어를 기반으로합니다.

  • 함수형 프로그래밍 언어입니다.

  • 그것은 기본적으로 제자리에 생성 된 객체를 변경해서는 안된다는 개념 인 불변성에 중점을 둡니다.

  • 프로그래머를 위해 애플리케이션의 상태를 관리 할 수 ​​있습니다.

  • 동시성을 지원합니다.

  • 기존 프로그래밍 언어를 포함합니다. 예를 들어 Clojure는 JVM을 통해 코드 실행을 관리하기 위해 전체 Java 에코 시스템을 사용할 수 있습니다.

Clojure의 공식 웹 사이트는 https://clojure.org/

Clojure를 프로그래밍 언어로 사용하는 방법에는 여러 가지가 있습니다. Clojure 프로그래밍을 사용하는 두 가지 방법을 살펴 보겠습니다.

  • Leiningen − Leiningen은 Clojure 프로젝트를 생성, 구축 및 자동화하는 데 필수적인 도구입니다.

  • Eclipse Plugin − CounterClockwise라는 플러그인이 있으며 Eclipse IDE에서 Clojure 개발을 수행하기 위해 Eclipse에서 사용할 수 있습니다.

Leiningen 설치

설치를 진행하기 전에 다음 시스템 요구 사항이 충족되는지 확인하십시오.

시스템 요구 사항

JDK JDK 1.7 이상
기억 2GB RAM (권장)

Step 1− 바이너리 설치를 다운로드합니다. 링크로 이동http://leiningen-wininstallerWindows Installer를 얻으려면. 옵션을 클릭하여 Groovy 설치 프로그램의 다운로드를 시작하십시오.

Step 2 − 설치 프로그램을 시작하고 다음 버튼을 클릭합니다.

Step 3 − 설치할 위치를 지정하고 다음 버튼을 클릭합니다.

Step 4− 설치 프로그램이 기존 Java 설치 위치를 감지합니다. 계속하려면 다음 버튼을 클릭하십시오.

Step 5 − 설치를 시작하려면 설치 버튼을 클릭합니다.

설치가 완료되면 Clojure 프로그램을 만들고 테스트하는 데 사용할 수있는 환경 인 Clojure REPL을 열 수있는 옵션이 제공됩니다.

Eclipse 설치

설치를 진행하기 전에 다음 시스템 요구 사항이 충족되는지 확인하십시오.

시스템 요구 사항

JDK JDK 1.7 이상
Eclipse 4.5 (Mars)

Step 1− Eclipse를 열고 메뉴 항목을 클릭합니다. 도움말 → Eclipse Marketplace를 클릭하십시오.

Step 2− 나타나는 대화 상자에 키워드 Clojure를 입력하고 '이동'버튼을 누르십시오. 시계 반대 방향 옵션이 나타나면 설치 버튼을 클릭하여이 플러그인의 설치를 시작합니다.

Step 3 − 다음 대화 상자에서 확인 버튼을 클릭하여 설치를 시작합니다.

Step 4− 다음 대화 상자에서 사용권 계약에 동의하라는 메시지가 표시됩니다. 라이센스 계약에 동의하고 마침 버튼을 클릭하여 설치를 계속합니다.

설치가 시작되고 완료되면 Eclipse를 다시 시작하라는 메시지가 표시됩니다.

Eclipse가 다시 시작되면 Eclipse에 새 Clojure 프로젝트를 만드는 옵션이 표시됩니다.

Clojure의 기본 구문을 이해하기 위해 먼저 간단한 Hello World 프로그램을 살펴 보겠습니다.

완전한 프로그램으로서의 Hello World

완전한 Clojure 프로그램에서 'Hello world'를 작성하십시오. 다음은 그 예입니다.

(ns clojure.examples.hello
   (:gen-class))
(defn hello-world []
   (println "Hello World"))
(hello-world)

위 프로그램에 대해 다음 사항에 유의해야합니다.

  • 프로그램은 main.clj라는 파일에 작성됩니다. 확장자 'clj'는 클로저 코드 파일의 확장자 이름입니다. 위의 예에서 파일 이름은 main.clj입니다.

  • 'defn'키워드는 함수를 정의하는 데 사용됩니다. 다른 장에서 자세한 기능을 볼 것입니다. 그러나 지금은 메인 Clojure 코드가있는 helloworld라는 함수를 만들고 있음을 알고 있습니다.

  • Clojure 코드에서 'println'문을 사용하여 콘솔 출력에 "Hello World"를 인쇄합니다.

  • 그런 다음 'println'문을 실행하는 hello-world 함수를 호출합니다.

위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

Hello World

성명서의 일반적인 형식

다음 예와 같이 모든 문의 일반 형식은 중괄호로 평가해야합니다.

(+ 1 2)

위의 예에서 전체 표현식은 중괄호로 묶여 있습니다. 위 명령문의 출력은 3입니다. + 연산자는 숫자를 추가하는 데 사용되는 Clojure의 함수처럼 작동합니다. 1과 2의 값은 다음과 같이 알려져 있습니다. parameters to the function.

또 다른 예를 살펴 보겠습니다. 이 예에서 'str'은 두 문자열을 연결하는 데 사용되는 연산자입니다. "Hello"및 "World"문자열이 매개 변수로 사용됩니다.

(str "Hello" "World")

위의 두 문장을 조합하여 프로그램을 작성하면 다음과 같이됩니다.

(ns clojure.examples.hello
   (:gen-class))
(defn Example []
   (println (str "Hello World"))
   (println (+ 1 2)))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

Hello World
3

네임 스페이스

네임 스페이스는 Clojure에 정의 된 모듈 간의 논리적 경계를 정의하는 데 사용됩니다.

현재 네임 스페이스

이것은 현재 Clojure 코드가있는 현재 네임 스페이스를 정의합니다.

통사론

*ns*

REPL 명령 창에서 다음 명령을 실행하십시오.

*ns*

산출

위의 명령을 실행하면 현재 네임 스페이스에 따라 출력이 지연됩니다. 다음은 출력의 예입니다. Clojure 코드의 네임 스페이스는-

clojure.examples.hello

(ns clojure.examples.hello
   (:gen-class))
(defn Example []
   (println (str "Hello World"))
   (println (+ 1 2)))
(Example)

Clojure의 Require 문

Clojure 코드는 라이브러리에 패키지되어 있습니다. 각 Clojure 라이브러리는 Java 패키지와 유사한 네임 스페이스에 속합니다. 'Require'문을 사용하여 Clojure 라이브러리를로드 할 수 있습니다.

통사론

(require quoted-namespace-symbol)

다음은이 명령문의 사용 예입니다.

(ns clojure.examples.hello
   (:gen-class))
(require ‘clojure.java.io’)
(defn Example []
   (.exists (file "Example.txt")))
(Example)

위 코드에서 우리는 'require'키워드를 사용하여 입력 / 출력 기능에 필요한 모든 기능이있는 네임 스페이스 clojure.java.io를 가져옵니다. 필요한 라이브러리가 없기 때문에 위 코드에서 'file'함수를 사용할 수 있습니다.

Clojure의 의견

주석은 코드를 문서화하는 데 사용됩니다. 한 줄 주석은 ;; 라인의 모든 위치에서. 다음은 그 예입니다.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (println "Hello World"))
(Example)

구분자

Clojure에서 문은 곡선 또는 대괄호 중괄호를 사용하여 분할하거나 구분할 수 있습니다.

다음은 두 가지 예입니다.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (println (+ 1 2 3)))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

6

다음은 또 다른 예입니다.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (println [+ 1 2 3]))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

[#object[clojure.core$_PLUS_ 0x10f163b "clojure.core$_PLUS_@10f163b"] 1 2 3]

공백

Clojure에서 공백을 사용하여 더 명확하게하기 위해 명령문의 여러 구성 요소를 분할 할 수 있습니다. 이것은 쉼표 (,) 연산자의 도움으로 수행 할 수 있습니다.

예를 들어 다음 두 명령문은 동일하며 두 명령문의 출력은 15가됩니다.

(+ 1 2 3 4 5)
(+ 1, 2, 3, 4, 5)

Clojure는 쉼표를 무시하지만 때로는 프로그래머가 더 쉽게 읽을 수 있도록 쉼표를 사용합니다.

예를 들어 다음과 같은 해시 맵 (def a-map {: a 1 : b 2 : c 3})이 있고 REPL 창에서 해당 값을 요청하면 Clojure는 출력을 {: a 1, : b 2, : c 3}.

특히 많은 양의 데이터를보고있는 경우 결과를 읽기가 더 쉽습니다.

기호

Clojure에서 기호는 다른 프로그래밍 언어의 식별자와 동일합니다. 그러나 다른 프로그래밍 언어와 달리 컴파일러는 기호를 실제 문자열 값으로 간주합니다. 심볼이 값이기 때문에 다른 객체와 마찬가지로 심볼을 컬렉션에 저장하고 함수 등에 인수로 전달할 수 있습니다.

기호에는 영숫자와 '* +! /. :-_? ' 그러나 숫자 나 콜론으로 시작해서는 안됩니다.

다음은 유효한 기호의 예입니다.

tutorial-point!
TUTORIAL
+tutorial+

Clojure 프로젝트 구조

마지막으로 Clojure 프로젝트의 일반적인 프로젝트 구조에 대해 이야기하겠습니다. Clojure 코드는 Java 가상 머신에서 실행되기 때문에 Clojure 내의 대부분의 프로젝트 구조는 Java 프로젝트에서 찾을 수있는 것과 유사합니다. 다음은 Clojure 프로젝트를위한 Eclipse의 샘플 프로젝트 구조 스냅 샷입니다.

위의 프로그램 구조에 대해 다음과 같은 주요 사항에 유의해야합니다.

  • demo_1-이것은 Clojure 코드 파일이있는 패키지입니다.

  • core.clj-이것은 Clojure 응용 프로그램의 코드를 포함하는 기본 Clojure 코드 파일입니다.

  • Leiningen 폴더에는 Clojure 기반 애플리케이션을 실행하는 데 필요한 clojure-1.6.0.jar과 같은 파일이 포함되어 있습니다.

  • pom.properties 파일에는 Clojure 프로젝트의 groupId, artifactId 및 버전과 같은 정보가 포함됩니다.

  • project.clj 파일에는 Clojure 애플리케이션 자체에 대한 정보가 포함되어 있습니다. 다음은 프로젝트 파일 내용의 샘플입니다.

(defproject demo-1 "0.1.0-SNAPSHOT"
   :description "FIXME: write description"
   :url "http://example.com/FIXME"
   :license {
      :name "Eclipse Public License"
      :url "http://www.eclipse.org/legal/epl-v10.html"
   }
   :dependencies [[org.clojure/clojure "1.6.0"]])

REPL (read-eval-print loop)은 Clojure 코드를 실험하기위한 도구입니다. 이를 통해 실행중인 프로그램과 상호 작용하고 일이 제대로 작동하는지 신속하게 시험해 볼 수 있습니다. 코드를 입력 할 수있는 프롬프트를 표시하여이를 수행합니다. 그런 다음 입력을 읽고, 평가하고, 결과를 인쇄하고, 반복하여 프롬프트를 다시 표시합니다.

이 프로세스를 통해 대부분의 다른 언어에서는 불가능한 빠른 피드백주기가 가능합니다.

REPL 세션 시작

REPL 세션은 명령 줄에 다음 명령을 입력하여 Leiningen에서 시작할 수 있습니다.

lein repl

다음 REPL 창이 시작됩니다.

그런 다음 필요에 따라 REPL 창에서 Clojure 명령 평가를 시작합니다.

Eclipse에서 REPL 세션을 시작하려면 메뉴 옵션을 클릭하고 다음으로 실행 → Clojure 애플리케이션으로 이동하십시오.

콘솔 출력과 함께 별도의 창에서 새 REPL 세션이 시작됩니다.

개념적으로 REPL은 SSH (Secure Shell)와 유사합니다. SSH를 사용하여 원격 서버와 상호 작용할 수있는 것과 동일한 방식으로 Clojure REPL을 사용하면 실행중인 Clojure 프로세스와 상호 작용할 수 있습니다. 이 기능은 REPL을 라이브 프로덕션 앱에 첨부하고 실행되는 프로그램을 수정할 수 있기 때문에 매우 강력 할 수 있습니다.

REPL의 특수 변수

REPL에는 몇 가지 유용한 변수가 포함되어 있으며 널리 사용되는 변수는 특수 변수 * 1, * 2 및 * 3입니다. 이것은 가장 최근의 세 가지 표현식의 결과를 평가하는 데 사용됩니다.

다음 예는 이러한 변수를 사용하는 방법을 보여줍니다.

user => "Hello"
Hello
user => "World"
World
user => (str *2 *1)
HelloWorld

위의 예에서 처음 두 문자열은 각각 "Hello"및 "World"로 REPL 출력 창에 전송됩니다. 그런 다음 * 2 및 * 1 변수를 사용하여 마지막 2 개의 평가 된 식을 호출합니다.

Clojure는 다양한 built-in data types.

내장 데이터 유형

다음은 Clojure에 정의 된 데이터 유형 목록입니다.

  • Integers − 다음은 Clojure에서 사용할 수있는 정수의 표현입니다.

    • Decimal Integers (Short, Long and Int)− 정수를 나타내는 데 사용됩니다. 예 : 1234.

    • Octal Numbers− 8 진수로 숫자를 표현하는 데 사용됩니다. 예 : 012.

    • Hexadecimal Numbers− 숫자를 표현하는 데 사용됩니다. 예 : 0xff.

    • Radix Numbers− 기수 표현으로 숫자를 표현하는 데 사용됩니다. 예를 들어, 2r1111에서 기수는 2에서 36 사이의 정수입니다.

  • Floating point

    • 기본값은 32 비트 부동 소수점 숫자를 나타내는 데 사용됩니다. 예 : 12.34.

    • 다른 표현은 과학적 표기법입니다. 예 : 1.35e-12.

  • char− 이것은 단일 문자 리터럴을 정의합니다. 문자는 백래시 기호로 정의됩니다. 예 : / e.

  • Boolean − 이것은 true 또는 false가 될 수있는 부울 값을 나타냅니다.

  • String− 이들은 문자 체인의 형태로 표현되는 텍스트 리터럴입니다. 예 : "Hello World".

  • Nil − Clojure에서 NULL 값을 나타내는 데 사용됩니다.

  • Atom− Atom은 공유, 동기, 독립 상태를 관리하는 방법을 제공합니다. refs 및 vars와 같은 참조 유형입니다.

바운드 값

Clojure의 모든 데이터 유형은 Java에서 상속되므로 경계 값은 Java 프로그래밍 언어와 동일합니다. 다음 표는 숫자 및 10 진수 리터럴에 허용되는 최대 값을 보여줍니다.

리터럴 범위
짧은 -32,768에서 32,767
int -2,147,483,648에서 2,147,483,647
-9,223,372,036,854,775,808 ~ +9,223,372,036,854,775,807
흙손 1.40129846432481707e-45 ~ 3.40282346638528860e + 38
더블 4.94065645841246544e-324d에서 1.79769313486231570e + 308d로

클래스 숫자 유형

기본 유형 외에도 다음 객체 유형 (래퍼 유형이라고도 함)이 허용됩니다.

이름
java.lang.Byte
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float
java.lang.Double

다음 프로그램은 Clojure의 데이터 유형을 보여주기 위해 통합 된 clojure 코드를 보여줍니다.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   ;; The below code declares a integer variable
   (def x 1)
   
   ;; The below code declares a float variable
   (def y 1.25)
   
   ;; The below code declares a string variable
   (def str1 "Hello")
   (println x)
   (println y)
   (println str1))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

1
1.25
Hello

Clojure에서 variables 에 의해 정의됩니다 ‘def’예어. 변수의 개념이 바인딩과 더 관련이 있다는 점에서 약간 다릅니다. Clojure에서 값은 변수에 바인딩됩니다. Clojure에서 주목해야 할 한 가지 중요한 점은 변수가 불변이라는 것입니다. 즉, 변수의 값이 변경 되려면 삭제하고 다시 만들어야합니다.

다음은 Clojure의 기본 변수 유형입니다.

  • short− 짧은 숫자를 나타내는 데 사용됩니다. 예 : 10.

  • int− 정수를 나타내는 데 사용됩니다. 예 : 1234.

  • long− 이것은 긴 숫자를 나타내는 데 사용됩니다. 예 : 10000090.

  • float− 32 비트 부동 소수점 수를 나타내는 데 사용됩니다. 예 : 12.34.

  • char− 이것은 단일 문자 리터럴을 정의합니다. 예 : '/ a'.

  • Boolean − 이것은 true 또는 false가 될 수있는 부울 값을 나타냅니다.

  • String− 이들은 문자 체인의 형태로 표현되는 텍스트 리터럴입니다. 예 : "Hello World".

변수 선언

다음은 변수를 정의하는 일반적인 구문입니다.

통사론

(def var-name var-value)

여기서 'var-name'은 변수의 이름이고 'var-value'는 변수에 바인딩 된 값입니다.

다음은 변수 선언의 예입니다.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   ;; The below code declares a integer variable
   (def x 1)
   
   ;; The below code declares a float variable
   (def y 1.25)

   ;; The below code declares a string variable
   (def str1 "Hello")
   
   ;; The below code declares a boolean variable
   (def status true))
(Example)

이름 지정 변수

변수 이름은 문자, 숫자 및 밑줄 문자로 구성 될 수 있습니다. 문자 또는 밑줄로 시작해야합니다. Java와 마찬가지로 Clojure는 대소 문자를 구분하는 프로그래밍 언어이기 때문에 대문자와 소문자가 구별됩니다.

다음은 Clojure에서 변수 이름 지정의 몇 가지 예입니다.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   ;; The below code declares a Boolean variable with the name of status
   (def status true)
   
   ;; The below code declares a Boolean variable with the name of STATUS
   (def STATUS false)
   
   ;; The below code declares a variable with an underscore character.
   (def _num1 2))
(Example)

Note − 위의 설명에서 대소 문자 구분으로 인해 상태와 STATUS는 Clojure에서 정의하는 두 가지 다른 변수입니다.

위의 예는 밑줄 문자로 변수를 정의하는 방법을 보여줍니다.

변수 인쇄

Clojure는 JVM 환경을 사용하므로 'println'기능을 사용할 수도 있습니다. 다음 예는이를 달성하는 방법을 보여줍니다.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   ;; The below code declares a integer variable
   (def x 1)
   
   ;; The below code declares a float variable
   (def y 1.25)
   
   ;; The below code declares a string variable
   (def str1 "Hello")
   (println x)
   (println y)
   (println str1))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

1
1.25
Hello

operator 컴파일러에게 특정 수학적 또는 논리적 조작을 수행하도록 지시하는 기호입니다.

Clojure에는 다음과 같은 유형의 연산자가 있습니다.

  • 산술 연산자
  • 관계 연산자
  • 논리 연산자
  • 비트 연산자

Note − Clojure에서 연산자와 피연산자는 다음 구문 방식으로 작동합니다.

통사론

(operator operand1 operand2 operandn)

예를 들면

(+ 1 2)

위의 예는 숫자 1과 2에 대한 산술 연산을 수행합니다.

산술 연산자

Clojure 언어는 모든 언어로 일반 산술 연산자를 지원합니다. 다음은 Clojure에서 사용할 수있는 산술 연산자입니다.

예시보기

운영자 기술
+ 두 개의 피연산자 추가 (+ 1 2) 3을 줄 것입니다
첫 번째에서 두 번째 피연산자를 뺍니다. (-2 1) 1을 줄 것입니다.
* 두 피연산자의 곱셈 (* 2 2) 4를 줄 것입니다
/ 분모로 분자 나누기 (float (/ 3 2)) 1.5를 줄 것입니다.
inc 피연산자의 값을 1 씩 증가시키는 데 사용되는 증분 연산자 inc 5는 6을 줄 것입니다.
12 월 피연산자의 값을 1 씩 줄이는 데 사용되는 증분 연산자 12 월 5 일은 4를 줄 것입니다
최대 가장 큰 인수를 반환합니다. max 12 3은 3을 반환합니다.
가장 작은 인수를 반환합니다. min 12 3은 1을 반환합니다.
첫 번째 숫자를 두 번째로 나눈 나머지 rem 3 2는 1을 줄 것입니다

관계 연산자

관계 연산자를 사용하면 개체를 비교할 수 있습니다. 다음은 Clojure에서 사용할 수있는 관계 연산자입니다.

예시보기

운영자 기술
= 두 개체 간의 동등성을 테스트합니다. (= 2 2) 사실을 줄 것입니다
not = 두 개체의 차이를 테스트합니다. (not = 3 2) true를 제공합니다.
< 왼쪽 개체가 오른쪽 피연산자보다 작은 지 확인합니다. (<2 3) 사실을 줄 것입니다
<= 왼쪽 개체가 오른쪽 피연산자보다 작거나 같은지 확인합니다. (<= 2 3) true를 제공합니다
> 왼쪽 개체가 오른쪽 피연산자보다 큰지 확인합니다. (> 3 2) 진실을 줄 것입니다
> = 왼쪽 개체가 오른쪽 피연산자보다 크거나 같은지 확인합니다. (> = 3 2) true를 제공합니다.

논리 연산자

논리 연산자는 부울 표현식을 평가하는 데 사용됩니다. 다음은 Groovy에서 사용할 수있는 논리 연산자입니다.

예시보기

운영자 기술
and 이것은 논리 "and"연산자입니다. (또는 true true) true를 제공합니다
or 이것은 논리 "or"연산자입니다. (그리고 참 거짓) 거짓을 줄 것입니다
not 이것은 논리적 "아님"연산자입니다. (거짓이 아님) 사실을 줄 것입니다

다음 코드 스 니펫은 다양한 연산자를 사용하는 방법을 보여줍니다.

비트 연산자

Clojure는 4 개의 비트 연산자를 제공합니다. 다음은 Clojure에서 사용할 수있는 비트 연산자입니다.

예시보기

Sr. 아니. 연산자 및 설명
1

bit-and

이것은 비트 "and"연산자입니다.

2

bit-or

이것은 비트 "or"연산자입니다.

bit-xor

이것은 비트 "xor"또는 배타적 'or'연산자입니다.

4

bit-not

이것은 비트 부정 연산자입니다.

다음은 이러한 연산자를 보여주는 진리표입니다.

p & q p | 큐 피 ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

연산자 우선 순위

일반적으로 LISP의 경우와 마찬가지로 연산자 우선 순위에 대해 걱정할 필요가 없습니다. 이것은 S-Expressions와 접두사 표기법의 이점 중 하나입니다. 모든 함수는 왼쪽에서 오른쪽으로, 안쪽에서 바깥쪽으로 평가됩니다. Clojure의 연산자는 함수일 뿐이며 모든 것이 완전히 괄호로 묶여 있습니다.

지금까지 우리는 순차적으로 차례로 실행되는 명령문을 보았습니다. 또한 프로그램 논리에서 제어 흐름을 변경하기 위해 Clojure에 문이 제공됩니다. 그런 다음 자세히 살펴볼 제어문의 흐름으로 분류됩니다.

Sr. 아니. 루프 및 설명
1 While 문

그만큼 'while' 문은 먼저 조건식 (부울 값)을 평가하여 실행되고 결과가 참이면 while 루프의 문이 실행됩니다.

2 Doseq 성명

그만큼 ‘doseq’문은 다른 많은 프로그래밍 언어에서 볼 수있는 'for each'문과 유사합니다. doseq 문은 기본적으로 시퀀스를 반복하는 데 사용됩니다.

Dotimes 성명

그만큼 ‘dotimes’ 문은 'x'번 문을 실행하는 데 사용됩니다.

4 루프 문

루프 특수 형태는 ‘for’고리. 루프의 사용법은 let 바인딩과 동일합니다. 그러나 루프는 재귀 지점을 설정합니다.

Decision-making structures 프로그래머가 조건이 참인 경우 실행될 명령문 또는 명령문과 함께 프로그램이 평가하거나 테스트 할 하나 이상의 조건을 지정하고, 조건이 다음과 같은 경우 실행될 다른 명령문을 선택적으로 지정하도록 요구합니다. 거짓입니다.

Sr. 아니. 방법 및 설명
1 If 문

Clojure에서 조건은 참 또는 거짓으로 평가하는 표현식입니다. 'If' 조건이 참이면 statement # 1이 실행되고, 그렇지 않으면 statement # 2가 실행됩니다.

2 If / do 표현식

그만큼 ‘if-do’ Clojure의 식은 'if'문의 각 분기에 대해 여러 식을 실행할 수 있도록하는 데 사용됩니다.

중첩 된 If 문

배수 'if' 서로 내부에 포함 된 문.

4 사례 진술

Clojure는 ‘case’ 다음과 유사한 진술 ‘switch’ Java 프로그래밍 언어에서 사용할 수있는 명령문.

5 Cond 문

Clojure는 ‘cond’성명서. 이 문은 테스트 / 표현식 쌍 집합을 사용합니다.

Clojure는 함수형 프로그래밍 언어로 알려져 있으므로 Clojure에서 함수가 작동하는 방식에 많은 강조점을 보게 될 것입니다. 이 장에서는 Clojure의 함수로 수행 할 수있는 모든 작업을 다룹니다.

Sr. 아니. 기능 및 설명
1 함수 정의

함수는 다음을 사용하여 정의됩니다. ‘defn’ 매크로.

2 익명 함수

익명 함수는 연관된 이름이없는 함수입니다.

여러 인수가있는 함수

Clojure 함수는 0 개 이상의 매개 변수로 정의 할 수 있습니다. 함수에 전달하는 값이 호출됩니다.arguments, 인수는 모든 유형이 될 수 있습니다.

4 가변 함수

Clojure offers the ‘case’ statement which is similar to the ‘switch’ statement available in the Java programming language.

5 Higher Order Functions

Higher-order functions (HOFs) are functions that take other functions as arguments. HOFs are an important functional programming technique and are quite commonly used in Clojure.

Numbers datatype in Clojure is derived from Java classes.

Clojure supports integer and floating point numbers.

  • An integer is a value that does not include a fraction.

  • A floating-point number is a decimal value that includes a decimal fraction.

Following is an example of numbers in Clojure.

(def x 5)
(def y 5.25)

Where ‘x’ is of the type Integer and ‘y’ is the float.

In Java, the following classes are attached to the numbers defined in Clojure.

To actually see that the numbers in Clojure are derived from Java classes, use the following program to see the type of numbers assigned when using the ‘def’ command.

Example

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (def x 5)
   (def y 5.25)
   (println (type x))
   (println (type y)))
(Example)

The ‘type’ command is used to output the class associated with the value assigned to a variable.

Output

The above code will produce the following output.

Java.lang.long
Java.lang.double

Number Tests

The following test functions are available for numbers.

Sr.No. Numbers & Description
1 zero?

Returns true if the number is zero, else false.

2 pos?

Returns true if number is greater than zero, else false.

3 neg?

Returns true if number is less than zero, else false.

4 even?

Returns true if the number is even, and throws an exception if the number is not an integer.

5 odd?

Returns true if the number is odd, and throws an exception if the number is not an integer.

6 number?

Returns true if the number is really a Number.

7 integer?

Returns true if the number is an integer.

8 float?

Returns true if the number is a float.

We have seen the recur statement in an earlier topic and whereas the ‘for’ loop is somewhat like a loop, recur is a real loop in Clojure.

If you have a programming background, you may have heard of tail recursion, which is a major feature of functional languages. This recur special form is the one that implements tail recursion. As the word “tail recursion” indicates, recur must be called in the tail position. In other words, recur must be the last thing to be evaluated.

The simplest example of the recur statement is used within the ‘for’ loop. In the following example, the recur statement is used to change the value of the variable ‘i’ and feed the value of the variable back to the loop expression.

Example

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (loop [i 0]
      (when (< i 5)
      (println i)
      (recur (inc i)))))
(Example)

Output

The above program produces the following output.

0
1
2
3
4

Clojure provides a number of helper methods when working with I/O. It offers easier classes to provide the following functionalities for files.

  • Reading files
  • Writing to files
  • Seeing whether a file is a file or directory

Let’s explore some of the file operations Clojure has to offer.

Reading the Contents of a File as an Entire String

If you want to get the entire contents of the file as a string, you can use the clojure.core.slurp method. The slurp command opens a reader on a file and reads all its contents, returning a string.

Following is an example of how this can be done.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (def string1 (slurp "Example.txt"))
   (println string1))
(Example)

If the file contains the following lines, they will be printed as −

line : Example1
line : Example2

Reading the Contents of a File One Line at a Time

If you want to get the entire contents of the file as a string one line at a time, you can use the clojure.java.io/reader method. The clojure.java.io/reader class creates a reader buffer, which is used to read each line of the file.

Following is an example that shows how this can be done.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (with-open [rdr (clojure.java.io/reader "Example.txt")]
   (reduce conj [] (line-seq rdr))))
(Example)

If the file contains the following lines, they will be printed as −

line : Example1
line : Example2

The output will be shown as −

["line : Example1" "line : Example2"]

Writing ‘to’ Files

If you want to write ‘to’ files, you can use the clojure.core.spit command to spew entire strings into files. The spit command is the opposite of the slurp method. This method opens a file as a writer, writes content, then closes file.

Following is an example.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (spit "Example.txt"
      "This is a string"))

In the above example, if you see the contents of the Example.txt file , you will see the contents of “This is a string”.

Writing ‘to’ Files One Line at a Time

If you want to write ‘to’ files one line at a time, you can use the clojure.java.io.writer class. The clojure.java.io.writer class is used to create a writer stream wherein bytes of data are fed into the stream and subsequently into the file.

Following is an example that shows how the spit command can be used.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (with-open [w (clojure.java.io/writer "Example.txt" :append true)]
      (.write w (str "hello" "world"))))
(Example)

When the above code is executed, the line “hello world” will be present in the Example.txt file. The append:true option is to append data to the file. If this option is not specified, then the file will be overwritten whenever data is written to the file.

Checking to See If a File Exists

To check if a file exists, the clojure.java.io.file class can be used to check for the existence of a file. Following is an example that shows how this can be accomplished.

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (println (.exists (clojure.java.io/file "Example.txt"))))
(Example)

If the file Example.txt exists, the output will be true.

Reading from the Console

To read data from the console, the read-line statement can be used. Following is an example that shows how this can be used.

If you enter the (read-line) command in the REPL window, you will have the chance to enter some input in the console window.

user->(read-line)
Hello World

The above code will produce the following output.

“Hello World”

A String literal is constructed in Clojure by enclosing the string text in quotations. Strings in Clojure need to be constructed using the double quotation marks such as “Hello World”.

Example

Following is an example of the usage of strings in Clojure.

(ns clojure.examples.hello
   (:gen-class))
(defn hello-world []
   (println "Hello World")
   (println "This is a demo application"))
(hello-world)

Output

The above program produces the following output.

Hello World
This is a demo application

Basic String Operations

Clojure has a number of operations that can be performed on strings. Following are the operations.

Sr.No. String Operations & Description
1 str

The concatenation of strings can be done by the simple str function.

2 format

The formatting of strings can be done by the simple format function. The format function formats a string using java.lang.String.format.

3 count

Returns the number of characters in the string.

4 subs

Returns the substring of ‘s’ beginning at start inclusive, and ending at end (defaults to length of string), exclusive.

5 compare

Returns a negative number, zero, or a positive number when ‘x’ is logically 'less than', 'equal to', or 'greater than' ‘y’.

6 lower-case

Converts string to all lower-case.

7 upper-case

Converts string to all upper-case.

8 join

Returns a string of all elements in collection, as returned by (seq collection), separated by an optional separator.

9 split

Splits string on a regular expression.

10 split-lines

Split strings is based on the escape characters \n or \r\n.

11 reverse

Reverses the characters in a string.

12 replace

Replaces all instance of a match in a string with the replacement string.

13 trim

Removes whitespace from both ends of the string.

14 triml

Removes whitespace from the left hand side of the string.

15 trimr

Removes whitespace from the right hand side of the string.

List is a structure used to store a collection of data items. In Clojure, the List implements the ISeq interface. Lists are created in Clojure by using the list function.

Example

Following is an example of creating a list of numbers in Clojure.

(ns clojure.examples.example
   (:gen-class))
(defn example []
   (println (list 1 2 3 4)))
(example)

Output

The above code produces the following output.

(1 2 3 4)

Following is an example of creating a list of characters in Clojure.

(ns clojure.examples.example
   (:gen-class))
(defn example []
   (println (list 'a 'b 'c 'd)))
(example)

The above code produces the following output.

(a b c d)

Following are the list methods available in Clojure.

Sr.No. Lists & Description
1 list*

Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence.

2 first

This function returns the first item in the list.

3 nth

This function returns the item in the ‘nth’ position in the list.

4 cons

Returns a new list wherein an element is added to the beginning of the list.

5 conj

Returns a new list wherein the list is at the beginning and the elements to be appended are placed at the end.

6 rest

Returns the remaining items in the list after the first item.

Sets in Clojure are a set of unique values. Sets are created in Clojure with the help of the set command.

Example

Following is an example of the creation of sets in Clojure.

(ns clojure.examples.example
   (:gen-class))
(defn example []
   (println (set '(1 1 2 2))))
(example)

Output

The above code produces the following output.

#{1,2}

Following are the methods available in Clojure for sets.

Sr.No. Sets & Description
1 sorted-set

Returns a sorted set of elements.

2 get

Returns the element at the index position.

3 contains?

Finds out whether the set contains a certain element or not.

4 conj

Appends an element to the set and returns the new set of elements.

5 disj

Disjoins an element from the set.

6 union

Return a set that is the union of the input sets

7 difference

Return a set that is the first set without elements of the remaining sets.

8 intersection

Return a set that is the intersection of the input sets.

9 subset?

Is set1 a subset of set2?

10 superset?

Is set1 a superset of set2?

A Vector is a collection of values indexed by contiguous integers. A vector is created by using the vector method in Clojure.

Example

Following is an example of creating a vector in Clojure.

(ns clojure.examples.example
   (:require [clojure.set :as set])
   (:gen-class))
(defn example []
   (println (vector 1 2 3)))
(example)

Output

The above code produces the following output.

[1 2 3]

Following are the methods available in Clojure.

Sr.No. Vectors & Description
1 vector-of

Creates a new vector of a single primitive type ‘t’, where ‘t’ is one of :int :long :float :double :byte :short :char or :boolean.

2 nth

This function returns the item in the nth position in the vector.

3 get

Returns the element at the index position in the vector.

4 conj

Appends an element to the vector and returns the new set of vector elements.

5 pop

For a list or queue, returns a new list/queue without the first item, for a vector, returns a new vector without the last item.

6 subvec

Returns a sub vector from a starting and ending index.

A Map is a collection that maps keys to values. Two different map types are provided - hashed and sorted. HashMaps require keys that correctly support hashCode and equals. SortedMaps require keys that implement Comparable, or an instance of Comparator.

A map can be created in two ways, the first is via the hash-map method.

Creation - HashMaps

HashMaps have a typical key value relationship and is created by using hash-map function.

(ns clojure.examples.example
   (:gen-class))
(defn example []
   (def demokeys (hash-map "z" "1" "b" "2" "a" "3"))
   (println demokeys))
(example)

Output

The above code produces the following output.

{z 1, b 2, a 3}

Creation - SortedMaps

SortedMaps have the unique characteristic of sorting their elements based on the key element. Following is an example that shows how the sorted map can be created using the sorted-map function.

(ns clojure.examples.example
   (:gen-class))
(defn example []
   (def demokeys (sorted-map "z" "1" "b" "2" "a" "3"))
   (println demokeys))
(example)

The above code produces the following output.

{a 3, b 2, z 1}

From the above program you can clearly see that elements in the maps are sorted as per the key value. Following are the methods available for maps.

Sr.No. Maps & Description
1 get

Returns the value mapped to key, not-found or nil if key is not present.

2 contains?

See whether the map contains a required key.

3 find

Returns the map entry for the key.

4 keys

Returns the list of keys in the map.

5 vals

Returns the list of values in the map.

6 dissoc

Dissociates a key value entry from the map.

7 merge

Merges two maps entries into one single map entry.

8 merge-with

Returns a map that consists of the rest of the maps conj-ed onto the first.

9 select-keys

Returns a map containing only those entries in map whose key is in keys.

10 rename-keys

Renames keys in the current HashMap to the newly defined ones.

11 map-invert

Inverts the maps so that the values become the keys and vice versa.

Namespaces in Clojure are used to differentiate classes into separate logical spaces just like in Java. Consider the following statement.

(:require [clojure.set :as set])

In the above statement, ‘clojure.set’ is a namespace which contains various classes and methods to be used in the program. For example, the above namespace contains the function called map-invert, which is used to invert a map of key-values. We cannot use this function unless we explicitly tell our program to include this namespace.

Let’s look at the different methods available for namespaces.

Sr.No. Methods & Description
1 *ns*

This is used to look at your current namespace.

2 ns

This is used to create a new namespace and associate it with the running program.

3 alias

Add an alias in the current namespace to another namespace. Arguments are two symbols: the alias to be used and the symbolic name of the target namespace.

4 all-ns

Returns a list of all namespaces.

5 find-ns

Finds and returns a particular namespace.

6 ns-name

Returns the name of a particular namespace.

7 ns-aliases

Returns the aliases, which are associated with any namespaces.

8 ns-map

Returns a map of all the mappings for the namespace.

9 un-alias

Returns a map containing only those entries in map whose key is in keys.

Exception handling is required in any programming language to handle the runtime errors so that the normal flow of the application can be maintained. Exception usually disrupts the normal flow of the application, which is the reason why we need to use exception handling in our application.

Exception is broadly classified into the following categories −

  • Checked Exception − The classes that extend Throwable class except RuntimeException and Error are known as checked exceptions. E.g. IOException, SQLException, etc. Checked exceptions are checked at compile-time.

Let’s consider the following program which does an operation on a file called Example.txt. However, there can be always a case wherein the file Example.txt does not exist.

(ns clojure.examples.example
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (def string1 (slurp "Example.txt"))
   (println string1))
(Example)

If the file Example.txt does not exist, then the following exception will be generated by the program.

Caused by: java.io.FileNotFoundException: Example.txt (No such file or
directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at clojure.java.io$fn__9185.invoke(io.clj:229) at clojure.java.io$fn__9098$G__9091__9105.invoke(io.clj:69) at clojure.java.io$fn__9197.invoke(io.clj:258)
at clojure.java.io$fn__9098$G__9091__9105.invoke(io.clj:69)

위의 예외에서 우리는 프로그램이 FileNotFoundException을 발생 시켰음을 분명히 알 수 있습니다.

  • Unchecked Exception− RuntimeException을 확장하는 클래스는 확인되지 않은 예외로 알려져 있습니다. 예를 들어 ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException 등입니다. 확인되지 않은 예외는 런타임에 확인되는 것이 아니라 컴파일시 확인되지 않습니다.

한 가지 고전적인 경우는 배열 길이보다 큰 배열의 인덱스에 액세스하려고 할 때 발생하는 ArrayIndexOutOfBoundsException입니다. 다음은 이러한 종류의 실수에 대한 전형적인 예입니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (try
      (aget (int-array [1 2 3]) 5)
      (catch Exception e (println (str "caught exception: " (.toString e))))
      (finally (println "This is our final block")))
   (println "Let's move on"))
(Example)

위 코드가 실행되면 다음과 같은 예외가 발생합니다.

caught exception: java.lang.ArrayIndexOutOfBoundsException: 5
This is our final block
Let's move on

오류

오류는 복구 할 수 없습니다 (예 : OutOfMemoryError, VirtualMachineError, AssertionError 등). 이러한 오류는 프로그램이 복구 할 수 없으며 프로그램이 중단되는 원인이됩니다. 이제 이러한 예외가 존재하는 경우 프로그램이 계속 실행될 수 있도록 이러한 예외를 포착하는 메커니즘이 필요합니다.

다음 다이어그램은 Clojure의 예외 계층 구조가 어떻게 구성되는지 보여줍니다. 모두 Java에 정의 된 계층 구조를 기반으로합니다.

예외 잡기

다른 프로그래밍 언어와 마찬가지로 Clojure는 예외가 발생할 때 예외를 포착하기 위해 일반적인 'try-catch'블록을 제공합니다.

다음은 try-catch 블록의 일반 구문입니다.

(try
   (//Protected code)
   catch Exception e1)
(//Catch block)

예외를 발생시킬 수있는 모든 코드는 Protected code block.

에서 catch block, 애플리케이션이 예외에서 복구 할 수 있도록 예외를 처리하는 사용자 지정 코드를 작성할 수 있습니다.

파일을 찾을 수 없음 예외를 생성 한 이전 예제를 살펴보고 try catch 블록을 사용하여 프로그램에서 발생한 예외를 포착하는 방법을 살펴 보겠습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (try
      (def string1 (slurp "Example.txt"))
      (println string1)
      (catch Exception e (println (str "caught exception: " (.getMessage e))))))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

caught exception: Example.txt (No such file or directory)

위의 코드에서 잘못된 코드를 try block. catch 블록에서 우리는 예외를 포착하고 예외가 발생했다는 메시지를 출력합니다. 이제 프로그램에 의해 생성 된 예외를 캡처하는 의미있는 방법이 생겼습니다.

다중 캐치 블록

하나는 여러 유형의 예외를 처리하기 위해 여러 catch 블록을 가질 수 있습니다. 각 catch 블록에 대해 발생하는 예외 유형에 따라 적절하게 처리하는 코드를 작성합니다.

두 개의 catch 블록을 포함하도록 이전 코드를 수정 해 보겠습니다. 하나는 파일을 찾을 수 없음 예외를위한 것이고 다른 하나는 일반 예외 블록을위한 것입니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (try
      (def string1 (slurp "Example.txt"))
      (println string1)
      
      (catch java.io.FileNotFoundException e (println (str "caught file
         exception: " (.getMessage e))))
      
      (catch Exception e (println (str "caught exception: " (.getMessage e)))))
   (println "Let's move on"))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

caught file exception: Example.txt (No such file or directory)
Let's move on

위의 출력에서 ​​우리는 예외가 일반 블록이 아닌 'FileNotFoundException'catch 블록에 의해 포착되었음을 분명히 알 수 있습니다.

마지막으로 차단

finally 블록은 try 블록 또는 catch 블록을 따릅니다. finally 코드 블록은 예외 발생에 관계없이 항상 실행됩니다.

finally 블록을 사용하면 보호 된 코드에서 어떤 일이 발생하더라도 실행하려는 정리 유형 문을 실행할 수 있습니다. 다음은이 블록의 구문입니다.

(try
   (//Protected code)
   catch Exception e1)
(//Catch block)
(finally
   //Cleanup code)

위의 코드를 수정하고 finally 코드 블록을 추가해 보겠습니다. 다음은 코드 조각입니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (try
      (def string1 (slurp "Example.txt"))
      (println string1)
      
      (catch java.io.FileNotFoundException e (println (str "caught file
         exception: " (.getMessage e))))
      
      (catch Exception e (println (str "caught exception: " (.getMessage e))))
      (finally (println "This is our final block")))
   (println "Let's move on"))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

caught file exception: Example.txt (No such file or directory)
This is our final block
Let's move on

위의 프로그램에서 catch 블록이 필요한 예외를 포착 한 후에도 최종 블록이 구현되었음을 알 수 있습니다.

Clojure는 Java와 마찬가지로 Java에서 예외 처리를 파생하므로 Clojure에서 예외 관리를 위해 다음 메서드를 사용할 수 있습니다.

  • public String getMessage()− 발생한 예외에 대한 자세한 메시지를 반환합니다. 이 메시지는 Throwable 생성자에서 초기화됩니다.

  • public Throwable getCause() − Throwable 객체가 나타내는 예외의 원인을 반환합니다.

  • public String toString() − getMessage ()의 결과와 연결된 클래스 이름을 반환합니다.

  • public void printStackTrace() − 오류 출력 스트림 인 System.err에 스택 추적과 함께 toString ()의 결과를 인쇄합니다.

  • public StackTraceElement [] getStackTrace()− 스택 트레이스의 각 요소를 포함하는 배열을 반환합니다. 인덱스 0의 요소는 호출 스택의 맨 위를 나타내고 배열의 마지막 요소는 호출 스택의 맨 아래에있는 메서드를 나타냅니다.

  • public Throwable fillInStackTrace() −이 Throwable 객체의 스택 추적을 현재 스택 추적으로 채우고 스택 추적의 이전 정보에 추가합니다.

다음은 위에 나열된 방법 중 일부를 사용하는 예제 코드입니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (try
      (def string1 (slurp "Example.txt"))
      (println string1)
      
      (catch java.io.FileNotFoundException e (println (str "caught file
         exception: " (.toString e))))
      
      (catch Exception e (println (str "caught exception: " (.toString e))))
   (finally (println "This is our final block")))
   (println "Let's move on"))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

caught file exception: java.io.FileNotFoundException: Example.txt (No such file
or directory)
This is our final block
Let's move on

Sequences 의 도움으로 만들어집니다 ‘seq’명령. 다음은 시퀀스 생성의 간단한 예입니다.

(ns clojure.examples.example
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (println (seq [1 2 3])))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

(1 2 3)

다음은 시퀀스에 사용할 수있는 다양한 방법입니다.

Sr. 아니. 방법 및 설명
1 단점

'x'가 첫 번째 요소이고 'seq'가 나머지 요소 인 새 시퀀스를 반환합니다.

2 conj

'x'가 시퀀스 끝에 추가되는 요소 인 새 시퀀스를 반환합니다.

연결

두 시퀀스를 함께 연결하는 데 사용됩니다.

4 뚜렷한

고유 한 요소가 시퀀스에 추가되었는지 확인하는 데만 사용됩니다.

5 역전

시퀀스의 요소를 반전합니다.

6 먼저

시퀀스의 첫 번째 요소를 반환합니다.

7 마지막

시퀀스의 마지막 요소를 반환합니다.

8 쉬다

첫 번째 요소를 제외한 전체 시퀀스를 반환합니다.

9 종류

정렬 된 요소 시퀀스를 반환합니다.

10 하락

제거해야하는 요소 수에 따라 시퀀스에서 요소를 삭제합니다.

11 마지막으로

시퀀스에서 마지막 요소 목록을 가져옵니다.

12 취하다

시퀀스에서 첫 번째 요소 목록을 가져옵니다.

13 분할

항목 시퀀스를 두 부분으로 분할합니다. 분할이 발생해야하는 위치가 지정됩니다.

regular expression텍스트에서 하위 문자열을 찾는 데 사용되는 패턴입니다. 정규식은 다양한 프로그래밍 언어에서 사용되며 LISP 유형 프로그래밍 언어에서 많이 사용됩니다.

다음은 정규식의 예입니다.

//d+

위의 정규식은 문자열에서 한 번 더 숫자를 찾는 데 사용됩니다. // 문자는 'd'및 '+'문자가 정규식을 나타내는 데 사용되도록하는 데 사용됩니다.

일반적으로 정규식은 다음 규칙 세트와 함께 작동합니다.

  • 줄의 시작과 끝을 나타내는 데 사용되는 두 가지 특수 위치 문자가 있습니다. 캐럿 (∧) 및 달러 기호 ($) :

  • 정규식은 수량자를 포함 할 수도 있습니다. 더하기 기호 (+)는 표현식의 이전 요소에 적용되는 한 번 이상을 나타냅니다. 별표 (*)는 0 개 이상의 발생을 나타내는 데 사용됩니다. 물음표 (?)는 0 또는 한 번을 나타냅니다.

  • 메타 문자 {및}는 이전 문자의 특정 인스턴스 수를 일치시키는 데 사용됩니다.

  • 정규식에서 마침표 기호 (.)는 모든 문자를 나타낼 수 있습니다. 이것은 와일드 카드 문자로 설명됩니다.

  • 정규식에는 문자 클래스가 포함될 수 있습니다. 문자 집합은 [aeiou]에서와 같이 메타 문자 [and]로 묶인 간단한 문자 시퀀스로 제공 될 수 있습니다. 문자 또는 숫자 범위의 경우 [a–z] 또는 [a–mA–M]에서와 같이 대시 구분 기호를 사용할 수 있습니다. 문자 클래스의 보완은 [∧a–z]에서와 같이 대괄호 안에 선행 캐럿으로 표시되며 지정된 문자 이외의 모든 문자를 나타냅니다.

정규식에는 다음 방법을 사용할 수 있습니다.

Sr. 아니. 방법 및 설명
1 재 패턴

java.util.regex.Pattern의 인스턴스를 리턴합니다. 그런 다음 패턴 일치를위한 추가 방법에서 사용됩니다.

2 정제하다

java.util.regex.Matcher.find ()를 사용하여 패턴에 대한 문자열의 다음 정규식 일치 (있는 경우)를 반환합니다.

바꾸다

replace 함수는 문자열의 하위 문자열을 새 문자열 값으로 바꾸는 데 사용됩니다. 하위 문자열 검색은 패턴을 사용하여 수행됩니다.

4 우선 교체

replace 함수는 문자열의 하위 문자열을 새 문자열 값으로 대체하는 데 사용되지만 하위 문자열이 처음 나타나는 경우에만 사용됩니다. 하위 문자열 검색은 패턴을 사용하여 수행됩니다.

Predicates조건을 평가하고 true 또는 false 값을 제공하는 함수입니다. 우리는 숫자에 관한 장의 예에서 술어 함수를 보았습니다. '짝수?'와 같은 기능을 본 적이 있습니다. 숫자가 짝수인지 아닌지를 테스트하는 데 사용됩니다. 숫자가 0보다 큰지 여부를 테스트하는 데 사용됩니다. 이러한 모든 함수는 true 또는 false 값을 반환합니다.

다음은 Clojure의 술어 예입니다.

(ns clojure.examples.example
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (def x (even? 0))
   (println x)
   
   (def x (neg? 2))
   (println x)
   
   (def x (odd? 3))
   (println x)
   
   (def x (pos? 3))
   (println x))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

true
false
true
true

일반 술어 함수 외에도 Clojure는 술어에 대한 더 많은 함수를 제공합니다. 술어에는 다음 메소드를 사용할 수 있습니다.

Sr. 아니. 방법 및 설명
1 모든 포식자

술어 세트를 취하고 모든 구성 술어가 모든 인수에 대해 논리 true 값을 리턴하면 true를 리턴하고 그렇지 않으면 false를 리턴하는 함수 'f'를 리턴합니다.

2 마다?

조건자가 모든 값에 대해 true이면 true를 반환하고 그렇지 않으면 false를 반환합니다.

약간

값 컬렉션에서 x의 모든 술어 값에 대한 첫 번째 논리 true 값을 반환합니다.

4 아냐?

컬렉션에있는 값의 조건자가 논리적으로 참이면 거짓을 반환하고 그렇지 않으면 참을 반환합니다.

Destructuring 는 Clojure 내의 기능으로, 벡터와 같은 데이터 구조에서 값을 추출하고 데이터 구조를 명시 적으로 탐색하지 않고도 기호에 바인딩 할 수 있습니다.

정확히 Destructuring이 무엇을 의미하고 어떻게 발생하는지에 대한 예를 살펴 보겠습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def my-vector [1 2 3 4])
   (let [[a b c d] my-vector]
   (println a b c d)))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

1 2 3 4

위의 예에서 다음 사항에 유의해야합니다.

  • 정수 벡터를 1, 2, 3, 4로 정의합니다.

  • 그런 다음 우리는 ‘let’ my-vector 변수에 4 개의 변수 (a, b, c 및 d)를 직접 할당하는 명령문입니다.

  • 우리가 실행하면 ‘println’ 4 개의 변수에 대한 설명을 통해 각각 벡터의 값에 이미 할당되었음을 알 수 있습니다.

따라서 clojure는 'let'문을 사용하여 할당되었을 때 4 개의 값을 가진 my-vector 변수를 구조화했습니다. 분해 된 4 개의 값은 그에 따라 4 개의 매개 변수에 할당되었습니다.

할당 할 수있는 해당 값이없는 초과 변수가 있으면 nil 값이 할당됩니다. 다음 예는이 점을 명확히합니다.

(ns clojure.examples.hello
   (:gen-class))
(defn Example []
   (def my-vector [1 2 3 4])
   (let [[a b c d e] my-vector]
   (println a b c d e)))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다. 출력에서 마지막 변수 'e'는 벡터에 해당 값이 없으므로 nil로 간주됩니다.

산출

1 2 3 4 nil

나머지

'the-rest'변수는 어떤 변수에도 할당 할 수없는 나머지 값을 저장하는 데 사용됩니다.

이것이 어떻게 사용되는지에 대한 예가 다음 프로그램에 나와 있습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def my-vector [1 2 3 4])
   (let [[a b & the-rest] my-vector]
   (println a b the-rest)))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다. 출력에서 3과 4의 값은 어떤 변수에도 할당 될 수 없으므로 'the-rest'변수에 할당된다는 것을 분명히 알 수 있습니다.

산출

1 2 (3 4)

지도 구조 해제

벡터와 마찬가지로 맵도 분해 될 수 있습니다. 다음은이를 수행하는 방법의 예입니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def my-map {"a" 1 "b" 2})
   (let [{a "a" b "b"} my-map]
   (println a b)))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다. 프로그램에서 "a"와 "b"의 맵 값이 a와 b의 변수에 할당되어 있음을 분명히 알 수 있습니다.

산출

1 2

유사하게 벡터의 경우, 구조화가 발생할 때 맵에 해당 값이 없으면 변수에 nil 값이 할당됩니다.

다음은 그 예입니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def my-map {"a" 1 "b" 2})
   (let [{a "a" b "b" c "c"} my-map]
   (println a b c)))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

1 2 nil

Clojure 프레임 워크는 Java 클래스에서 파생되었으므로 Clojure에서 Java에서 사용할 수있는 날짜-시간 클래스를 사용할 수 있습니다. 그만큼class date 밀리 초 정밀도로 특정 순간을 나타냅니다.

다음은 날짜-시간 클래스에 사용할 수있는 메서드입니다.

java.util.Date

Clojure에서 날짜 개체를 만드는 데 사용됩니다.

통사론

다음은 구문입니다.

java.util.Date.

Parameters − 없음.

Return Value − Date 객체를 할당하고 가장 가까운 밀리 초 단위로 측정 된 할당 된 시간을 나타내도록 초기화합니다.

이것이 어떻게 사용되는지에 대한 예가 다음 프로그램에 나와 있습니다.

(ns example)
(defn Example []
   (def date (.toString (java.util.Date.)))
   (println date))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다. 이것은 프로그램이 실행되는 시스템의 현재 날짜와 시간에 따라 다릅니다.

Tue Mar 01 06:11:17 UTC 2016

java.text.SimpleDateFormat

날짜 출력 형식을 지정하는 데 사용됩니다.

통사론

다음은 구문입니다.

(java.text.SimpleDateFormat. format dt)

Parameters− '형식'은 날짜 형식을 지정할 때 사용되는 형식입니다. 'dt'는 형식화해야하는 날짜입니다.

Return Value − 형식화 된 날짜 출력.

이것이 어떻게 사용되는지에 대한 예가 다음 프로그램에 나와 있습니다.

(ns example)
(defn Example []
   (def date (.format (java.text.SimpleDateFormat. "MM/dd/yyyy") (new java.util.Date)))
   (println date))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다. 이것은 프로그램이 실행되는 시스템의 현재 날짜와 시간에 따라 다릅니다.

03/01/2016

getTime

이 Date 객체가 나타내는 1970 년 1 월 1 일 00:00:00 GMT 이후의 밀리 초 수를 반환합니다.

통사론

다음은 구문입니다.

(.getTime)

Parameters − 없음.

Return Value − 1970 년 1 월 1 일 00:00:00 GMT 이후이 날짜로 표시되는 밀리 초 수.

이것이 어떻게 사용되는지에 대한 예가 다음 프로그램에 나와 있습니다.

(ns example)
(import java.util.Date)
(defn Example []
   (def date (.getTime (java.util.Date.)))
   (println date))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다. 이것은 프로그램이 실행되는 시스템의 현재 날짜와 시간에 따라 다릅니다.

1456812778160

Atoms공유, 동기, 독립 상태를 관리하는 방법을 제공하는 Clojure의 데이터 유형입니다. 원자는 다른 프로그래밍 언어의 모든 참조 유형과 같습니다. 원자의 주요 용도는 Clojure의 불변 데이터 구조를 유지하는 것입니다. 원자가 보유한 값은swap! method.

내부적으로 스왑! 현재 값을 읽고 여기에 함수를 적용하고 비교 및 ​​설정을 시도합니다. 다른 스레드가 중간 시간에 값을 변경했을 수 있으므로 재 시도해야 할 수 있으며 스핀 루프에서 수행합니다. 순 효과는 값이 항상 원자 적으로 현재 값에 제공된 함수를 적용한 결과라는 것입니다.

원자는 원자 방법의 도움으로 생성됩니다. 동일한 예가 다음 프로그램에 표시됩니다.

(ns clojure.examples.example
   (:gen-class))
(defn example []
   (def myatom (atom 1))
   (println @myatom))
(example)

산출

위의 프로그램은 다음과 같은 결과를 생성합니다.

1

@ 기호를 사용하여 atom 값에 액세스합니다. Clojure에는 원자에 대해 수행 할 수있는 몇 가지 작업이 있습니다. 다음은 작업입니다.

Sr. 아니. 운영 및 설명
1 초기화!

현재 값에 관계없이 atom의 값을 새 값으로 설정합니다.

2 비교 및 설정!

원자의 현재 값이 원자가 보유한 이전 값과 동일한 경우에만 원자 값을 새 값으로 원자 적으로 설정합니다. 설정이 발생하면 true를 반환하고 그렇지 않으면 false를 반환합니다.

교환!

특정 기능에 따라 원자 값을 새 값으로 원자 적으로 바꿉니다.

Clojure에서 metadata컬렉션의 데이터 또는 기호에 저장된 데이터에 주석을 추가하는 데 사용됩니다. 일반적으로 유형에 대한 데이터를 기본 컴파일러에 주석 처리하는 데 사용되지만 개발자에게도 사용할 수 있습니다. 메타 데이터는 개체 값의 일부로 간주되지 않습니다. 동시에 메타 데이터는 변경할 수 없습니다.

Clojure에서는 메타 데이터와 관련하여 다음 작업이 가능합니다.

Sr. 아니. 운영 및 설명
1 메타

이 함수는 모든 개체에 대한 메타 데이터 맵을 정의하는 데 사용됩니다.

2 메타

이 함수는 메타 데이터가 개체와 연결되어 있는지 확인하는 데 사용됩니다.

다양한 메타

원본 개체와 유형 및 값이 동일하지만 메타 데이터가 결합 된 개체를 반환합니다.

StructMapsClojure에서 구조를 만드는 데 사용됩니다. 예를 들어, 직원 이름과 직원 ID로 구성된 구조를 만들려면 StructMaps를 사용하면됩니다.

Clojure에서 StructMaps와 관련하여 다음 작업이 가능합니다.

Sr. 아니. 운영 및 설명
1 defstruct

이 기능은 필요한 구조를 정의하는 데 사용됩니다.

2 구조체

이 함수는 defstruct 작업에 의해 생성되는 유형의 구조 객체를 정의하는 데 사용됩니다.

구조체 맵

이 함수는 구조의 어떤 키에 할당되는 값을 명시 적으로 정의하여 키 값에 값을 구체적으로 할당하는 데 사용됩니다.

4 개별 필드에 액세스

구조 개체와 함께 키에 액세스하여 구조의 개별 필드에 액세스 할 수 있습니다.

5 불변의 자연

기본적으로 구조도 변경 불가능하므로 특정 키의 값을 변경하려고해도 변경되지 않습니다.

6 구조에 새 키 추가

구조는 불변이므로 다른 키를 구조에 추가 할 수있는 유일한 방법은 새 구조를 만드는 것입니다. 이를 달성하는 방법에 대한 예가 다음 프로그램에 나와 있습니다.

여러 번 지적했듯이 Clojure는 많은 데이터 유형이 변경 불가능한 프로그래밍 언어입니다. 즉, 변수 값을 변경할 수있는 유일한 방법은 새 변수를 만들고 새 값을 할당하는 것입니다. 그러나 Clojure는 변경 가능한 상태를 생성 할 수있는 몇 가지 요소를 제공합니다. 이것은 atom 데이터 유형으로 달성 될 수 있음을 확인했습니다. 다른 방법은 에이전트를 사용하는 것입니다.

Agents개별 위치의 독립적 인 비동기 변경을 제공합니다. 에이전트는 수명 동안 단일 저장 위치에 바인딩되며 작업의 결과로 해당 위치의 변경 (새로운 상태로) 만 허용됩니다. 작업은 에이전트의 상태에 비동기 적으로 적용되고 반환 값이 에이전트의 새 상태가되는 함수 (선택적으로 추가 인수 포함)입니다.

에이전트와 관련하여 Clojure에서 다음 작업이 가능합니다.

Sr. 아니. 운영 및 설명
1 에이전트

agent 명령을 사용하여 에이전트를 만듭니다.

2 보내다

이 함수는 값을 통해 에이전트에 전송하는 데 사용됩니다.

종료 에이전트

이 기능은 실행중인 에이전트를 종료하는 데 사용됩니다.

4 배웅

에이전트에게 본질적으로 차단되는 기능이 할당되는 경우가 있습니다.

5 기다리다

에이전트 값이 업데이트 될 때 지연이 있기 때문에 Clojure는 에이전트가 업데이트되기를 기다리는 시간을 밀리 초 단위로 지정하는 데 사용되는 'await-for'함수를 제공했습니다.

6 기다리다

이 스레드 또는 에이전트에서 에이전트로 지금까지 전달 된 모든 작업이 발생할 때까지 현재 스레드를 무기한으로 차단합니다. 실패한 에이전트를 차단합니다.

7 에이전트 오류

에이전트가 실패한 경우 에이전트의 비동기 작업 중에 발생한 예외를 반환합니다. 에이전트가 실패하지 않으면 nil을 반환합니다.

Watchers변수 유형의 값이 변경 될 때 호출되는 원자 및 참조 변수와 같은 변수 유형에 추가되는 함수입니다. 예를 들어, 호출 프로그램이 원자 변수의 값을 변경하고 감시자 함수가 원자 변수에 첨부 된 경우 원자 값이 변경되는 즉시 함수가 호출됩니다.

Clojure for Watchers에서는 다음 기능을 사용할 수 있습니다.

추가 시계

agent / atom / var / ref 참조에 감시 기능을 추가합니다. 시계‘fn’4 개의 인수로 구성된 'fn'이어야합니다 : 키, 참조, 이전 상태, 새 상태. 참조의 상태가 변경 될 때마다 등록 된 모든 시계의 함수가 호출됩니다.

통사론

다음은 구문입니다.

(add-watch variable :watcher
   (fn [key variable-type old-state new-state]))

Parameters− '변수'는 ​​원자 또는 참조 변수의 이름입니다. '변수 유형'은 원자 또는 참조 변수의 변수 유형입니다. '이전 상태 및 새 상태'는 변수의 이전 값과 새 값을 자동으로 보유하는 매개 변수입니다. 'key'는 참조마다 고유해야하며 remove-watch로 시계를 제거하는 데 사용할 수 있습니다.

Return Value − 없음.

이것이 어떻게 사용되는지에 대한 예가 다음 프로그램에 나와 있습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def x (atom 0))
   (add-watch x :watcher
      (fn [key atom old-state new-state]
      (println "The value of the atom has been changed")
      (println "old-state" old-state)
      (println "new-state" new-state)))
(reset! x 2))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

The value of the atom has been changed
old-state 0
new-state 2

제거 시계

참조 변수에 첨부 된 시계를 제거합니다.

통사론

다음은 구문입니다.

(remove-watch variable watchname)

Parameters− '변수'는 ​​원자 또는 참조 변수의 이름입니다. 'watchname'은 시계 기능이 정의 될 때 시계에 부여되는 이름입니다.

Return Value − 없음.

이것이 어떻게 사용되는지에 대한 예가 다음 프로그램에 나와 있습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def x (atom 0))
   (add-watch x :watcher
      (fn [key atom old-state new-state]
         (println "The value of the atom has been changed")
         (println "old-state" old-state)
         (println "new-state" new-state)))
   (reset! x 2)
   (remove-watch x :watcher)
(reset! x 4))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

The value of the atom has been changed
old-state 0
new-state 2

위의 프로그램에서 두 번째 재설정 명령이 감시자 목록에서 제거 되었기 때문에 감시자를 트리거하지 않음을 분명히 알 수 있습니다.

어떤 언어로든 Macros인라인 코드를 생성하는 데 사용됩니다. Clojure도 예외는 아니며 개발자에게 간단한 매크로 기능을 제공합니다. 매크로는 코드 생성 루틴을 작성하는 데 사용되며 개발자에게 개발자의 요구에 맞게 언어를 조정할 수있는 강력한 방법을 제공합니다.

다음은 매크로에 사용할 수있는 방법입니다.

데프 매크로

이 함수는 매크로를 정의하는 데 사용됩니다. 매크로에는 매크로 이름, 매개 변수 목록 및 매크로 본문이 있습니다.

통사론

다음은 구문입니다.

(defmacro name [params*] body)

Parameters− 'name'은 매크로의 이름입니다. 'params'는 매크로에 할당 된 매개 변수입니다. 'body'는 매크로의 본문입니다.

Return Value − 없음.

이것이 어떻게 사용되는지에 대한 예가 다음 프로그램에 나와 있습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (defmacro Simple []
      (println "Hello"))
   (macroexpand '(Simple)))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

Hello

위 프로그램에서 'Simple'매크로가 'println' 'Hello'로 인라인으로 확장 된 것을 볼 수 있습니다. 매크로는 함수와 비슷하지만 매크로의 경우 양식에 대한 인수가 평가된다는 점만 다릅니다.

매크로 확장

이것은 매크로를 확장하고 프로그램에서 코드를 인라인으로 배치하는 데 사용됩니다.

통사론

다음은 구문입니다.

(macroexpand macroname)

Parameters − 'macroname'은 확장해야하는 매크로의 이름입니다.

Return Value − 확장 된 매크로.

이것이 어떻게 사용되는지에 대한 예가 다음 프로그램에 나와 있습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (defmacro Simple []
      (println "Hello"))
   (macroexpand '(Simple)))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

Hello

인수가있는 매크로

매크로를 사용하여 인수를받을 수도 있습니다. 매크로는 여러 인수를 사용할 수 있습니다. 다음 예제는 인수를 사용하는 방법을 보여줍니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (defmacro Simple [arg]
      (list 2 arg))
   (println (macroexpand '(Simple 2))))
(Example)

위의 예제는 Simple 매크로에 인수를 배치 한 다음 인수를 사용하여 목록에 인수 값을 추가합니다.

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

(2 2)

Reference valuesClojure가 가변 변수를 갖기 위해 작업 할 수있는 또 다른 방법입니다. Clojure는 원자, 에이전트 및 참조 유형과 같은 변경 가능한 데이터 유형을 제공합니다.

다음은 참조 값에 사용할 수있는 작업입니다.

Sr. 아니. 운영 및 설명
1 심판

참조 값을 생성하는 데 사용됩니다. 참조 값을 생성 할 때 생성 된 값의 유효성을 검사하는 유효성 검사 기능을 제공하는 옵션이 있습니다.

2 참조 세트

이 함수는 이전 값에 관계없이 새 값에 대한 참조 값을 설정하는 데 사용됩니다.

바꾸다

이 함수는 안전한 방식으로 참조 유형의 값을 변경하는 데 사용됩니다. 이것은 다른 프로세스에서 액세스 할 수없는 스레드에서 실행됩니다.

4 dosync

표현식 및 중첩 된 호출을 포함하는 트랜잭션에서 표현식 (암시 적 do에서)을 실행합니다.

5 갈다

Commute는 alter 및 ref-set과 마찬가지로 참조 유형의 값을 변경하는데도 사용됩니다.

데이터베이스 기능을 사용하려면 먼저 jdbc files 다음 URL에서- https://codeload.github.com/clojure/java.jdbc/zip/master

Clojure가 데이터베이스에 연결하는 데 필요한 드라이버가있는 zip 파일을 찾을 수 있습니다. zip 파일의 압축이 풀리면 압축이 풀린 위치를 클래스 경로에 추가해야합니다.

데이터베이스 연결을위한 기본 파일은 다음과 같은 파일입니다. jdbc.clj clojure / java 위치에 있습니다.

clojure jdbc 커넥터는 다음과 같은 다양한 데이터베이스를 지원합니다.

  • H2Database
  • Oracle
  • 마이크로 소프트 SQL 서버
  • MySQL
  • PostgreSQL

이 예에서는 MySQL DB를 예로 사용할 것입니다.

Clojure에서 데이터베이스와 관련하여 다음 작업이 가능합니다.

데이터베이스 연결

MySQL 데이터베이스에 연결하기 전에 다음을 확인하십시오.

  • TESTDB 데이터베이스를 만들었습니다.

  • TESTDB에 EMPLOYEE 테이블을 작성했습니다.

  • 이 테이블에는 FIRST_NAME, LAST_NAME, AGE, SEX 및 INCOME 필드가 있습니다.

  • 사용자 ID "testuser"및 비밀번호 "test123"은 TESTDB에 액세스하도록 설정됩니다.

  • 'mysql jar 파일'을 다운로드하고 파일을 클래스 경로에 추가했는지 확인하십시오.

  • MySQL 기본 사항 을 이해하기 위해 MySQL 자습서를 살펴 보았습니다 .

통사론

다음은 Clojure에서 연결을 생성하는 구문입니다.

(def connection_name {
   :subprotocol “protocol_name”
   :subname “Location of mysql DB”
   :user “username” :password “password” })

Parameters− 'connection_name'은 연결에 부여 할 이름입니다. 'subprotocol'은 연결에 사용할 프로토콜입니다. 기본적으로 mysql 프로토콜을 사용합니다. 'subname'은 데이터베이스 이름과 함께 mysql db에 연결하는 URL입니다. 'user'는 데이터베이스에 연결하는 데 사용되는 사용자 이름입니다. 'password'는 데이터베이스에 연결하는 데 사용할 암호입니다.

Return Value − 이는 후속 mysql 작업에서 사용할 수있는 연결 문자열을 제공합니다.

다음 예는 정보 스키마의 테이블에 연결하고 테이블의 모든 데이터를 검색하는 방법을 보여줍니다.

(ns test.core
   (:require [clojure.java.jdbc :as sql]))
(defn -main []
   (def mysql-db {
      :subprotocol "mysql"
      :subname "//127.0.0.1:3306/information_schema"
      :user "root"
      :password "shakinstev"})
   (println (sql/query mysql-db
      ["select table_name from tables"]
      :row-fn :table_name)))

데이터 쿼리

모든 데이터베이스에서 데이터를 쿼리하는 것은 데이터베이스에서 유용한 정보를 가져 오는 것을 의미합니다. 데이터베이스 연결이 설정되면이 데이터베이스에 쿼리를 작성할 준비가 된 것입니다. 다음은 Clojure를 사용하여 데이터를 쿼리 할 수있는 구문입니다.

통사론

clojure.java.jdbc/query dbconn
["query"]
   :row-fn :sequence

Parameters− 'dbconn'은 데이터베이스에 연결하는 데 사용되는 연결 이름입니다. 'query'는 데이터베이스에서 데이터를 가져 오는 데 사용되는 쿼리 문자열입니다. ': sequence'는 기본적으로 데이터베이스에서 가져온 데이터의 모든 행이며 시퀀스로 반환됩니다. 그런 다음 시퀀스에서 필요한 작업을 수행하여 가져온 데이터를 확인할 수 있습니다.

Return Value − 이것은 쿼리 작업의 데이터 행을 포함하는 시퀀스를 반환합니다.

다음 예는 employee 테이블에 연결하고 테이블 행의 first_name 열을 가져 오는 방법을 보여줍니다.

(ns test.core
   (:require [clojure.java.jdbc :as sql]))
(defn -main []
   (def mysql-db {
      :subprotocol "mysql"
      :subname "//127.0.0.1:3306/testdb"
      :user "root"
      :password "shakinstev"})
   (println (sql/query mysql-db
      ["select first_name from employee"]
      :row-fn :first_name)))

위의 코드에서 우리는

  • “select first_name from employee”쿼리가 쿼리 문자열로 전달됩니다.

  • : first_name은 가져 오기 작업의 결과로 반환되는 시퀀스입니다.

John의 first_name 값을 포함하는 데이터베이스에 행이 하나만 있다고 가정하면 위 프로그램의 출력은 다음과 같습니다.

(John)

데이터 삽입

데이터베이스 테이블에 레코드를 만들 때 필요합니다. 다음은 Clojure를 사용하여 데이터를 삽입 할 수있는 구문입니다. 이것은‘insert!’ 함수.

통사론

clojure.java.jdbc/insert!
   :table_name {:column_namen columnvalue}

Parameters− ': table_name'은 삽입이 필요한 테이블의 이름입니다. '{: column_namen columnvalue}'는 테이블에서 행으로 추가해야하는 모든 열 이름과 값의 맵입니다.

Return Value − 성공적으로 삽입되면 nil을 반환합니다.

다음 예제는 testdb 데이터베이스의 employee 테이블에 레코드를 삽입하는 방법을 보여줍니다.

(ns test.core
   (:require [clojure.java.jdbc :as sql]))
(defn -main []
   (def mysql-db {
      :subprotocol "mysql"
      :subname "//127.0.0.1:3306/testdb"
      :user "root"
      :password "shakinstev"})
   (sql/insert! mysql-db
      :employee {:first_name "John" :last_name "Mark" :sex "M" :age 30 :income 30}))

이제 MySQL 데이터베이스와 직원 테이블을 확인하면 위의 행이 테이블에 성공적으로 삽입되는 것을 볼 수 있습니다.

데이터 삭제

다음을 사용하여 테이블에서 행을 삭제할 수 있습니다. ‘delete!’함수. 다음은이 작업을 수행 할 수있는 방법에 대한 구문입니다.

통사론

clojure.java.jdbc/delete!
   :table_name [condition]

Parameters− ': table_name'은 삽입이 필요한 테이블의 이름입니다. '조건'은 테이블에서 삭제해야하는 행을 결정하는 데 사용되는 조건입니다.

Return Value − 삭제 된 행 수를 반환합니다.

다음 예제는 testdb 데이터베이스의 employee 테이블에서 레코드를 삭제하는 방법을 보여줍니다. 이 예에서는 연령이 30이라는 조건에 따라 테이블에서 행을 삭제합니다.

(ns test.core
   (:require [clojure.java.jdbc :as sql]))
(defn -main []
   (def mysql-db {
      :subprotocol "mysql"
      :subname "//127.0.0.1:3306/testdb"
      :user "root"
      :password "shakinstev"})
   (println (sql/delete! mysql-db
      :employee ["age = ? " 30])))

기간이 30 인 행이있는 레코드가있는 경우 해당 행이 삭제됩니다.

데이터 업데이트

행은 다음을 사용하여 테이블에서 업데이트 할 수 있습니다. ‘update!’함수. 다음은이 작업을 수행 할 수있는 방법에 대한 구문입니다.

통사론

clojure.java.jdbc/update!
   :table_name
{setcondition}
[condition]

Parameters− ': table_name'은 삽입이 필요한 테이블의 이름입니다. 'setcondition'은 맵에서 언급 한대로 업데이트해야하는 열입니다. '조건'은 테이블에서 삭제해야하는 행을 결정하는 데 사용되는 조건입니다.

Return Value − 업데이트 된 행 수를 반환합니다.

다음 예제는 testdb 데이터베이스의 employee 테이블에서 레코드를 삭제하는 방법을 보여줍니다. 이 예에서는 연령이 30 인 조건에 따라 테이블의 행을 업데이트하고 소득 값을 40으로 업데이트합니다.

(ns test.core
   (:require [clojure.java.jdbc :as sql]))
(defn -main []
   (def mysql-db {
      :subprotocol "mysql"
      :subname "//127.0.0.1:3306/testdb"
      :user "root"
      :password "shakinstev"})
   (println (sql/update! mysql-db
      :employee
      {:income 40}
      ["age = ? " 30])))

나이가 30 인 행이있는 레코드가있는 경우 해당 행이 업데이트되고 소득 값이 40으로 설정됩니다.

업무

트랜잭션은 데이터 일관성을 보장하는 메커니즘입니다. 거래에는 다음 네 가지 속성이 있습니다.

  • Atomicity − 거래가 완료되거나 아무 일도 일어나지 않습니다.

  • Consistency − 트랜잭션은 일관된 상태에서 시작하고 시스템을 일관된 상태로 유지해야합니다.

  • Isolation − 거래의 중간 결과는 현재 거래 외부에서 볼 수 없습니다.

  • Durability − 트랜잭션이 커밋되면 시스템 장애 후에도 효과가 지속됩니다.

다음 예제는 Clojure에서 트랜잭션을 구현하는 방법을 보여줍니다. 트랜잭션에서 수행해야하는 모든 작업은‘with-dbtransaction’ 절.

(ns test.core
   (:require [clojure.java.jdbc :as sql]))
(defn -main []
   (def mysql-db {
      :subprotocol "mysql"
      :subname "//127.0.0.1:3306/testdb"
      :user "root"
      :password "shakinstev"})
   (sql/with-db-transaction [t-con mysql-db]
      (sql/update! t-con
         :employee
         {:income 40}
         ["age = ? " 30])))

이미 알고 있듯이 Clojure 코드는 결국 Java 가상 환경에서 실행됩니다. 따라서 Clojure가 Java의 모든 기능을 활용할 수 있다는 것은 의미가 있습니다. 이 장에서는 Clojure와 Java의 상관 관계에 대해 설명하겠습니다.

자바 메서드 호출

점 표기법을 사용하여 Java 메서드를 호출 할 수 있습니다. 예는 문자열입니다. Clojure의 모든 문자열은 어쨌든 Java 문자열이기 때문에 문자열에서 일반 Java 메서드를 호출 할 수 있습니다.

이를 수행하는 방법에 대한 예가 다음 프로그램에 나와 있습니다.

(ns Project
   (:gen-class))
(defn Example []
   (println (.toUpperCase "Hello World")))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다. 코드에서 문자열 메서드에 대해 점 표기법을 호출하면 Clojure에서도 작동한다는 것을 알 수 있습니다.

산출

HELLO WORLD

매개 변수를 사용하여 Java 메소드 호출

매개 변수를 사용하여 Java 메소드를 호출 할 수도 있습니다. 이를 수행하는 방법에 대한 예가 다음 프로그램에 나와 있습니다.

(ns Project
   (:gen-class))
(defn Example []
   (println (.indexOf "Hello World","e")))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다. 위 코드에서 "e"매개 변수를 indexOf 메소드로 전달하고 있음을 알 수 있습니다. 위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

1

자바 객체 생성

Java에서 수행되는 것과 유사한 'new'키워드를 사용하여 Clojure에서 객체를 생성 할 수 있습니다.

이를 수행하는 방법에 대한 예가 다음 프로그램에 나와 있습니다.

(ns Project
   (:gen-class))
(defn Example []
   (def str1 (new String "Hello"))
   (println str1))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다. 위의 코드에서 'new'키워드를 사용하여 Java의 기존 String 클래스에서 새 객체를 만들 수 있음을 알 수 있습니다. Java 에서처럼 객체를 생성하는 동안 값을 전달할 수 있습니다. 위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

Hello

다음은 Integer 클래스의 개체를 만들고 일반 Clojure 명령에서 사용하는 방법을 보여주는 또 다른 예입니다.

(ns Project
   (:gen-class))
(defn Example []
   (def my-int(new Integer 1))
   (println (+ 2 my-int)))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

3

가져 오기 명령

또한 import 명령을 사용하여 클래스와 메소드에 쉽게 액세스 할 수 있도록 네임 스페이스에 Java 라이브러리를 포함 할 수 있습니다.

다음 예는 import 명령을 사용하는 방법을 보여줍니다. 이 예에서는 import 명령을 사용하여java.util.stack도서관. 그런 다음 스택 클래스의 push 및 pop 메서드를 그대로 사용할 수 있습니다.

(ns Project
   (:gen-class))
(import java.util.Stack)
(defn Example []
   (let [stack (Stack.)]
   (.push stack "First Element")
   (.push stack "Second Element")
   (println (first stack))))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

First Element

Java 명령을 사용하여 코드 실행

Clojure 코드는 Java 명령을 사용하여 실행할 수 있습니다. 다음은이를 수행하는 방법에 대한 구문입니다.

java -jar clojure-1.2.0.jar -i main.clj

모든 Clojure 기반 클래스가 JVM에로드되도록 Clojure jar 파일을 언급해야합니다. 'main.clj'파일은 실행해야하는 Clojure 코드 파일입니다.

자바 내장 함수

Clojure는 Java의 많은 내장 기능을 사용할 수 있습니다. 그들 중 일부는-

Math PI function− Clojure는 PI의 값에 대해 Math 방법을 사용할 수 있습니다. 다음은 예제 코드입니다.

(ns Project
   (:gen-class))
(defn Example []
   (println (. Math PI)))
(Example)

위의 코드는 다음 출력을 생성합니다.

산출

3.141592653589793

System Properties− Clojure는 시스템 속성을 조회 할 수도 있습니다. 다음은 예제 코드입니다.

(ns Project
   (:gen-class))
(defn Example []
   (println (.. System getProperties (get "java.version"))))
(Example)

시스템의 Java 버전에 따라 해당 값이 표시됩니다. 다음은 예제 출력입니다.

산출

1.8.0_45

Clojure 프로그래밍에서 대부분의 데이터 유형은 변경 불가능하므로 동시 프로그래밍의 경우 이러한 데이터 유형을 사용하는 코드는 코드가 여러 프로세서에서 실행될 때 매우 안전합니다. 그러나 데이터를 공유해야하는 경우가 많고 여러 프로세서에서 데이터를 공유해야하는 경우 여러 프로세서로 작업 할 때 데이터 상태가 무결성 측면에서 유지되는지 확인해야합니다. 이것은concurrent programming Clojure는 이러한 프로그래밍을 지원합니다.

dosync, ref, set, alter 등을 통해 노출되는 소프트웨어 트랜잭션 메모리 시스템 (STM)은 동기식 및 조정 된 방식으로 스레드간에 변경 상태 공유를 지원합니다. 에이전트 시스템은 비동기적이고 독립적 인 방식으로 스레드 간의 변경 상태 공유를 지원합니다. 원자 시스템은 동기적이고 독립적 인 방식으로 스레드 간의 변경 상태 공유를 지원합니다. def, binding 등을 통해 노출되는 동적 var 시스템은 스레드 내에서 상태 변경 격리를 지원합니다.

다른 프로그래밍 언어도 동시 프로그래밍 모델을 따릅니다.

  • 변경 가능한 데이터에 대한 직접적인 참조가 있습니다.

  • 공유 액세스가 필요한 경우 개체가 잠기고 값이 변경되며 해당 값에 대한 다음 액세스를 위해 프로세스가 계속됩니다.

Clojure에는 잠금이 없지만 변경 불가능한 영구 데이터 구조에 대한 간접 참조가 있습니다.

Clojure에는 세 가지 유형의 참조가 있습니다.

  • Vars − 변경 사항은 스레드에서 격리됩니다.

  • Refs − 변경 사항은 스레드간에 동기화되고 조정됩니다.

  • Agents − 스레드 간의 비동기 독립 변경을 포함합니다.

동시 프로그래밍과 관련하여 Clojure에서 다음 작업이 가능합니다.

업무

Clojure의 동시성은 트랜잭션을 기반으로합니다. 참조는 트랜잭션 내에서만 변경할 수 있습니다. 거래에는 다음과 같은 규칙이 적용됩니다.

  • 모든 변경은 원자 적이며 격리되어 있습니다.
  • 참조에 대한 모든 변경은 트랜잭션에서 발생합니다.
  • 어떤 거래도 다른 거래의 효과를 보지 못합니다.
  • 모든 트랜잭션은 dosync 블록 내부에 배치됩니다.

우리는 이미 dosync 블록이하는 일을 보았습니다. 다시 살펴 보겠습니다.

dosync

표현식 및 중첩 된 호출을 포함하는 트랜잭션에서 표현식 (암시 적 do에서)을 실행합니다. 이 스레드에서 이미 실행중인 트랜잭션이 없으면 트랜잭션을 시작합니다. 잡히지 않은 예외는 트랜잭션을 중단하고 dosync에서 흘러 나옵니다.

다음은 구문입니다.

통사론

(dosync expression)

Parameters − 'expression'은 dosync 블록에 들어올 표현식 세트입니다.

Return Value − 없음.

참조 변수의 값을 변경하는 예를 살펴 보겠습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def names (ref []))
   (alter names conj "Mark"))
(Example)

산출

위의 프로그램을 실행하면 다음과 같은 오류가 발생합니다.

Caused by: java.lang.IllegalStateException: No transaction running
   at clojure.lang.LockingTransaction.getEx(LockingTransaction.java:208)
   at clojure.lang.Ref.alter(Ref.java:173)
   at clojure.core$alter.doInvoke(core.clj:1866)
   at clojure.lang.RestFn.invoke(RestFn.java:443)
   at clojure.examples.example$Example.invoke(main.clj:5) at clojure.examples.example$eval8.invoke(main.clj:7)
   at clojure.lang.Compiler.eval(Compiler.java:5424)
   ... 12 more

오류를 통해 먼저 트랜잭션을 시작하지 않고는 참조 유형의 값을 변경할 수 없음을 분명히 알 수 있습니다.

위의 코드가 작동하려면 다음 프로그램에서 수행 한대로 dosync 블록에 alter 명령을 배치해야합니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def names (ref []))
   
   (defn change [newname]
      (dosync
         (alter names conj newname)))
   (change "John")
   (change "Mark")
   (println @names))
(Example)

위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

[John Mark]

dosync의 또 다른 예를 보겠습니다.

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def var1 (ref 10))
   (def var2 (ref 20))
   (println @var1 @var2)
   
   (defn change-value [var1 var2 newvalue]
      (dosync
         (alter var1 - newvalue)
         (alter var2 + newvalue)))
   (change-value var1 var2 20)
   (println @var1 @var2))
(Example)

위의 예에서는 dosync 블록에서 변경되는 두 개의 값이 있습니다. 트랜잭션이 성공하면 두 값이 모두 변경되고 그렇지 않으면 전체 트랜잭션이 실패합니다.

위의 프로그램은 다음과 같은 출력을 생성합니다.

산출

10 20
-10 40

Clojure에는 다음을 생성 할 수있는 일부 기고 라이브러리가 있습니다. DesktopWeb-based applications. 그들 각각에 대해 논의합시다.

Sr. 아니. 응용 프로그램 및 설명
1 데스크탑 – 시소

See-saw는 데스크톱 응용 프로그램을 만드는 데 사용할 수있는 라이브러리입니다.

2 데스크탑 – 텍스트 값 변경

창에있는 콘텐츠의 값은 ‘config!’선택권. 다음 예에서 config! 옵션은 창 내용을 "Good Bye"의 새 값으로 변경하는 데 사용됩니다.

데스크탑 – 모달 대화 상자 표시

시소 클래스의 경고 방법을 사용하여 모달 대화 상자를 표시 할 수 있습니다. 이 메서드는 모달 대화 상자에 표시되어야하는 텍스트 값을 사용합니다.

4 데스크탑 – 버튼 표시

버튼 클래스의 도움으로 버튼을 표시 할 수 있습니다.

5 데스크탑 – 레이블 표시

레이블은 레이블 클래스를 사용하여 표시 할 수 있습니다.

6 데스크탑 – 텍스트 필드 표시

텍스트 필드는 텍스트 클래스의 도움으로 표시 될 수 있습니다.

웹 애플리케이션-소개

Clojure에서 웹 애플리케이션을 만들려면 다음 링크에서 제공되는 Ring 애플리케이션 라이브러리를 사용해야합니다. https://github.com/ring-clojure/ring

사이트에서 필요한 jar를 다운로드하고이를 Clojure 애플리케이션에 대한 종속성으로 추가해야합니다.

그만큼 Ring framework 다음과 같은 기능을 제공합니다-

  • http 요청이 웹 애플리케이션에 일반 Clojure HashMap으로 들어 오도록 설정하고 마찬가지로 응답을 HashMap으로 반환 할 수 있도록 만듭니다.

  • 해당 요청 및 응답 맵의 모양을 정확히 설명하는 사양을 제공합니다.

  • 웹 서버 (Jetty)를 가져와 웹 애플리케이션을 여기에 연결합니다.

Ring 프레임 워크는 자동으로 웹 서버를 시작할 수 있으며 Clojure 애플리케이션이이 서버에서 작동하는지 확인합니다. 그런 다음 Compojure 프레임 워크를 사용할 수도 있습니다. 이를 통해 현재 대부분의 최신 웹 애플리케이션이 개발되는 경로를 만들 수 있습니다.

Creating your first Clojure application − 다음 예제는 Clojure에서 첫 번째 웹 애플리케이션을 만드는 방법을 보여줍니다.

(ns my-webapp.handler
   (:require [compojure.core :refer :all]
      [compojure.route :as route]
      [ring.middleware.defaults :refer [wrap-defaults site-defaults]]))
(defroutes app-routes
   (GET "/" [] "Hello World")
   (route/not-found "Not Found"))
(def app
   (wrap-defaults app-routes site-defaults))

프로그램의 다음 측면을 살펴 보겠습니다.

  • 그만큼 ‘defroutes’ 다른 경로에 대한 웹 애플리케이션에 대한 요청이 Clojure 애플리케이션의 다른 기능으로 전달 될 수 있도록 경로를 생성하는 데 사용됩니다.

  • 위의 예에서 "/"는 기본 경로로 알려져 있으므로 웹 애플리케이션의베이스를 탐색 할 때 문자열 "Hello World"가 웹 브라우저로 전송됩니다.

  • 사용자가 Clojure 애플리케이션에서 처리 할 수없는 URL을 입력하면 "Not Found"라는 문자열이 표시됩니다.

Clojure 응용 프로그램을 실행할 때 기본적으로 응용 프로그램은 localhost : 3000으로로드되므로이 위치를 찾아 보면 다음 출력이 표시됩니다.

웹 애플리케이션 – 웹 애플리케이션에 더 많은 경로 추가

웹 애플리케이션에 더 많은 경로를 추가 할 수도 있습니다. 다음 예제는이를 달성하는 방법을 보여줍니다.

(ns my-webapp.handler
   (:require [compojure.core :refer :all]
      [compojure.route :as route]
      [ring.middleware.defaults :refer [wrap-defaults site-defaults]]))
(defroutes app-routes
   (GET "/" [] "Hello World")
   (GET "/Tutorial" [] "This is a tutorial on Clojure")
   (route/not-found "Not Found"))
(def app
   (wrap-defaults app-routes site-defaults))

응용 프로그램에 경로를 추가하는 것은 url 경로와 함께 다른 GET 함수를 추가하는 것만 큼 쉽습니다. (GET "/ Tutorial"[] "이것은 Clojure에 대한 튜토리얼입니다")

위치를 탐색하는 경우 http://localhost:3000/Tutorial, 다음 출력을 받게됩니다.

이 장에서는 Clojure에서 제공하는 자동 테스트 옵션에 대해 설명하겠습니다.

클라이언트 애플리케이션 테스트

Clojure 프레임 워크에 대한 테스트를 사용하려면 다음 위치에있는 종속성을 사용해야합니다. https://github.com/slagyr/speclj#manual-installation

이 URL은 specljFramework는 Clojure의 테스트 데이터 기반 또는 동작 기반 테스트 프레임 워크로 사용됩니다. 'speclj'라이브러리를 사용할 때 Clojure 1.7.0 프레임 워크를 사용하는지 확인해야합니다. 기본적으로 테스트 파일은 Clojure 코드 파일과 다르며 'spec'디렉토리에 배치해야합니다.

다음은 테스트 파일의 샘플 코드입니다.

(ns change.core-spec
   (:require [speclj.core :refer :all]))
(describe "Truth"
   (it "is true"
   (should true))
   (it "is not false"
   (should-not false)))
(run-specs)

위의 코드에 대해 다음 사항에 유의해야합니다.

  • 먼저 'speclj'프레임 워크의 모든 핵심 라이브러리를 포함하기 위해 'require'문을 사용해야합니다.

  • 다음은 '설명'기능입니다. 생성되는 테스트 케이스에 대한 설명을 제공하는 데 사용됩니다.

  • 다음 기능은 실제 테스트 케이스 인 'it'기능입니다. 첫 번째 테스트 케이스에서 "is true"문자열은 테스트 케이스에 지정된 이름입니다.

  • 해야 할 것과하지 말아야 할 것 assertions. 모든 주장은 should로 시작합니다. 해야 할 것과하지 말아야 할 것은 사용 가능한 많은 주장 중 두 가지입니다. 둘 다 진위와 허위를 각각 확인하는 표현을 사용합니다.

테스트 케이스를 실행하면 다음 출력이 표시됩니다. 출력은 테스트 케이스를 실행하는 데 걸린 시간 (밀리 초)을 표시합니다.

←[32m.←[0m←[32m.←[0m
Finished in 0.00014 seconds

웹 기반 응용 프로그램 테스트

Selenium현대 웹 기반 애플리케이션을 테스트하는 데 사용되는 주요 프레임 워크 중 하나입니다. 웹 기반 애플리케이션을 테스트하는 데 사용할 수있는 Clojure 라이브러리도 사용할 수 있습니다.

Clojure 웹 기반 애플리케이션을 테스트하기 위해 Selenium 라이브러리를 사용하는 방법을 살펴 보겠습니다.

Step 1− 첫 번째 단계는 테스트가 필요한 웹 기반 애플리케이션을 생성하기 위해 Ring 및 Compojure 프레임 워크를 사용하고 있는지 확인하는 것입니다. 이전 장의 예 중 하나를 사용하겠습니다. 다음 코드는 브라우저에 "Hello World"를 표시하는 간단한 웹 애플리케이션입니다.

(ns my-webapp.handler
   (:require [compojure.core :refer :all]
      [compojure.route :as route]
      [ring.middleware.defaults :refer [wrap-defaults site-defaults]]))
(defroutes app-routes
   (GET "/" [] "Hello World")
   (route/not-found "Not Found"))
(def app
   (wrap-defaults app-routes site-defaults))

Step 2 − 다음으로 셀레늄 jar 파일을 다운로드하십시오. https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-server/2.47.0 클래스 경로에 포함하십시오.

Step 3 − 또한 다음 위치에서 웹 테스트를 실행하는 데 사용될 'clj'웹 드라이버를 다운로드하십시오.

https://clojars.org/clj-webdriver/versions/0.7.1

Step 4 − 프로젝트 디렉토리에서 features라는 다른 디렉토리를 생성하고 'config.clj'라는 파일을 생성합니다.

Step 5 − 다음으로 이전 단계에서 생성 한 'config.clj'파일에 다음 코드를 추가합니다.

ns clj-webdriver-tutorial.features.config)
(def test-port 3000)
(def test-host "localhost")
(def test-base-url (str "http://" test-host ":" test-port "/"))

위의 코드는 기본적으로 웹 테스트 프레임 워크에 URL에로드되는 애플리케이션을 테스트하도록 지시합니다. http://localhost:3000

Step 6 − 마지막으로 테스트를 수행하기위한 코드를 작성해 보겠습니다.

(ns clj-webdriver-tutorial.features.homepage
   (:require [clojure.test :refer :all]
      [ring.adapter.jetty :refer [run-jetty]]
      [clj-webdriver.taxi :refer :all]
      [clj-webdriver-tutorial.features.config :refer :all]
      [clj-webdriver-tutorial.handler :refer [app-routes]]))
(ns clj-webdriver-tutorial.features.homepage
   (:require [clojure.test :refer :all]
      [ring.adapter.jetty :refer [run-jetty]]
      [clj-webdriver.taxi :refer :all]
      [clj-webdriver-tutorial.features.config :refer :all]
      [clj-webdriver-tutorial.handler :refer [app-routes]]))
(defn start-server []
   (loop [server (run-jetty app-routes {:port test-port, :join? false})]
      (if (.isStarted server)
         server
         (recur server))))
(defn stop-server [server]
   (.stop server))
(defn start-browser []
   (set-driver! {:browser :firefox}))
(defn stop-browser []
   (quit))
(deftest homepage-greeting
   (let [server (start-server)]
      (start-browser)
      (to test-base-url)
      (is (= (text "body") "Hello World"))
      (stop-browser)
      (stop-server server)))

위의 코드는 다음과 같은 조치를 취할 것입니다.

  • 애플리케이션의 서버를 시작하십시오.
  • 브라우저에서 루트 경로를 엽니 다.
  • 페이지에 "Hello World"메시지가 있는지 확인하십시오.
  • 브라우저를 닫습니다.
  • 서버를 종료하십시오.

Clojure 라이브러리를 강력하게 만드는 한 가지는 Clojure 프레임 워크에 사용할 수있는 라이브러리의 수입니다. 웹 테스트, 웹 개발, 스윙 기반 애플리케이션 개발, MySQL 데이터베이스에 연결하기위한 jdbc 라이브러리를 위해 이전 예제에서 사용 된 많은 라이브러리를 이미 보았습니다. 다음은 몇 가지 추가 라이브러리의 몇 가지 예입니다.

data.xml

이 라이브러리를 사용하면 Clojure가 XML 데이터로 작업 할 수 있습니다. 사용할 라이브러리 버전은 org.clojure / data.xml "0.0.8"입니다. data.xml은 XML 구문 분석 및 방출을 지원합니다. 구문 분석 함수는 Reader 또는 InputStream에서 XML을 읽습니다.

다음은 문자열에서 XML로 데이터를 처리하는 예입니다.

(ns clojure.examples.example
   (use 'clojure.data.xml)
   (:gen-class))
(defn Example []
   (let [input-xml (java.io.StringReader. "<?xml version = \"1.0\"
      encoding = \"UTF-8\"?><example><clo><Tutorial>The Tutorial
      value</Tutorial></clo></example>")]
      (parse input-xml)))

#clojure.data.xml.Element{
   :tag :example, :attrs {}, :content (#clojure.data.xml.Element {
      :tag :clo, :attrs {}, :content (#clojure.data.xml.Element {
         :tag :Tutorial, :attrs {},:content ("The Tutorial value")})})}
(Example)

data.json

이 라이브러리를 사용하면 Clojure가 JSON 데이터로 작업 할 수 있습니다. 사용할 라이브러리 버전은 org.clojure / data.json "0.2.6"입니다.

다음은이 라이브러리 사용에 대한 예입니다.

(ns clojure.examples.example
   (:require [clojure.data.json :as json])
   (:gen-class))
(defn Example []
   (println (json/write-str {:a 1 :b 2})))
(Example)

산출

위의 프로그램은 다음과 같은 출력을 생성합니다.

{\"a\":1,\"b\":2}

data.csv

이 라이브러리는 Clojure가 ‘csv’데이터. 사용할 라이브러리 버전은 org.clojure / data.csv "0.1.3"입니다.

다음은이 라이브러리 사용에 대한 예입니다.

(ns clojure.examples.example
   (require '[clojure.data.csv :as csv]
      '[clojure.java.io :as io])
   (:gen-class))
(defn Example []
   (with-open [in-file (io/reader "in-file.csv")]
      (doall
      (csv/read-csv in-file)))
   (with-open [out-file (io/writer "out-file.csv")]
   (csv/write-csv out-file
      [[":A" "a"]
      [":B" "b"]])))
(Example)

위 코드에서 'csv'함수는 먼저 in-file.csv모든 데이터를 변수 파일에 넣습니다. 다음으로 write-csv 함수를 사용하여 모든 데이터를out-file.csv.