Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

واجهة error

جزء من قسم البرمجة كائنية التوجه في رحلة GO على Coddy. الدرس 52 من 107.

في Go، تتم معالجة الأخطاء من خلال واجهة مضمّنة تُسمّى error. هذه الواجهة بسيطة بشكل ملحوظ. وهي تتطلب طريقة واحدة فقط:

type error interface {
    Error() string
}

أي نوع ينفّذ طريقة Error() تُرجع سلسلة نصية يحقّق تلقائيًا واجهة error. هذا هو نظام الواجهات في Go أثناء العمل: لا حاجة إلى تصريح صريح.

الطريقة الأكثر شيوعًا لإنشاء الأخطاء هي استخدام حزمة errors:

import "errors"

func Divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("cannot divide by zero")
    }
    return a / b, nil
}

تعيد دوال Go عادةً قيمة error كآخر قيمة مُعادة. عند عدم حدوث error، تعيد nil. ثم يتحقق المستدعي مما إذا كانت قيمة error غير nil قبل المتابعة:

result, err := Divide(10, 0)
if err != nil {
    fmt.Println("Error:", err.Error())
    return
}
fmt.Println("Result:", result)

يمكنك أيضًا استخدام fmt.Errorf لإنشاء رسائل خطأ منسَّقة:

func GetUser(id int) (string, error) {
    if id <= 0 {
        return "", fmt.Errorf("invalid user id: %d", id)
    }
    return "Alice", nil
}

يُعدّ هذا النمط المتمثل في إرجاع الأخطاء بدلاً من إطلاق الاستثناءات أمرًا أساسيًا في Go. فهو يجعل معالجة الأخطاء واضحة وصريحة، ويجبرك على التفكير فيما يحدث عندما تسوء الأمور: وهو جانب أساسي من كتابة تعليمات برمجية قوية وموجّهة للكائنات.

challenge icon

التحدي

سهل

لنَبْنِ نظام حساب مصرفي يوضّح نمط معالجة الأخطاء في Go. ستنشئ حسابًا بسيطًا يتحقق من العمليات ويُرجع أخطاءً ذات معنى عند حدوث مشكلات.

ستنظّم التعليمات البرمجية عبر ملفين:

  • account.go: أنشئ بنية BankAccount تحتوي على حقل Owner مُصدَّر (string) وحقل balance غير مُصدَّر (float64). نفّذ ما يلي:
    • NewBankAccount(owner string, initialDeposit float64) (*BankAccount, error) - مُنشئ يُرجع خطأً بالرسالة "initial deposit must be positive" إذا كان الإيداع الأولي يساوي صفرًا أو سالبًا. وإلا، أنشئ الحساب وأعِده.
    • Deposit(amount float64) error - يضيف الأموال إلى الرصيد. أرجع خطأً بالرسالة "deposit amount must be positive" إذا كان المبلغ يساوي صفرًا أو سالبًا.
    • Withdraw(amount float64) error - يزيل الأموال من الرصيد. أرجع خطأً بالرسالة "withdrawal amount must be positive" إذا كان المبلغ يساوي صفرًا أو سالبًا، أو "insufficient funds" إذا كان الرصيد أقل من مبلغ السحب.
    • Balance() float64 - يُرجع الرصيد الحالي
  • main.go: اقرأ تفاصيل الحساب ومبالغ المعاملات من الإدخال. حاول إنشاء حساب وتنفيذ العمليات. بعد كل عملية، اطبع إما رسالة النجاح أو رسالة الخطأ.

سيتم توفير المدخلات التالية:

  • السطر 1: اسم المالك
  • السطر 2: مبلغ الإيداع الأولي
  • السطر 3: مبلغ الإيداع
  • السطر 4: مبلغ السحب

لكل عملية، اطبع النتيجة:

  • بعد إنشاء الحساب: Account created for [Owner] with balance: $[balance] أو Error: [error message]
  • بعد الإيداع: Deposited successfully. New balance: $[balance] أو Error: [error message]
  • بعد السحب: Withdrew successfully. New balance: $[balance] أو Error: [error message]

نسّق جميع قيم الرصيد باستخدام منزلتين عشريتين. إذا فشل إنشاء الحساب، فتخطَّ العمليات المتبقية.

على سبيل المثال، عند إعطاء Alice و100 و50 و200، يجب أن يكون الناتج:

Account created for Alice with balance: $100.00
Deposited successfully. New balance: $150.00
Error: insufficient funds

وعند إعطاء Bob و-50 و25 و10، يجب أن يكون الناتج:

Error: initial deposit must be positive

جرّب بنفسك

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// اقرأ اسم المالك
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)

	// Read initial deposit
	initialDepositStr, _ := reader.ReadString('\n')
	initialDeposit, _ := strconv.ParseFloat(strings.TrimSpace(initialDepositStr), 64)

	// Read deposit amount
	depositStr, _ := reader.ReadString('\n')
	depositAmount, _ := strconv.ParseFloat(strings.TrimSpace(depositStr), 64)

	// Read withdrawal amount
	withdrawStr, _ := reader.ReadString('\n')
	withdrawAmount, _ := strconv.ParseFloat(strings.TrimSpace(withdrawStr), 64)

	// TODO: أنشئ حساب بنكي جديد باستخدام NewBankAccount
	// إذا كان هناك خطأ، اطبع "Error: [error message]" وأعد
	// إذا نجح، اطبع "Account created for [Owner] with balance: $[balance]"

	// TODO: حاول إيداع مبلغ الإيداع
	// إذا كان هناك خطأ، اطبع "Error: [error message]"
	// If successful, print "Deposited successfully. New balance: $[balance]"

	// TODO: حاول سحب مبلغ السحب
	// إذا كان هناك خطأ، اطبع "Error: [error message]"
	// If successful, print "Withdrew successfully. New balance: $[balance]"

	// تذكر تنسيق قيم الرصيد بخانتين عشريتين باستخدام fmt.Printf("%.2f", balance)

	_ = ownerName
	_ = initialDeposit
	_ = depositAmount
	_ = withdrawAmount
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Go عبر الإنترنت