"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > تقديم Do Notation في حزمة Mo لـ Golang

تقديم Do Notation في حزمة Mo لـ Golang

تم النشر بتاريخ 2024-08-15
تصفح:360

Introducing Do Notation in the Mo Package for Golang

ما هو هل التدوين؟

تدوين Do هو عبارة عن سكر نحوي يستخدم بشكل أساسي في لغات البرمجة الوظيفية مثل Haskell وScala. إنه يبسط تسلسل العمليات الأحادية، مما يجعل التعليمات البرمجية أكثر قابلية للقراءة والصيانة. من خلال جلب هذه الميزة إلى Go، يمكننا الآن كتابة تعليمات برمجية أكثر وضوحًا وتعبيرًا عند العمل مع monads.

لماذا التدوين؟

عند التعامل مع الأحاديات، خاصة في منطق الأعمال المعقد، يمكن أن تصبح عمليات التسلسل مرهقة. غالبًا ما تؤدي معالجة الأخطاء وإدارة الحالات المختلفة إلى هياكل متداخلة للغاية يصعب متابعتها. يعالج تدوين Do هذا الأمر من خلال السماح لنا بكتابة العمليات الأحادية بأسلوب تسلسلي، على غرار البرمجة الأمرية، ولكن مع جميع فوائد البرمجة الوظيفية.

كيف تعمل في حزمة Mo؟

في Go، لم يكن تنفيذ تدوين do أمرًا سهلاً، لكنني تمكنت من تحقيقه باستخدام الدالة Do. فيما يلي نظرة سريعة على كيفية استخدامه مع مثال:

package main

import (
    "errors"
    "fmt"
    "github.com/samber/mo"
)

func validateBooking(params map[string]string) mo.Result[map[string]string] {
    if params["guest"] != "" && params["roomType"] != "" {
        return mo.Ok(params)
    }
    return mo.Err[map[string]string](errors.New("validation failed"))
}

func createBooking(guest string) mo.Result[string] {
    if guest != "" {
        return mo.Ok("Booking Created for: "   guest)
    }
    return mo.Err[string](errors.New("booking creation failed"))
}

func assignRoom(booking string, roomType string) mo.Result[string] {
    if roomType != "" {
        return mo.Ok("Room Assigned: "   roomType   " for "   booking)
    }
    return mo.Err[string](errors.New("room assignment failed"))
}

// This could be a service package that performs the entire process
func bookRoom(params map[string]string) mo.Result[[]string] {
    return mo.Do(func() []string {
        // Validate booking parameters
        values := validateBooking(params).MustGet()

        // Create booking
        booking := createBooking(values["guest"]).MustGet()

        // Assign room
        room := assignRoom(booking, values["roomType"]).MustGet()

        // Return success with booking and room details
        return []string{booking, room}
    })
}

func main() {
    params := map[string]string{
        "guest":   "Foo",
        "roomType": "Suite",
    }

    result := bookRoom(params)
    if result.IsError() {
        fmt.Println("Error:", result.Error())
    } else {
        fmt.Println("Success:", result.MustGet())
    }
}

في هذا المثال، يستخدم bookRoom الوظيفة Do لإجراء عدة عمليات بشكل تسلسلي: التحقق من صحة معلمات الحجز وإنشاء حجز وتعيين غرفة. تُرجع كل خطوة نتيجة يمكن ربطها بسلاسة باستخدام وظيفة Do، مما يضمن معالجة الأخطاء بشكل واضح وقابل للقراءة.

مقارنة وظيفة غرفة الكتب

بدون تدوين

يمكنك الحصول على خيارين:

1. استخدام الربط (إذا تم تنفيذه):
يمكن أن تشبه عملية "الربط" في الوحدات الأحادية جحيم رد الاتصال عندما يكون هناك العديد من العمليات الأحادية بسبب الطبيعة المتداخلة والمتسلسلة لهذه العمليات. عندما يتم ربط العديد من هذه العمليات معًا، يمكن أن تصبح التعليمات البرمجية متداخلة بعمق وتصعب قراءتها، على غرار عمليات الاسترجاعات المتداخلة بعمق في البرمجة غير المتزامنة. إذا تم تنفيذ bind في حزمة Mo، فإن استخدامه في هذا المثال سيبدو كما يلي:

func bookRoom(params map[string]string) mo.Result[[]string] {
    return bind(validateBooking(params), func(values map[string]string) mo.Result[[]string] {
        return bind(createBooking(values["guest"]), func(booking string) mo.Result[[]string] {
            return bind(assignRoom(booking, values["roomType"]), func(room string) mo.Result[[]string] {
                return mo.Ok([]string{booking, room})
            })
        })
    })
}

سرعان ما يصبح هذا النهج صعب القراءة والصيانة.

2. باستخدام .Get():
هناك خيار آخر وهو استخدام .Get() على الموناد لفك الموناد والحصول على القيمة والخطأ الأساسيين. يبدو هذا كرمز Go النموذجي، لكن معالجة الأخطاء يمكن أن تكون مطولة:

func bookRoom(params map[string]string) mo.Result[[]string] {
    values, err := validateBooking(params).Get()
    if err != nil {
        return mo.Err[[]string](err)
    }

    booking, err := createBooking(values["guest"]).Get()
    if err != nil {
        return mo.Err[[]string](err)
    }

    room, err := assignRoom(booking, values["roomType"]).Get()
    if err != nil {
        return mo.Err[[]string](err)
    }

    return mo.Ok([]string{booking, room})
}

هذا الأسلوب أكثر قابلية للقراءة من استخدام الربط، ولكنه لا يزال يتضمن الكثير من معالجة الأخطاء المعيارية.

مع تدوين الفعل

باستخدام علامة do، يمكنك الاتصال بـ .MustGet() على الوحدة الأحادية للحصول على القيمة الأساسية مباشرة دون أخطاء. ستصاب هذه الوظيفة (MustGet()) بالذعر إذا كان هناك خطأ في الموناد؛ ومع ذلك، فإن التدوين سوف يتعامل مع ذلك ويختصر التنفيذ إذا كان هناك خطأ أو يعيد القيمة غير المغلفة مرة أخرى:

func bookRoom(params map[string]string) mo.Result[[]string] {
    return mo.Do(func() []string {
        values := validateBooking(params).MustGet()
        booking := createBooking(values["guest"]).MustGet()
        room := assignRoom(booking, values["roomType"]).MustGet()
        return []string{booking, room}
    })
}

هذا الأسلوب واضح وموجز وسهل القراءة، مما يقلل بشكل كبير من التعليمات البرمجية الشائعة لمعالجة الأخطاء.


الأفكار النهائية

إحدى المزايا الرائعة لاستخدام تدوين do هو أنك لا تحتاج إلى التحقق من الأخطاء بعد كل عملية أحادية. على الرغم من أن الموناد يمكن أن يحتوي على نوع خطأ، إلا أن تدوين الفعل سيتعامل تلقائيًا مع انتشار الخطأ ويقصر دائرة التنفيذ في حالة حدوث خطأ. يؤدي هذا إلى تعليمات برمجية أكثر وضوحًا وقابلية للصيانة، وهو أمر ذو قيمة خاصة في سير العمل المعقد.

بيان الافراج تم إعادة إنتاج هذه المقالة على: https://dev.to/taman9333/introducing-do-notation-in-the-mo-package-for-golang-1jpc?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3