top of page

מבוא לשפת סוויפט - swift


סוויפט שפה חדשה של אפל, המתפתחת ומשתנה כל הזמן בקצר מהיר (לקראת יציאת סוויפט 2),

כעת לאחר שהיא כבר יצאה בצורה רשמית ומחליפה את השפה הקודמת אובג'קטיב סי (objective c), אם כי חלק מהיכולות עדיין תלוי בשפה הקודמת ועובר התאמה לשפה החדשה.

נסקור בקצרה את התחביר שלה

כל משתנה חייב להתחיל בהצהרה var, או let במידה וזה משתנה קבוע - משתנה שערכו לא ניתן לשינוי (משפט אשר נשמע לא סותר את עצמו .. אבל הכוונה מובנת).

הטיפוסים הבסיסיים בשפה זו הם:

מספר שלם - Int

מספר ממשי (עד 6 ספרות אחרי הנקודה) - Float

מספר ממשי (64 ביט) - Double

בולאני - Bool

תו בודד (טבלת יוניקוד) - Character

מחרוזת - String

מערך - Array

מילון (מערך אסוציאטיבי) - Dictionary

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

לדוגמה:

var name:String

name="israel"

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

לדוגמה:

var name="israel"

ואז אין אפשרות לשנות את ערכו לערך מספרי או בולאני,

כי הטיפוס שלו כבר נקבע להיות משתנה מסוג מחרוזת.

מחלקה מופשטת, הנקראת ממשק (interface) בשפות אחרות, בשפה זו נקראת פרוטוקול (Protocol).

זוהי מחלקה אשר אינה נותנת מימוש לשיטות (מתודות) שלה, אלא מציינת איזה שיטות ישנם.

אח"כ תגיע מחלקה אשר תירש ממנה ותממש אותם בהתאם לצרכים שלה.

יצירת מחלקה, כרגיל בשפות אחרות, נעשית על ידי המילה: class Car

על מנת ליצור ממה אובייקט, אין צורך במילה new, אלא נרשום:

var c = Car()

מבנה (Struct), בדיוק כמו מחלקה, ההבדל ביניהם שאובייקט של מבנה משכפל את עצמו בכל העתקה למשתנה אחר (value type), בדומה להעתקה מערך אשר כל שינוי במערך הראשון לא ישפיע על המערך השני שהוא מערך אחר לחלוטין שמחזיק כרגע אותם ערכים.

לעומת מחלקה אשר כל אובייקט המיוצר ממנה, במידה והוא מועתק למשתנה נוסף, מוחזק ההפנייה אל אותו אובייקט ראשוני (reference type), כי הוא בעצם מצביע על אותו אובייקט (כמו קיצור דרך לקובץ במחשב, שבלחיצה עליו נפתח אותו קובץ המקורי עליו יערכו כל השינויים שנבצע, בשונה מהעתקת קובץ).

על מנת להעביר משתנה ביי רפרנס (כי לפונקציה עובר רק הערך), נשתמש בסימן אמפרסנד בשליחה לפונקציה ומילה inout בתחילת הפונקציה:

y(&x);

func y(inout x:Int){

num=100;

}

במקרה הפוך, על מנת לוודע שהערך שאנחנו שמים במשתנה, יהיה רק לעותק היחיד הזה (לא ביי רפרנס), נרשום קודם פונקציה הבאה (אשר גורמת לו להיות עותק):

y.unshare

על מנת לאתחל מחלקה, נשתמש בבנאי הנקרא: init.

אפשר להעמיס אתחולים, זאת אומרת ליצור כמה סוגי אתחולים,

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

על מנת לרשת ממחלקה אחרת נשתמש בסימון נקודתיים: class Car:Bus

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

דוגמה:

extension Car{

func fast() { }

}

פונקציה נוצרת על ידי שימוש במילה fanc.

על מנת לומר שהפונציה מחזירה ערך, נשתמש בסימן חץ (<-).

דוגמה:

fanc fast() -> int { return 100 }

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

דוגמה לפונקציה שמקבלת כמות בלתי ידועה של פרמטרים מסוג כלשהו:

func car(nums:Int...)->Int{

var sum=0;

for n in nums{

sum+=n;

}

return sum;

}

var cars = car(1,2,3,4);

חשוב לדעת שבשפה זו (בשונה משפות אחרות כגון ג'אווה), הפרמטר של הפונקציה הוא קבוע (let) ואין אפשרות לשנותו בתוך הפונקציה, אלא אם קבענו שהוא משתנה רגיל על ידי המילה var.

דוגמה:

func car(var model:String){

model="I am" + model; // change value

println(model);

}

car("Volvo"); // prints I am Volvo

יש אופציה מיוחדת להקצות לפרמטר שם פנימי (לשימוש בפונקציה) ושם חיצוני (לשימוש בקריאה לפונקציה).

דוגמה בסיסית:

//defaults parameter

func car(model:String="Volvo"){

println("car \(model)");

}

car(model: "Honda"); //prints car Honda

car(); //prints car Volvo

דוגמה לשם חיצוני מותאם (על מנת שהקריאה לפונקציה תהיה ברורה יותר לנו):

func car(carModel model:String){

println(model);

}

car(carModel: "Volvo"); //prints Volvo

דוגמה לשם חיצוני ופנימי שהם אותו דבר, ניתן לקצר בשימוש סימן סולמית(#):

func car(#model:String){

println(model);

}

car(model:"Volvo"); //prints Volvo

תפל (tuple), הוא אובייקט המכיל מספר משתנים או ערכים, כמו מן מערך מיוחד, היכול להכיל סדרת ערכים מכמה טיפוסים שונים.

דוגמה:

var car = (100,"red");

println(car.0);

מערכים:

var cars:[Int]=[];

cars.append(90); // add

cars.removeLast(); // delete last

cars.count; // length of array

cars.insert(88, atIndex: 0); //asdd at

cars.removeAtIndex(2); //delete at

//inline declaration + initialization

var cars:[String]=["Mitsubishi ","Honda ","Mercedes","Peugeot","Porsche "];

// type(Int), size(3), values(1)

var threeOnes=[Int](count: 3, repeatedValue: 1);

מילונים:

var names:[String:Int]=["Israel":25,"David":31];

usersScores["Michael"]=45;

println(names);

// or iterate each keys & values

for (k,v) in names{

println(" \(k) has \(v)");

}

סוויפט היא שפה מהפכנית:

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

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

דוגמה:

if n1<n2{

println("n1 little");

}

2.

אם בתנאי מתג (swich) בשפות אחרות, אחרי כל מקרה (case) צריך לרשות עצור (break), כי אחרת הוא ימשיך לקרוא את ההמשך.

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

על ידי הפקודה: fallthrough

3.

בשפות אחרות ההנחה הבסיסית שישש בכל משתנה ערך מתאים וכל אובייקט קיים, אם מסתבר שהיה טעות, יש לתפוס את החריגות.

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

בשפה זו, הערכים נחשבים לאופציונאלים, מסומן בסימן שאלה (?), האומר שהם יכולים להיות לא מאותחלים (המחזיקים בערך nil הנקרא בשפות אחרות NULL), כל עוד לא כותבים במפורש לקומפיילר שזה ערך ודאי שאינו nil, על ידי סימן קריאה (!).

אגב, הערך nil או null, הוא אומר אפס (נול בגרמנית), אבל אין הכוונה לסיפרה אפס (טיפוס int) או לסטרינג ריק (טיפוס string), וכל אין הכוונה שהוא מחזיק ערך זבל כלשהו, אלא שהוא לא מחזיק ממש בכלום כלום...

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

דוגמא לערך אופציונאלי:

var name:String? // nil

דוגמה למשתנה שאנו יודעים בוודאות שלא יהיה ריק (במידה ויהיה ריק התוכנית תקרוס)

"var name:String! // String -> "israel

טיפים:

1. על מנת לבצע המרה (casting) לסטרינג בתוך מחרוזת, נשים את המשתנה בין סוגרים ומתחיל עם באק סלאש.

דוגמה:

println("the car ride \(fast) kilometer for hour");

2. לאפל יש כלי ששמו פליי גראונד באפליקצית Xcode (להורדה במערכת הפעלה מקינטוש),

כל עוד יש ותמיד יהיו באגים, אז לפעמים הקוד שכתבתם נכון ורק חסר רווחים, תוסיפו אותם ותראו שזה פשוט עובד! כמו כן, להוסיף סימן קריאה (או שאלה), גם יכול לעזור במקרה שזה מתאים.

3. ניתן שלא להשים נקודה-פסיק (;) בסוף שורה, ניתן לכתוב משתנים בשפות שאינם אנגלית, כמו עברית. וכן להשתמש במילה שמורה עם סימן אפוסטרוף (back pic), הנמצא ליד הטילדה (~) במקלדת.

לדוגמה: ... 3='var' או 3=ישראל.

אך זה לא תכנות בריא.

עוד נושא לסיום ושמו קלוסור (closure):

זהו למעשה טיפוס של מבנה של פונקציה או פונקציה אנונימית, אשר ניתן לקבוע אותה כערך למשתנה.

לדוגמה, משתנה n אשר מקבל פונקציה אנונימית המתאימה להגדרה שלו:

let n: Int -> Int; // declaration

n = {(x: Int)->Int in return x+x}; // initialization

למעשה n כעת הוא משתנה המחזיק פונקציה,

שבקריאתה היא תכפיל בשתיים ותחזיר את הערך המועבר אליה בפרמטר.

עוד נושא, ששמו מוטציה (Mutation),

וכן ישנם נושאים נוספים, כגון: lazy Stored Properties, Computed Properties, Subscripts, Enumeration

ועוד חזון למועד..

מאמרים נבחרים
מאמרים חדשים
ארכיון
חפש לפי תג
הבלוג של ישרוליק
  • Facebook Basic Square
  • Twitter Basic Square
  • Google+ Basic Square

ישרוליק נט

israelik net

גולשים אלייך...

bottom of page