العمل مع YAML في Go (Golang) — مكتبة gopkg.in/yaml.v3
\n\nYAML (YAML Ain't Markup Language) هو تنسيق شائع لتسلسل البيانات، يُستخدم غالبًا لملفات التكوين، وصف API (OpenAPI/Swagger)، خطوط أنابيب CI/CD (GitLab CI, GitHub Actions) و Docker Compose. في نظام Go (Golang) البيئي، لا توجد مكتبة قياسية للعمل مع YAML، لذلك يستخدم المطورون مكتبة طرف ثالث قوية ومستقرة gopkg.in/yaml.v3. في هذه المقالة، سنشرح بالتفصيل كيفية قراءة وكتابة ومعالجة YAML في Go.
تثبيت المكتبة
\nللبدء، أضف الحزمة إلى مشروعك:
\ngo get gopkg.in/yaml.v3\nبعد ذلك، قم باستيرادها في الكود:
\nimport "gopkg.in/yaml.v3"\n\nالهياكل الأساسية للعمل مع YAML
\nتدعم مكتبة yaml.v3 ما يلي:
- \n
- التسلسل (Marshal) — تحويل هياكل Go إلى سلسلة YAML. \n
- إلغاء التسلسل (Unmarshal) — تحليل سلسلة YAML إلى هيكل Go. \n
- التحليل التدفقي (Decoder/Encoder) للعمل مع الملفات. \n
- الوسوم
yaml:"fieldname"لتخصيص أسماء الحقول. \n
مثال 1: قراءة YAML من سلسلة نصية
\nأبسط حالة هي تحليل سلسلة YAML إلى هيكل Go:
\npackage main\n\nimport (\n "fmt"\n "gopkg.in/yaml.v3"\n)\n\ntype Config struct {\n Server struct {\n Port int `yaml:"port"`\n Host string `yaml:"host"`\n } `yaml:"server"`\n Database struct {\n User string `yaml:"user"`\n Pass string `yaml:"pass"`\n } `yaml:"database"`\n}\n\nfunc main() {\n yamlData := `\nserver:\n port: 8080\n host: "localhost"\ndatabase:\n user: "admin"\n pass: "secret"\n`\n var cfg Config\n err := yaml.Unmarshal([]byte(yamlData), &cfg)\n if err != nil {\n panic(err)\n }\n fmt.Printf("الخادم: %s:%d\\n", cfg.Server.Host, cfg.Server.Port)\n fmt.Printf("قاعدة البيانات: %s\\n", cfg.Database.User)\n}\n\nمثال 2: كتابة YAML إلى ملف
\nلكتابة البيانات إلى ملف YAML، استخدم yaml.Marshal والكتابة إلى نظام الملفات:
package main\n\nimport (\n "os"\n "gopkg.in/yaml.v3"\n)\n\ntype AppConfig struct {\n Name string `yaml:"name"`\n Version string `yaml:"version"`\n Debug bool `yaml:"debug"`\n}\n\nfunc main() {\n config := AppConfig{\n Name: "MyApp",\n Version: "1.0.0",\n Debug: true,\n }\n\n data, err := yaml.Marshal(&config)\n if err != nil {\n panic(err)\n }\n\n err = os.WriteFile("config.yaml", data, 0644)\n if err != nil {\n panic(err)\n }\n println("تم إنشاء الملف config.yaml")\n}\n\nمثال 3: العمل مع الهياكل المتداخلة والمعقدة
\nيدعم YAML القوائم، هياكل الخرائط (map) والتداخل العميق. إليك مثال لتحليل قائمة من الخوادم:
\npackage main\n\nimport (\n "fmt"\n "gopkg.in/yaml.v3"\n)\n\ntype Service struct {\n Name string `yaml:"name"`\n Ports []int `yaml:"ports"`\n Enabled bool `yaml:"enabled"`\n}\n\ntype Deployment struct {\n Version string `yaml:"version"`\n Services []Service `yaml:"services"`\n}\n\nfunc main() {\n input := `\nversion: "2.1"\nservices:\n - name: web\n ports: [80, 443]\n enabled: true\n - name: api\n ports: [3000]\n enabled: false\n`\n var dep Deployment\n if err := yaml.Unmarshal([]byte(input), &dep); err != nil {\n panic(err)\n }\n\n for _, s := range dep.Services {\n fmt.Printf("الخدمة %s: المنافذ %v، نشطة: %t\\n", s.Name, s.Ports, s.Enabled)\n }\n}\n\nالقراءة والكتابة التدفقية (Decoder/Encoder)
\nللعمل مع الملفات الكبيرة أو تدفقات البيانات، استخدم yaml.Decoder و yaml.Encoder:
package main\n\nimport (\n "