English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
في هذا المقال، ستتعلم عن الدوال المعددة المخصصة، التي ستحصل على أنواع مختلفة من الإدخالات وتقديم الخروج.
في المقال السابقدوال Swiftلقد تعلمنا الدوال الآن، وسنستعرض في هذا المقال طرق إنشاء الدوال المختلفة في Swift والأنواع، وهي كيفية التعامل مع الإدخال والخروج في الدوال.
لا تقبل هذه الأنواع من الدوال أي إدخال أو تقديم أي قيمة.
func funcname() { // الأوامر {} أو func funcname() -> () { // الأوامر {} أو func funcname() -> Void { // الأوامر {}
كل هذه القواعد صالحة لإنشاء دوال بدون معرفات وتقديم أي قيمة.
القواعد السابقة func funcname()->() تساوي func funcname()->void، لأن void هو اسم别名 للـ(). يمكنك زيارةاسماء别名 Swiftللتعرف على المزيد من المعلومات.
func greetUser() { print("صباح الخير!") {} greetUser()
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
صباح الخير!
لا تقبل هذه الأنواع من الوظائف أي معلمات، بل تعيد قيمة. لتمديد نوع العودة، تحتاج إلى إضافة السهم (->) ونوع العودة.
func funcname() -> ReturnType { // الأوامر return value {}
func greetUser() -> String { return "صباح الخير" {} let msg = greetUser() print(msg)
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
صباح الخير!
في البرنامج المذكور أعلاه، قمت بتحديد نوع العودة كString. لذلك، يجب أن تعود جملة من جسم الوظيفة كحرف، وإلا ستتلقى خطأ.
كلمة المفتاح return تنتقل سيطرة البرنامج من جسم الوظيفة إلى دعوة الوظيفة. إذا كنت بحاجة إلى العودة من وظيفة، فأضف القيمة التي تريد العودة منها بعد كلمة المفتاح return.
جملة return "صباح الخير!" تعيد قيمة من نوع String. يرجى الانتباه إلى أن نوع القيمة و القيمة يجب أن تتطابقان.
يمكنك أيضًا تخصيص القيمة العائدة إلى متغير أو ثابت. let msg = تخصيص القيمة العائدة إلى الثابت msg. لذلك، تنتج جملة print(msg) هذه القيمة."صباح الخير!".
إذا كنت ترغب في تجاهل هذه القيمة، فما عليك سوى استخدام خط التشكيل _، أي let _.
تستخدم المعلمات في الداخل الوظائف. تتضمن المعلمات اسم المعلمة ونوعها، مسبوقة بنقطة عائمة (:.). لا تعيد هذه الأنواع من الوظائف أي قيمة.
func funcname(parameterName:Type) { // الأوامر {}
func greetUser(msg:String) { print(msg) {} greetUser(msg: "صباح الخير!")
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
صباح الخير!
في البرنامج المذكور أعلاه، تقبل الوظيفة معلمة من نوع نص واحد. يمكن استخدام المعلمة فقط داخل الوظيفة. msg هو اسم المعلمة.
يمكنك تنفيذ الوظيفة greetUser(msg: "صباح الخير!") عن طريق تمرير قيمة النص msg كمعلمة للوظيفة. يظل اسم المعلمة مرئيًا فقط داخل وظيفة greetUser().
لذلك، جملة print(msg) تنتج "صباح الخير!".
هذه الأنواع من الوظائف تستخدم المعلمات وتعيد القيمة.
func funcname(parameterName:Type) -> ReturnType { // الأوامر {}
func greetUser(name:String) -> String { return "صباح الخير! " + name {} let msg = greetUser(name: "Jack") print(msg)
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
صباح الخير! Jack
في البرنامج أعلاه، تقبل الدالة عدة متغيرات من نوع String وتعيد قيمة من نوع String هي “صباح الخير! Jack”.
تستخدم هذه الأنواع من الدوال عدة معلمات مفصولة بالكومياس، وتعود عدة قيم. يمكنك استخدام الزوج في Swift للعودة عدة قيم.
func funcname(parameterName:Type, parameterName2:Type ..., ...) -> (ReturnType, ReturnType ...) { // الأوامر {}
func greetUser(name:String, age:Int) -> (String, Int) { let msg = "Good Morning!" + name var userage = age if age < 0 { userage = 0 {} return (msg, userage) {} let msg = greetUser(name: "Jack", age: -2) print(msg.0) print(" لديك \(msg.1) عملة متبقية")
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
صباح الخير!Jack لديك 0 عملة متبقية
في البرنامج أعلاه، يقبل الدالة greetUser() عدة متغيرات من نوع String و Int. كما تعود الدالة عدة قيم، من نوع String و Int.
للوصول إلى كل قيمة عودة، نستخدم المواقع الأساسية 0، 1،... هنا، نستخدم msg.0 للوصول إلى “Good Morning!Jack” و msg.1 للوصول إلى “0”.
استخدام الموقع الأساسي يمكن أن يكون غير واضح وغير قابلة للقراءة أحياناً. يمكننا حل هذه المشكلة بشكل رائع عن طريق تسمية القيم العودة. يمكن إعادة كتابة البرنامج كما يلي.
func greetUser(name:String, coins:Int) -> (name:String, coins:Int) { let msg = "Good Morning!" + name var userCoins = coins if coins < 0 { userCoins = 0 {} return (msg, userCoins) {} let msg = greetUser(name: "Jack", coins: -2) print(msg.name) print("You have \(msg.coins) coins left")
في هذا البرنامج، تكون النوعية نوع المجموعة، تحتوي على اسم المتغيرات التي لها هذا النوع. أهم ميزة لذلك هي أن يمكنك استخدام اسم المتغير msg.name و msg.coins بديلاً عن msg.0 و msg.1 للحصول على النتائج.
عند تعريف وظيفة تقبل المدخلات، يمكنك استخدام اسم المعلمة لتعريف اسم المدخلات. ولكن، هناك اسم آخر يمكنك استخدامه مع اسم المعلمة، وهو بطاقة المعلمة.
استخدام بطاقات المعلمة يسمح باستدعاء الوظيفة بطريقة تعبيرية، تشبه الجملة، بينما توفر جسم الوظيفة قابلة للقراءة ومفهومة.
كل معلمة في الوظيفة تحتوي على بطاقة معلمة واسم المعلمة. بشكل افتراضي، تستخدم المعلمة اسمها كبطاقة معلمة. ولكن، إذا قمت بتحديد اسم المعلمة، ستستخدم بطاقة المعلمة عند استدعاء الوظيفة.
تكون نحو وظيفة مع بطاقات معلمة كالتالي
func funcname(argumentLabel parameterName: Type) -> Return Type { // الأوامر {}
لنرى ذلك في المثال التالي.
func sum(a: Int, b: Int) -> Int { return a + b {} let result = sum(a: 2, b: 3) print("الجمع هو \(result)")
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
الجمع هو 5
في المثال السابق، لم نحدد بطاقات المعلمات، لذا عند استدعاء الوظيفة ستستخدم بطاقات المعلمات الافتراضية a وb كبطاقات المعلمات.
عند استدعاء الوظيفة، قد تلاحظ أن استدعاء الوظيفة ليس تعبيرًا/جملة. إذا كان يمكنك إعداد استدعاء الوظيفة كالتالي:
let result = sum(of: 2, and: 3)
الآن دعونا نغير الوظيفة:
func sum(of: Int, and: Int) -> Int { return of + and {} let result = sum(of: 2, and: 3) print("الجمع هو \(result)")
الآن، يمكن التعبير عن استدعاء الطريقة. ولكن، الآن يجب علينا استخدام اسم المعلمة of&and، وreturn of + and للبحث عن مجموع数字ين. هذا يجعل جسم الوظيفة أقل قابلية للقراءة. سيكون من المفيد أكثر استخدام a و b بدلاً من of&and في جسم الوظيفة.
لهذا، يجب علينا تحديد بطاقات المعلمات بشكل واضحًا:
func sum(of a :Int, and b:Int) -> Int { return a + b {} let result = sum(of: 2, and: 3) print("الجمع هو \(result)")
في البرنامج المذكور أعلاه، تأخذ الوظيفة إثنين من المعلمات من نوع Int. يتم استدعاء الوظيفة باستخدام معلمات التسمية of&and، مما يكون sum(of: 2, and: 3) بدلاً من sum(a: 2, b: 3).
إضافة إلى ذلك، يستخدم جسم الوظيفة أسماء المعلمات a وb بدلاً من of&and، مما يكون أكثر معنى عند تطبيق العمليات.
يمكنك أيضًا توفير معلمات بدون تسمية بتسجيل علامة تحتية _ في بداية اسم المعلمات.
func sum(_ a :Int, _ b:Int) -> Int { return a + b {} let result = sum(2, 3) print("الجمع هو \(result)")
يمكنك تقديم قيمة افتراضية لأي معلمات في الوظيفة، عن طريق تخصيص قيمة للمعلمات بعد نوعها. يمكن أن تجعل تقديم معلمات افتراضية تسمح لك بتخطي المعلمات عند استدعاء الوظيفة.
إذا لم يتم تمرير قيمة إلى المعلمات عند استدعاء الوظيفة، يتم استخدام القيمة الافتراضية. ولكن إذا تم تمرير قيمة صريحة إلى المعلمات عند الاستدعاء، يتم استخدام القيمة المحددة.
func funcname(parameterName:Type = value) -> Return Type { // الأوامر {}
func sum(of a :Int = 7, وb:Int = 8) -> Int { return a + b {} let result1 = sum(of: 2, and: 3) print("الجمع هو \(result1)") let result2 = sum(of: 2) print("الجمع هو \(result2)") let result3 = sum(and: 2) print("الجمع هو \(result3)") let result4 = sum() print("الجمع هو \(result4)")
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
الجمع هو 5 الجمع هو 10 الجمع هو 9 الجمع هو 15
في البرنامج المذكور أعلاه، تأخذ الوظيفة sum(a :Int = 7 , وb:Int = 8) -> Int إثنين من المعلمات من نوع Int وتحدد القيم الافتراضية للمعلمتين a=7 وb=8.
إذا تم نقل value كمعامل عند استدعاء الدالة، sum(of: 2, and: 3) يتم استخدامها2و3بديلاً عن القيم الافتراضية للمعامل.
لكن إذا لم تكن تقدم قيمة المعامل إلى sum()، فإن القيم الافتراضية 7 و 8 ستستخدم كقيم المعامل.
يمكن للمعاملات المتغيرة قبول صفر أو أكثر من القيم من نوع معين. يمكنك تحديد معامل متغير عن طريق إضافة ثلاث نقاط (...) بعد اسم نوع المعامل.
يستخدم عادة معاملات متغيرة عندما تحتاج إلى نقل كميات مختلفة من القيم إلى المعامل عند استدعاء الدالة. على سبيل المثال، قائمة أرقام، قائمة أحرف وما إلى ذلك.
تكون جملة دالة تحتوي على معاملات متغيرة كالتالي:
func funcname(parameterName: Type...) -> Return Type { // الأوامر {}
func sum(of numbers: Int...) { var result = 0 for num in numbers { result += num {} print("مجموع الأرقام هو \(result)") {} sum(of: 1, 2, 3, 4, 5, 6, 7, 8)
في البرنامج أعلاه، تقبل الدالة sum(of numbers: Int...) معاملات متغيرة من نوع Int. يمكن للمعاملات المتغيرة قبول عدة قيم منفصلة بالكومات sum(of: 1, 2, 3, 4, 5, 6, 7, 8).
القيم التي يتم نقلها كمعاملات متغيرة1،2،3،4،5،6،7،8يمكن استخدامها كعدد من نوع Int داخل جسم الدالة. لذلك، يمكن تطبيق حلقة for-in كـ for num in numbers.
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
مجموع الأرقام هو 36
ملاحظة: تقبل دالة print() المدمجة في Swift أي نوع من أنواع البيانات المتغيرة.
Any تمثل أي نوع بيانات في Swift، مثل Int، Float، Double، String وما إلى ذلك.
لا يمكنك تعديل معامل الدالة داخل الجسم. لذلك، هي ثابتة بشكل افتراضي. دعونا نرى ذلك في مثال:
func process(name: String) { if name == ""{ name = "guest" {} {}
سيؤدي البرنامج أعلاه إلى خطأ في التجميع، لأنك لا يمكنك تعديل قيمة المعامل.
إذا كنت ترغب في تعديل قيمة المعامل من قبل الدالة، فعليك تعريف المعامل كمعامل in-out. يمكنك كتابة المعاملات المدخلة/المخرجة عن طريق وضع كلمة المفتاح inout أمام نوع المعامل.
في الخلفية، يحتوي معامل in-out على قيمة واحدة، يتم نقل هذه القيمة إلى الدالة، يتم تعديلها من قبل الدالة، ثم يتم نقلها مرة أخرى إلى الدالة لتعويض القيمة الأصلية. لذلك، لا يمكن نقل القيمة الثابتة في استدعاء الدالة. يجب عليك إعلانها كمتغير.
يكون جملة وظيفة تحتوي على معلمات مخرجة كالتالي: }}
func funcname(parameterName:inout Type) -> Return Type { // الأوامر {}
func process(name:inout String) { if name == ""{ name = "guest" {} {} var userName = "" process(name: &userName) print(userName)
عند تشغيل البرنامج المذكور أعلاه، الناتج سيكون:
guest
في البرنامج المذكور أعلاه، قمنا بتعريف وظيفة تأخذ معلمات مخرجة لتغيير/تعديل المعلمات name في جسم الوظيفة.
عند تمرير المعلمات إلى المعلمات المخرجة، يجب استخدام علامة & مباشرة قبل اسم المتغير حتى يتمكن الوظيفة من تعديلها.