1. परिचय

Expr एक डायनामिक कॉन्फ़िगरेशन सॉल्यूशन है जो गो भाषा के लिए डिज़ाइन की गई है, जिसे इसकी सरल सिन्टेक्स और शक्तिशाली प्रदर्शन की विशेषता के लिए जाना जाता है। Expr व्यंजन इंजन का मूल फोकस सुरक्षा, गति, और सहजता पर है, जो इसे उपयुक्त बनाता है जैसे पहुंच नियंत्रण, डेटा फ़िल्टरिंग, और संसाधन प्रबंधन जैसे परिदृश्यों के लिए। जब गो में लागू किया जाता है, तो Expr ऐप्लिकेशन को डायनामिक नियमों को संभालने की क्षमता को बढ़ाता है। अन्य भाषाओं में अनुप्रेताओं या स्क्रिप्ट इंजन की तरह, Expr स्थिर प्रकार की जाँच संचालन के लिए और बाइटकोड उत्पन्न करने के लिए अपना साहित्य करता है, जिससे प्रदर्शन और सुरक्षा दोनों सुनिश्चित होती है।

2. Expr की इंस्टॉलेशन

आप गो भाषा के पैकेज प्रबंधन उपकरण go get का उपयोग करके Expr व्यंजन इंजन को इंस्टॉल कर सकते हैं:

go get github.com/expr-lang/expr

यह कमांड Expr लाइब्रेरी फ़ाइलें डाउनलोड करेगी और उन्हें आपके गो प्रोजेक्ट में इंस्टॉल कर देगी, जिससे आप अपने गो कोड में Expr को आयात और उपयोग कर सकते हैं।

3. तेज़ शुरू

3.1 मूल अभिव्यक्तियों का कंपाइल और प्रारंभ करना

चलो एक मूल उदाहरण के साथ शुरू करते हैं: एक साधारण अभिव्यक्ति लिखना, इसे कंपाइल करना, और फिर उसे परिणाम प्राप्त करने के लिए चलाना।

package main

import (
	"fmt"
	"github.com/expr-lang/expr"
)

func main() {
	// एक मूल जोड़ने वाली अभिव्यक्ति को कंपाइल करना
	कार्यक्रम, त्रुटि := expr.Compile(`2 + 2`)
	यदि त्रुटि != nil {
		panic(त्रुटि)
	}

	// संकलित अभिव्यक्ति को चलाना बिना किसी पर्यावरण को पास करते हुए, क्योंकि यहाँ कोई चर आवश्यक नहीं है
	नतीजा, त्रुटि := expr.Run(कार्यक्रम, nil)
	यदि त्रुटि != nil {
		panic(त्रुटि)
	}

	// परिणाम प्रिंट करना
	fmt.Println(नतीजा)  // 4 को आउटपुट करता है
}

इस उदाहरण में, अभिव्यक्ति 2 + 2 को कॉम्पाइल करके कार्यात्मक बाइटकोड में बदलता है, जिसे तो परिणाम प्राप्त करने के लिए चलाया जाता है।

3.2 परिवर्तनीय अभिव्यक्तियों का उपयोग

अगले, हम एक पर्यावरण बनाएंगे जिसमें मान शामिल होते हैं, वार्ता करेंगे जो इन मानों का उपयोग करती है, इस अभिव्यक्ति को कंपाइल और चलाया जाएगा।

package main

import (
	"fmt"
	"github.com/expr-lang/expr"
)

func main() {
	// मान से भरा एक पर्यावरण बनाना
	env := map[string]interface{}{
		"foo": 100,
		"bar": 200,
	}

	// पर्यावरण के लिए चरों का उपयोग करने वाला अभिव्यक्ति को कंपाइल करना
	कार्यक्रम, त्रुटि := expr.Compile(`foo + bar`, expr.Env(env))
	यदि त्रुटि != nil {
		panic(त्रुटि)
	}

	Printing the result
	fmt.Println(output)  // Outputs 300
}

इस उदाहरण में, पर्यावरण env में foo और bar मान होते हैं। अभिव्यक्ति foo + bar कंपाइल करता है और यहाँ दुर्व्यासना करता है कि क्या चर और बार के प्रकार पर्यावरण संकलन के दौरान, और यह चलने के समय में इन मानों का उपयोग करता है इसका परिणाम प्राप्त करने के लिए।

4. विस्तृत में Expr व्याकरण

4.1 चरों और शारीरिक

Expr व्याकरण व्यंजन सामान्य डेटा प्रकार शारीरिक, स्ट्रिंग, और बूलियन मान शामिल कर सकता है। अभिव्यक्तियाँ डेटा मान होती हैं, जैसे 42, "hello", और true

संख्याएँ

Expr में, आप सीधे पूर्णांकों और फ्लोटिंग पॉइंट संख्याएँ लिख सकते हैं:

42      // पूर्णांक 42 को प्रस्तुत करता है
3.14    // फ्लोटिंग पॉइंट संख्या 3.14 को प्रस्तुत करता है

स्ट्रिंग

स्ट्रिंग शारीरिक को डबल कोट्स " या बैकट `` में बंधा जाता है। उदाहरण के लिए:

"हैलो, वर्ल्ड" // डबल कोट्स में बंधा हुआ स्ट्रिंग, भागों का समर्थन
`हैलो, वर्ल्ड` // बैकट में बंधा हुआ स्ट्रिंग, स्ट्रिंग स्वरूप के समर्थन के बिना

बूलियन

केवल दो बूलियन मान हैं, true और false, जो तर्कसंगत सच और गलत को प्रस्तुत करते हैं:

true   // बूलियन सच्चाई की मूल्य
false  // बूलियन गलती की मूल्य
#### अंकगणितीय और तार्किक ऑपरेटर

अंकगणितीय ऑपरेटर में जोड़ना (`+`), घटाना (`-`), गुणा करना (`*`), भाग करना (`/`), और शेष (`%`) शामिल है। तार्किक ऑपरेटर में तार्किक AND (`&&`), तार्किक OR (`||`), और तार्किक NOT (`!`) शामिल हैं, उदाहरण के लिए:

```go
2 + 2 // परिणाम 4 है
7 % 3 // परिणाम 1 है
!true // परिणाम false है
age >= 18 && name == "Alice" // यहां जांचें कि आयु 18 से कम नहीं है और नाम "Alice" के बराबर है

तुलना ऑपरेटर

तुलना ऑपरेटर में बराबर (==), बराबर नहीं (!=), से कम (<), से कम या बराबर (<=), से अधिक (>), और से अधिक या बराबर (>=) शामिल हैं, दो मानों की तुलना करने के लिए:

age == 25 // यहां जांचें कि आयु 25 के बराबर है
age != 18 // यहां जांचें कि आयु 18 के बराबर नहीं है
age > 20  // यहां जांचें कि आयु 20 से अधिक है

सेट ऑपरेटर

Expr में कुछ सेट के साथ काम करने के लिए ऑपरेटर भी हैं, जैसे in जो यह जांचने के लिए है कि कोई तत्व सेट में है या नहीं। सेट्स एरे, स्लाइस, या मैप्स हो सकते हैं:

"user" in ["user", "admin"]  // true, क्योंकि "user" एरे में है
3 in {1: true, 2: false}     // false, क्योंकि 3 मैप में कुंजी नहीं है

उन्हें कुछ उन्नत सेट ऑपरेशन कार्य भी हैं, जैसे all, any, one, और none, जिन्हें अनामित फ़ंक्शन (लैम्बडा) का उपयोग करना आवश्यक होता है।

all(tweets, {.Len <= 240})  // सभी ट्वीट की लेन फ़ील्ड 240 से अधिक नहीं होती है, यहां जांचें
any(tweets, {.Len > 200})   // क्या ट्वीट में ऐसी जगह है जहां लेन फ़ील्ड 200 से अधिक होती है, यहां जांचें

सदस्य ऑपरेटर

Expr व्यंग्य भाषा में, सदस्य ऑपरेटर हमें गो भाषा के struct की गुणधर्मों तक पहुँचने की अनुमति देता है। यह सुविधा Expr को संविकृत डेटा संरचनाओं को सीधे हैंडल करने की अनुमति देती है, जिससे यह बहुत ही लचीला और व्यावहारिक होता है।

सदस्य ऑपरेटर का उपयोग करना बहुत ही सरल है, बस गुणधर्म के नाम के बाद . ऑपरेटर का प्रयोग करें। उदाहरण के लिए, अगर हमारे पास निम्नलिखित struct है:

type User struct {
    Name string
    Age  int
}

तो आप User संरचना की Name गुणधर्म का पहुँच करने के लिए निम्नलिखित अभिव्यक्ति लिख सकते हैं:

env := map[string]interface{}{
    "user": User{Name: "Alice", Age: 25},
}

code := `user.Name`

program, err := expr.Compile(code, expr.Env(env))
if err != nil {
    panic(err)
}

output, err := expr.Run(program, env)
if err != nil {
    panic(err)
}

fmt.Println(output) // Output: Alice

nil मानों के संबंध में व्यवस्था

गुणधर्मों के पहुंच करने पर, आपको स्थितियों का सामना करना पड़ सकता है जहां ऑब्जेक्ट nil हो। Expr सुरक्षित प्रॉपर्टी पहुंच प्रदान करता है, ताकि यदि संरचना या घनीभूत प्रॉपर्टी nil हो, तो यह एक रनटाइम पैनिक त्रुटि नहीं फैलाएगा।

संपत्ति को संदर्भित करने के लिए ?. ऑपरेटर का उपयोग करें। यदि ऑब्जेक्ट nil है, तो यह त्रुटि फैलाने की बजाय nil लौटाएगा।

author.User?.Name

समकक्ष अभिव्यक्ति

author.User != nil ? author.User.Name : nil

?? ऑपरेटर का उपयोग मुख्य रूप से डिफ़ॉल्ट मान लौटाने के लिए होता है:

author.User?.Name ?? "Anonymous"

समकक्ष अभिव्यक्ति

author.User != nil ? author.User.Name : "Anonymous"

पाइप ऑपरेटर

Expr में पाइप ऑपरेटर (|) का उपयोग एक अभिव्यक्ति के परिणाम को एक अन्य अभिव्यक्ति के पैरामीटर के रूप में पास करने के लिए किया जाता है। यह यूनिक्स शैली में पाइप कार्य के साथ समान है, जिससे कई कार्यात्मक मॉड्यूलों को एक प्रसंस्करण पाइपलाइन बनाने के लिए जोड़ा जा सकता है। Expr में इसका उपयोग करके व्याख्यान को और भी स्पष्ट और संक्षेपित बनाया जा सकता है।

उदाहरण के तौर पर, अगर हमारे पास एक उपयोगकर्ता का नाम प्राप्त करने के लिए और एक वेलकम संदेश के लिए एक फ़ंक्शन होता है:

env := map[string]interface{}{
    "user":      User{Name: "Bob", Age: 30},
    "get_name":  func(u User) string { return u.Name },
    "greet_msg": "Hello, %s!",
}

code := `get_name(user) | sprintf(greet_msg)`

program, err := expr.Compile(code, expr.Env(env))
if err != nil {
    panic(err)
}

output, err := expr.Run(program, env)
if err != nil {
    panic(err)
}

fmt.Println(output) // आउटपुट: Hello, Bob!

इस उदाहरण में, हम पहले get_name(user) के माध्यम से उपयोगकर्ता का नाम प्राप्त करते हैं, फिर इस नाम को sprintf फ़ंक्शन को पास करते हैं जिसके लिए हमने पाइप ऑपरेटर | का उपयोग किया है ताकि अंतिम वेलकम संदेश बना सके।

पाइप ऑपरेटर का उपयोग हमारे कोड को मॉड्यूलरिज़ कर सकता है, कोड की पुन:उपयोगिता में सुधार कर सकता है, और अभिव्यक्तियों को और पढ़ने योग्य बना सकता है।

4.3 फ़ंक्शन

Expr निर्मित फ़ंक्शनों और कस्टम फ़ंक्शनों का समर्थन करता है, जिससे अभिव्यक्तियों को शक्तिशाली और लचीला बनाया जा सकता है।

निर्मित फ़ंक्शनों का उपयोग

len, all, none, any आदि जैसे निर्मित फ़ंक्शनों का सीधा उपयोग अभिव्यक्ति में किया जा सकता है।

// निर्मित फ़ंक्शन का उपयोग का उदाहरण
program, err := expr.Compile(`all(users, {.Age >= 18})`, expr.Env(env))
if err != nil {
    panic(err)
}

// ध्यान दें: यहां env में users वेरिएबल होना चाहिए, और प्रत्येक उपयोगकर्ता के पास आयु संपत्ति होनी चाहिए
output, err := expr.Run(program, env)
fmt.Print(output) // अगर env में सभी उपयोगकर्ता 18 वर्ष या अधिक हैं, तो यह true लौटाएगा

कस्टम फ़ंक्शन को परिभाषित और उपयोग करना

Expr में, आप परिवर्तनियों पर निर्देशिका मैपिंग में फ़ंक्शन परिभाषाएँ पारित करके कस्टम फ़ंक्शन बना सकते हैं।

// कस्टम फ़ंक्शन का उदाहरण
env := map[string]interface{}{
    "greet": func(name string) string {
        return fmt.Sprintf("Hello, %s!", name)
    },
}

program, err := expr.Compile(`greet("World")`, expr.Env(env))
if err != nil {
    panic(err)
}

output, err := expr.Run(program, env)
fmt.Print(output) // यह Hello, World! लौटाएगा!

Expr में फ़ंक्शनों का उपयोग करते समय, आप अपने कोड को मॉड्यूलराइज़ कर सकते हैं और अभिव्यक्तियों में जटिल तर्क को शामिल कर सकते हैं। चरणों, ऑपरेटरों, और फ़ंक्शनों को मिलाकर, Expr एक शक्तिशाली और सरल उपकरण बन जाता है। हमेशा याद रखें कि Expr परिवेश और अभिव्यक्तियों को चलाने के समय प्रकार सुरक्षा को सुनिश्चित करें।

5. निर्मित फ़ंक्शन दस्तावेज़ीकरण

Expr अभिव्यक्ति इंजन डेवलपरों को विभिन्न जटिल स्थितियों को संभालने के लिए विभिन्न निर्मित फ़ंक्शनों के साथ एक बहुमूल्य सेट प्रदान करता है। नीचे, हम इन निर्मित फ़ंक्शनों और उनके उपयोग का विस्तार से वर्णन करेंगे।

all

all फ़ंक्शन का उपयोग किसी संग्रह में सभी तत्वों को दिए गए शर्त को पूरा करते हैं की जांचने के लिए किया जा सकता है। इसमें दो पैरामीटर लेता है: संग्रह और शर्त अभिव्यक्ति।

// सभी ट्वीट्स का जाँच करना जिनकी सामग्री की लंबाई 240 से कम है
code := `all(tweets, len(.Content) < 240)`

any

all के समान, any फ़ंक्शन का उपयोग किसी संग्रह में किसी भी तत्व को किसी शर्त को पूरा करते हैं की जांचने के लिए किया जा सकता है।

// जाँच करना कि क्या किसी भी ट्वीट की सामग्री की लंबाई 240 से अधिक है
code := `any(tweets, len(.Content) > 240)`

none

none फ़ंक्शन का उपयोग किसी संग्रह में कोई तत्व उन विशेष शर्त को पूरा नहीं करता है की जांचने के लिए किया जाता है।

// सुनिश्चित करना कि कोई भी ट्वीट दोहराया नहीं गया है
code := `none(tweets, .IsRepeated)`

one

one फ़ंक्शन का उपयोग किसी संग्रह में केवल एक तत्व एक विशेष शर्त को पूरा करता है की जांचने के लिए किया जाता है।

// जाँच करना कि क्या केवल एक ट्वीट में एक विशिष्ट शब्द है
code := `one(tweets, contains(.Content, "keyword"))`

filter

filter फ़ंक्शन एक दिए गए शर्त को पूरा करने वाले संग्रह तत्वों को फ़िल्टर कर सकता है।

// सभी ट्वीट्स को प्राथमिकता मार्क करने वाले तत्व फ़िल्टर करना
code := `filter(tweets, .IsPriority)`

map

map फ़ंक्शन एक संग्रह में तत्वों को एक निर्दिष्ट विधि के अनुसार परिवर्तित करने के लिए उपयोग किया जाता है।

// सभी ट्वीटों की प्रकाशन समय को स्वरूपित करना
code := `map(tweets, {.PublishTime: Format(.Date)})`

len

len फ़ंक्शन का उपयोग संग्रह या स्ट्रिंग की लंबाई वापस करने के लिए किया जाता है।

// उपयोगकर्ता नाम की लंबाई प्राप्त करना
code := `len(username)`

contains

contains फ़ंक्शन का उपयोग करने से पता चलता है कि कोई स्ट्रिंग एक सबस्ट्रिंग को या कोई संग्रह एक विशिष्ट तत्व को शामिल करता है या नहीं।

// यहाँ देखते हैं कि उपयोगकर्ता नाम में अवैध वर्ण हैं या नहीं
code := `contains(username, "illegal characters")`

ऊपर दिए गए उदाहरण में केवल, Expr व्यंजन इंजन द्वारा प्रदान की गई स्थापित फ़ंक्शनों का एक हिस्सा है। इन शक्तिशाली फ़ंक्शनों के साथ, आप डेटा और तर्क को और लचीलापूर्वक और दक्षतापूर्वक संभाल सकते हैं। अधिक विस्तृत फ़ंक्शनों और उपयोग निर्देशों के लिए, कृपया आधिकारिक Expr विवरण का संदर्भ लें।