DSL in Go: Wie Sie eine domänenspezifische Sprache für reale Aufgaben erstellen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

DSL in Go: Verwandeln Sie Ihren Code in eine neue Sprache



Stellen Sie sich vor, Sie schreiben ein System zur Auftragsverarbeitung. Jeden Tag bitten Manager: „Fügen Sie 10% Rabatt für alle Kunden aus Moskau hinzu, aber nur, wenn der Bestellwert über 5000 liegt.“ Sie gehen in den Code, ändern if-else, testen, deployen. Eine Woche später – eine neue Anfrage: „15% Rabatt für VIP, wenn mehr als drei Artikel vorhanden sind.“ Kommt Ihnen bekannt vor?



Was wäre, wenn Manager diese Regeln selbst schreiben könnten? Ohne Ihr Zutun. Ohne Risiko, die Produktion zu beschädigen. Genau dafür gibt es domänenspezifische Sprachen (DSL) – kompakte Sprachen, die auf eine bestimmte Aufgabe zugeschnitten sind. Und Go eignet sich mit seiner Einfachheit und Leistungsfähigkeit ideal für die Erstellung solcher DSL.



In diesem Artikel werden wir uns ansehen, wie man DSL in Go erstellt – von einfachen eingebetteten Lösungen bis hin zu vollwertigen externen Parsern. Sie erfahren, wie Sie Routineaufgaben automatisieren und Ihren Benutzern ein Werkzeug geben, das sie ohne Programmierkenntnisse verstehen.



Was ist ein DSL und warum wird es in Go benötigt?



DSL (Domain-Specific Language) ist eine Programmiersprache, die für einen engen Bereich entwickelt wurde. Im Gegensatz zu universellen Sprachen (Go, Python, Java) löst ein DSL eine einzige Aufgabe, tut dies aber elegant.



Beispiele aus der Praxis:

  • SQL – DSL für die Arbeit mit Datenbanken.
  • Regex – DSL für die Mustersuche in Texten.
  • HTML – DSL für die Auszeichnung von Webseiten.


In Go werden DSL verwendet für:

  • Konfiguration – statt YAML/JSON kann man Logik in einer eigenen Sprache schreiben.
  • Geschäftsregeln – Analysten die Möglichkeit geben, Logik ohne Programmierer zu ändern.
  • Testen – Szenarien in lesbarer Form beschreiben.
  • Datenverarbeitung – Transformations-Pipelines erstellen.


Go wurde nicht zufällig gewählt: Sein Compiler ist schnell, die Syntax prägnant und die integrierten Werkzeuge (z. B. text/scanner oder go/ast) vereinfachen das Parsen. Aber das Wichtigste ist, dass Go sowohl interne DSL (in die Syntax von Go selbst eingebettet) als auch externe DSL (mit eigener Syntax und eigenem Parser) ermöglicht.



Interne DSL in Go: Nutzung der Sprachsyntax



Interne DSL sind Bibliotheken, die wie eine separate Sprache aussehen, aber die Syntax von Go verwenden. Sie erfordern kein Schreiben eines Parsers: Sie schreiben einfach Funktionen, die zu Aufrufketten „verknüpft“ werden.



Beispiel: DSL für Rabattregeln



Angenommen, wir möchten, dass die Regeln so aussehen:



discount := Rule("VIP Rabatt").    When(City("Moskau")).    When(OrderSum > 5000).    Apply(Discount(10))


Wie setzt man das in Go um? Wir verwenden das Builder-Muster und Funktionen höherer Ordnung:



package main

import "fmt"

// Rule - Struktur der Regeltype Rule struct { Name string Checks []func(order map[string]interface{}) bool Discount int}

// When fügt eine Bedingung hinzufunc (r *Rule) When(check func(order map[string]interface{}) bool) *Rule { r.Checks = append(r.Checks, check) return r}

// Apply legt den Rabatt festfunc (r *Rule) Apply(discount int) *Rule { r.Discount = discount return r}

// Evaluate prüft, ob die Bestellung passtfunc (r *Rule) Evaluate(order map[string]interface{}) bool { for _, check := range r.Checks { if !check(order) { return false } } return true}

// Hilfsfunktionen für Bedingungenfunc City(city string) func(map[string]interface{}) bool { return func(order map[string]interface{}) bool { return order["city"] == city }}

func OrderSum(order map[string]interface{}) int { return order["sum"].(int)}

// Überladung des Operators > durch Closurefunc GreaterThan(a func(map[string]interface{}) int, b

Blogs

Buchempfehlungen