Menu
CoddyTech

מיוצא לעומת לא מיוצא

חלק מהיחידה לוגיקה וזרימת התוכנית במסלול ה-GO של Coddy. שיעור 52 מתוך 68.

ב-Go, הנראות של מזהים (משתנים, פונקציות, טיפוסים וכו׳) נקבעת לפי מוסכמת שמות פשוטה. היא קובעת אם קוד מחבילות אחרות יכול לגשת למזהים שלך.

מזהים מיוצאים מתחילים באות גדולה ונגישים מחבילות אחרות. אפשר לחשוב עליהם כעל ״ציבוריים״ — כל מי שמייבא את החבילה שלך יכול להשתמש בהם.

// אלה מיוצאים (ציבוריים)
var Name string
func Calculate() int
type Person struct

מזהים שאינם מיוצאים מתחילים באות קטנה ונגישים רק בתוך אותה חבילה. הם "פרטיים" לחבילה שלך.

// אלה אינם מיוצאים (פרטיים)
var age int
func helper() string
type config struct

מוסכמת השמות הזאת היא הדרך של Go לשלוט בגישה בלי להזדקק למילות מפתח כמו public או private. כשתנסה להשתמש במזהה לא מיוצא מחבילה אחרת, Go תציג שגיאת קומפילציה, משום שהמזהה הזה אינו גלוי מחוץ לחבילה שלו.

challenge icon

אתגר

קל

תקן את בעיות החשיפה בחבילת Go על ידי תיקון מוסכמת השמות של מזהים מיוצאים ולא מיוצאים. תעבוד עם תרחיש מדומה של כמה חבילות, שבו חלק מהמזהים קיבלו שמות שגויים, מה שגורם לשגיאות הידור כאשר מנסים לגשת אליהם מחבילות אחרות.

תקבל שני קלטים:

  • מחרוזת שמכילה הגדרות של חבילות בפורמט "package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1" (לדוגמה, "utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public")
  • מחרוזת שמכילה ניסיונות גישה בפורמט "accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3" (לדוגמה, "main.helper,main.Calculate,utils.Version")

המשימה שלך היא:

  1. לנתח את הקלט הראשון על ידי פיצול לפי קווים אנכיים כדי לקבל הגדרות נפרדות של חבילות
  2. עבור כל הגדרת חבילה, לפצל לפי נקודתיים כדי לקבל את שם החבילה ואת המזהים שלה
  3. עבור כל הגדרת מזהה, לפצל לפי נקודתיים כדי לקבל את שם המזהה, את הסוג ואת החשיפה המיועדת
  4. ליצור פונקציה בשם fixIdentifierName שמקבלת שם של מזהה ואת החשיפה המיועדת, ומחזירה את השם המתוקן:
    • אם החשיפה היא "public", לוודא שהמזהה מתחיל באות גדולה
    • אם החשיפה היא "private", לוודא שהמזהה מתחיל באות קטנה
  5. להציג את כותרת ניתוח החבילות: "=== PACKAGE VISIBILITY ANALYSIS ==="
  6. עבור כל חבילה, להציג את פרטי החבילה:
    • "Package: [package_name]"
    • עבור כל מזהה בחבילה:
      • אם צריך לתקן את שם המזהה: "- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])"
      • אם שם המזהה תקין: "- [identifier_name] ([type]) (visibility: [visibility]) ✓"
    • לנתח את הקלט השני על ידי פיצול לפי פסיקים כדי לקבל ניסיונות גישה נפרדים
    • עבור כל ניסיון גישה, לפצל לפי נקודות כדי לקבל את החבילה שמנסה לגשת ואת המזהה שאליו ניגשים
    • להציג את כותרת אימות הגישה: "=== ACCESS VALIDATION ==="
    • עבור כל ניסיון גישה, לקבוע אם הגישה תקינה:
      • למצוא את החבילה שמכילה את המזהה
      • לבדוק אם שם המזהה המתוקן מתחיל באות גדולה (מיוצא)
      • אם המזהה מיוצא: "[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)"
      • אם המזהה אינו מיוצא: "[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)"
      • אם המזהה לא קיים: "[accessing_package] accessing unknown.[identifier_name]: ✗ NOT FOUND" (להדפיס את המילה unknown כשם החבילה; ניסיון זה נספר כגישה שנדחתה)
    • לספור ולהציג את נתוני הסיכום:
      • "=== SUMMARY ==="
      • "Total packages analyzed: [number_of_packages]"
      • "Total identifiers processed: [total_number_of_identifiers]"
      • "Identifiers requiring fixes: [number_of_identifiers_that_needed_fixing]"
      • "Access attempts: [number_of_access_attempts]"
      • "Allowed accesses: [number_of_allowed_accesses]"
      • "Denied accesses: [number_of_denied_accesses]"
    • להציג את ההמלצות הסופיות:
      • אם היו מזהים שנדרש לתקן: "Recommendation: Fix identifier naming to follow Go conventions"
      • אם כל המזהים היו תקינים: "All identifiers follow proper Go naming conventions"

יש להשתמש בחבילת strings כדי לפצל את מחרוזות הקלט, בחבילת fmt עבור פלט מעוצב, ובפונקציות לעיבוד מחרוזות כדי לבדוק ולשנות שמות של מזהים. האתגר הזה מדגים כיצד מוסכמת השמות של Go קובעת את החשיפה של חבילות ועוזר לך להבין את ההבדל בין מזהים מיוצאים למזהים שאינם מיוצאים.

נסו בעצמכם

package main

import (
	"fmt"
	"strings"
)

func main() {
	// קרא את הקלט
	var packageDefinitions string
	var accessAttempts string
	fmt.Scanln(&packageDefinitions)
	fmt.Scanln(&accessAttempts)

	// TODO: כתוב את הקוד שלך למטה
	
	// צור את הפונקציה fixIdentifierName
	
	// נתח את הגדרות החבילות
	
	// הצג את ניתוח החבילות
	
	// נתח את ניסיונות הגישה
	
	// הצג את אימות הגישה
	
	// חשב והצג נתונים סטטיסטיים מסכמים
	
	// הצג המלצות
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה לוגיקה וזרימת התוכנית

תרגלו בעצמכם: קומפיילר Go אונליין