সুইফট: গার্ড যদি বনাম যাই হোক


131

আমি সুইফটে অপশনালগুলি সম্পর্কে পড়ছি, এবং আমি উদাহরণগুলি দেখেছি যেখানে if letOচ্ছিকর কোনও মান আছে কিনা তা পরীক্ষা করার জন্য ব্যবহৃত হয় এবং যদি তা হয় - মোড়কযুক্ত মান দিয়ে কিছু করুন।

তবে, আমি দেখেছি যে সুইফট ২.০-তে মূল কীওয়ার্ডটি guard letবেশিরভাগ ক্ষেত্রেই ব্যবহৃত হয়। আমি অবাক হই যে if letসুইফট ২.০ থেকে সরানো হয়েছে বা এটি এখনও ব্যবহার করা সম্ভব কিনা possible

আমার থাকা প্রোগ্রামগুলিতে কি আমার পরিবর্তন if letকরা উচিত guard let?

উত্তর:


164

if letএবং guard letঅনুরূপ, কিন্তু স্বতন্ত্র উদ্দেশ্য পরিবেশন।

"অন্য" কেসের ক্ষেত্রে guardঅবশ্যই বর্তমান সুযোগটি প্রস্থান করতে হবে। সাধারণত এর অর্থ এটি returnপ্রোগ্রামটি কল করতে বা বাতিল করতে হবে। guardবাকি ফাংশনটির নেস্টিংয়ের প্রয়োজন ছাড়াই তাড়াতাড়ি রিটার্ন সরবরাহ করতে ব্যবহৃত হয়।

if letএটির সুযোগকে বাসা বেঁধে রাখে এবং এর জন্য বিশেষ কোনও কিছুর প্রয়োজন হয় না। এটা returnনা পারে।

সাধারণভাবে, যদি if-letব্লকটি বাকী কাজটি করে চলেছিল, বা এর elseঅনুচ্ছেদে এটির একটি returnবা গর্ভপাত বন্ধ রয়েছে, তবে আপনার guardপরিবর্তে আপনার ব্যবহার করা উচিত । এটির প্রায়শই অর্থ হয় (অন্তত আমার অভিজ্ঞতায়), যখন সন্দেহ হয়, guardসাধারণত এটিই আরও ভাল উত্তর। তবে এমন অনেক পরিস্থিতি রয়েছে যেখানে if letএখনও উপযুক্ত।


38
কেসটি বৈধ if letহলে ব্যবহার করুন non-nil। কেস guardযখন nilকোনও ধরণের ত্রুটি উপস্থাপন করে তখন ব্যবহার করুন ।
বলপয়েন্টবেন

4
@ বালপয়েন্টে আমি এর সাথে একমত নই এমন অনেকগুলি ক্ষেত্রে রয়েছে যেখানে guardত্রুটি না থাকলেও উপযুক্ত। কখনও কখনও এর অর্থ হ'ল কিছুই করার নেই। উদাহরণস্বরূপ, একটি positionTitleপদ্ধতি হতে পারে guard if let title = title else {return}। শিরোনাম alচ্ছিক হতে পারে, এই ক্ষেত্রে এটি ত্রুটি নয়। তবে guard letএখনও উপযুক্ত।
রব নেপিয়ার

1
হ্যাঁ; আমি গার্ড বলতে চাই মন্তব্য করতে।
রব নেপিয়ার

1
অন্য কথায়, কোডটি অন্য শর্তসাপেক্ষে ব্যবহার না করার বিষয়ে 99% নিশ্চিত হওয়ার পরে "গার্ড লেট" ব্যবহৃত হয়; অন্যদিকে কোডটি 50 - 50 (উদাহরণস্বরূপ) অন্য শর্তটি ব্যবহার করার জন্য "যদি" দেওয়া হয়।
চিনো প্যান

1
দ্বারা আবদ্ধ ভেরিয়েবলটি কেবল স্কোপের ভিতরেif let দৃশ্যমান । দ্বারা আবদ্ধ পরিবর্তনশীলটি পরে প্রদর্শিত হবে। সুতরাং এটি guardচ্ছিক মানগুলিকেও আবদ্ধ করতে গার্ড ব্যবহার করা বোধগম্য হয়। if letguard let
বোয়েইডম্যান

105

গার্ড স্পষ্টতা উন্নত করতে পারেন

যখন আপনি গার্ড ব্যবহার করেন আপনার প্রহরীর সাফল্যের জন্য অনেক বেশি প্রত্যাশা থাকে এবং এটি কিছুটা গুরুত্বপূর্ণ যে এটি যদি সফল না হয় তবে আপনি কেবল স্কোপটি প্রারম্ভিকভাবে প্রস্থান করতে চান । আপনার মতো কোনও ফাইল / চিত্র উপস্থিত রয়েছে কিনা তা পাহারা দেওয়ার জন্য, যদি একটি অ্যারে এমপিটি হয় বা না থাকে।

func icon() -> UIImage {
    guard let image = UIImage(named: "Photo") else {
        return UIImage(named: "Default")! //This is your fallback
    }
    return image //-----------------you're always expecting/hoping this to happen
}

যদি আপনি উপরের কোডটি if-দিয়ে লিখেন তবে এটি পড়ার বিকাশকারীকে জানিয়ে দেয় যে এটি 50-50 এর বেশি। তবে আপনি যদি গার্ডটি ব্যবহার করেন তবে আপনি আপনার কোডটিতে স্বচ্ছতা যুক্ত করেন এবং এর থেকে বোঝা যায় আমি এটি সময়ের 95% কাজ করার প্রত্যাশা করি ... যদি এটি কখনও ব্যর্থ হয় তবে আমি জানি না কেন এটি হবে; এটি অত্যন্ত অসম্ভব ... তবে তার পরিবর্তে কেবলমাত্র এই ডিফল্ট চিত্রটি ব্যবহার করুন বা সম্ভবত কোন ভুল হয়েছে তা বর্ণনা করে কোনও অর্থবোধক বার্তা যুক্ত করুন!

  • চলুন guardগুলি যখন তারা পার্শ্ব প্রতিক্রিয়া তৈরি, রক্ষীদের হিসেবে ব্যবহার করা হয় প্রাকৃতিক প্রবাহ। elseক্লজগুলি পার্শ্ব প্রতিক্রিয়াগুলি প্রবর্তন করলে গার্ডদের এড়িয়ে চলুন । গার্ডগুলি প্রাথমিকভাবে প্রস্থান করার প্রস্তাব দিয়ে সঠিকভাবে সম্পাদন করার জন্য কোডের জন্য প্রয়োজনীয় শর্তাদি প্রতিষ্ঠা করে

  • আপনার কাছ থেকে ইতিবাচক শাখায় উল্লেখযোগ্য গণনার, refactor সঞ্চালন যখন ifএকটি থেকে guardবিবৃতি এবং ফলব্যাক মান elseদফা

থেকে: এরিকা সাদুনের সুইফ্ট স্টাইলের বই

উপরোক্ত পরামর্শ এবং পরিষ্কার কোডের ফলস্বরূপ, আপনি ব্যর্থ গার্ডের বিবৃতিগুলিতে দৃ as়তা যুক্ত করতে বা তার পক্ষে আরও বেশি বেশি সম্ভাবনা চান , এটি কেবল পাঠযোগ্যতার উন্নতি করে এবং অন্যান্য বিকাশকারীদের কাছে আপনি কী প্রত্যাশা করেছিলেন তা পরিষ্কার করে দেয়।

guard​ ​let​ image =UIImage(named: selectedImageName) else { // YESSSSSS
     assertionFailure("Missing ​​\(​selectedImageName​)​​ asset") 
     return
} 

guard​ ​let​ image =UIImage(named: selectedImageName) else { // NOOOOOOO
​     ​return 
}

থেকে: এরিকা সাদুনের সুইফ্ট স্টাইলের বই + কিছু পরিবর্তন

(আপনি এজেন্টস / পূর্ব শর্তাদি ব্যবহার করবেন না if-letIt এটি ঠিক ঠিক বলে মনে হচ্ছে না)

প্রহরীদের ব্যবহার ডুমের পিরামিড এড়িয়ে স্বচ্ছতার উন্নতি করতে আপনাকে সহায়তা করে । দেখুন নিতিন এর উত্তর


গার্ড একটি নতুন ভেরিয়েবল তৈরি করে

এর মধ্যে একটি গুরুত্বপূর্ণ পার্থক্য রয়েছে যে আমি বিশ্বাস করি যে কেউই ভালভাবে ব্যাখ্যা করতে পারেন নি।

উভয় guard letএবং ভেরিয়েবল if let আনপ্রেপ যাইহোক

সঙ্গে guard letআপনি তৈরি করছেন একটি নতুন পরিবর্তনশীল যে হবে অস্তিত্ব বাইরে elseবিবৃতি।

সঙ্গে if letআপনি তৈরি করছে না কোনো নতুন পরিবর্তনশীল পর অন্য বিবৃতি, আপনি শুধুমাত্র লিখুন কোড ব্লক যদি ঐচ্ছিক অ শূন্য হয়। নব নির্মিত পরিবর্তনশীল শুধুমাত্র বিদ্যমান ভিতরে কোড ব্লক না পরে!

guard let:

func someFunc(blog: String?) {

    guard let blogName = blog else {
        print("some ErrorMessage")
        print(blogName) // will create an error Because blogName isn't defined yet
        return
    }
    print(blogName) // You can access it here ie AFTER the guard statement!!

    //And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
    guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
        print(" Some errorMessage")
        return
    }
    print(blogName)
}

if-let:

func someFunc(blog: String?) {


    if let blogName1 = blog {
        print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
    }
    if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
        print(blogName1)
    }
}

if letকরণীয় সম্পর্কে আরও তথ্যের জন্য : কেন alচ্ছিক বাঁধার পুনরায় ঘোষণার ফলে ত্রুটি তৈরি হয় না


গার্ডের স্কোপ প্রস্থান করা প্রয়োজন

(রব নেপিয়ারের উত্তরেও উল্লেখ করা হয়েছে):

আপনি অবশ্যই একটি ফানকের ভিতরেguard সংজ্ঞা দিয়েছেন । এটা তোলে প্রধান উদ্দেশ্য, টি থামিয়ে দিতে / রিটার্ন / প্রস্থান সুযোগ হয় যদি একটি শর্ত পূরণ না হয়:

var str : String?

guard let blogName1 = str else {
    print("some error")
    return // Error: Return invalid outside of a func
}
print (blogName1)

জন্য if letযদি আপনি কোন func ভিতরে এটা থাকতে হবে না:

var str : String?    
if let blogName1 = str {
   print(blogName1) // You don't get any errors!
}

guard বনাম if

এটি লক্ষণীয় যে এটি guard letবনাম if letএবং guardবনাম হিসাবে এই প্রশ্নটি দেখতে আরও উপযুক্ত if

স্বতন্ত্র ifকোনও আনারপ্যাটিং করে না, এমনকি কোনও স্ট্যান্ডেলোনও করে না guard। নীচে উদাহরণ দেখুন। কোনও মান হলে তা তাড়াতাড়ি প্রস্থান করে না nil। Optionচ্ছিক মান নেই। কোনও শর্ত পূরণ না হলে এটি খুব তাড়াতাড়ি প্রস্থান করে।

let array = ["a", "b", "c"]
func subscript(at index: Int) -> String?{
   guard index > 0, index < array.count  else { return nil} // exit early with bad index
   return array[index]
}

46

কখন ব্যবহার করবেন if-letএবং কখন ব্যবহার করবেন guardতা প্রায়শই শৈলীর প্রশ্ন।

বলুন আপনার কাছে func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Intএবং আইটেমগুলির একটি alচ্ছিক অ্যারে ( var optionalArray: [SomeType]?) রয়েছে এবং 0অ্যারের nil(সেট-সেট না) থাকলে বা countঅ্যারের মান (সেট করা) থাকলে আপনার ফিরে আসতে হবে।

আপনি এটি ব্যবহার করে এটি প্রয়োগ করতে পারেন if-let:

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        if let array = optionalArray {
            return array.count
        }
        return 0
    }

বা এটি ব্যবহার করে পছন্দ করুন guard:

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        guard let array = optionalArray else {
            return 0
        }
        return array.count
    }

উদাহরণগুলি কার্যকরীভাবে অভিন্ন।

কোথায় guardসত্যিই shines আপনি ডাটা যাচাই মত একটি টাস্ক আছে, এবং আপনি ফাংশন গোড়ার দিকে ব্যর্থ ভুল কিছু বলে থাকলে বলতে চাই।

if-letসমাপ্তির মেয়াদ শেষ হওয়ার সাথে সাথে গুচ্ছের বাসা বাঁধার পরিবর্তে , "সাফল্যের পথ" এবং এখন সফলভাবে আবদ্ধ বিকল্পগুলি সমস্তই পদ্ধতির মূল ক্ষেত্রের মধ্যে রয়েছে কারণ ব্যর্থতার পথগুলি সমস্ত ইতিমধ্যে ফিরে এসেছে।


30

আমি কিছু (অপরিশোধিত) কোড দিয়ে গার্ডের বিবৃতিগুলির কার্যকারিতা ব্যাখ্যা করার চেষ্টা করব।

আপনার একটি ইউআই রয়েছে যেখানে আপনি ব্যবহারকারী নাম, পদবি, ইমেল, ফোন এবং পাসওয়ার্ড সহ নিবন্ধের জন্য পাঠ্য ক্ষেত্রগুলিকে যাচাই করছেন।

যদি কোনও টেক্সটফিল্ডে বৈধ পাঠ্য না থাকে, তবে সেই ক্ষেত্রটি প্রথমে রিসপন্ডার করা উচিত।

এখানে বিনা প্রতিরোধী কোডটি রয়েছে:

//pyramid of doom

func validateFieldsAndContinueRegistration() {
    if let firstNameString = firstName.text where firstNameString.characters.count > 0{
        if let lastNameString = lastName.text where lastNameString.characters.count > 0{
            if let emailString = email.text where emailString.characters.count > 3 && emailString.containsString("@") && emailString.containsString(".") {
                if let passwordString = password.text where passwordString.characters.count > 7{
                    // all text fields have valid text
                    let accountModel = AccountModel()
                    accountModel.firstName = firstNameString
                    accountModel.lastName = lastNameString
                    accountModel.email = emailString
                    accountModel.password = passwordString
                    APIHandler.sharedInstance.registerUser(accountModel)
                } else {
                    password.becomeFirstResponder()
                }
            } else {
                email.becomeFirstResponder()
            }
        } else {
            lastName.becomeFirstResponder()
        }
    } else {
        firstName.becomeFirstResponder()
    }
}

আপনি উপরে দেখতে পারেন যে সমস্ত স্ট্রিং (ফার্স্টনেমস্ট্রিং, লাস্টনামস্ট্রিং ইত্যাদি) কেবলমাত্র যদি স্টেটমেন্টের স্কোপের মধ্যেই অ্যাক্সেসযোগ্য হয়। সুতরাং এটি "ডুমের পিরামিড" তৈরি করে এবং এর সাথে অনেকগুলি সমস্যা রয়েছে যার মধ্যে পাঠযোগ্যতা এবং চলাফেরার জিনিসগুলি সহজেই (ক্ষেত্রের ক্রমটি যদি পরিবর্তন হয় তবে আপনাকে এই কোডটির বেশিরভাগটিই আবার লিখতে হবে)

গার্ড স্টেটমেন্টের সাথে (নীচের কোডে) আপনি দেখতে পাচ্ছেন যে এই {}ক্ষেত্রগুলি বৈধ কিনা এই স্ট্রিংগুলি বাইরে পাওয়া যায় এবং এর ব্যবহার করা হয়।

// guard let no pyramid of doom
func validateFieldsAndContinueRegistration() {

guard let firstNameString = firstName.text where firstNameString.characters.count > 0 else {
            firstName.becomeFirstResponder()
            return
        }
guard let lastNameString = lastName.text where lastNameString.characters.count > 0 else {
            lastName.becomeFirstResponder()
            return
        }
guard let emailString = email.text where 
        emailString.characters.count > 3 &&
        emailString.containsString("@") && 
        emailString.containsString(".") else {
            email.becomeFirstResponder()
            return
        }
guard let passwordString = password.text where passwordString.characters.count > 7 else {
            password.becomeFirstResponder()
            return
        }

// all text fields have valid text
    let accountModel = AccountModel()
    accountModel.firstName = firstNameString
    accountModel.lastName = lastNameString
    accountModel.email = emailString
    accountModel.password = passwordString
    APIHandler.sharedInstance.registerUser(accountModel)
}

যদি ক্ষেত্রগুলির ক্রম পরিবর্তন হয়, কেবল কোডের সম্পর্কিত লাইনগুলি উপরে বা নীচে সরিয়ে দিন এবং আপনি যেতে ভাল।

এটি একটি খুব সাধারণ ব্যাখ্যা এবং ব্যবহারের কেস। আশাকরি এটা সাহায্য করবে!


14

বেসিক পার্থক্য

গার্ড দিন

  1. সুযোগ থেকে প্রাথমিকভাবে প্রক্রিয়া
  2. রিটার্ন, নিক্ষেপ ইত্যাদির মতো বিদ্যমান স্কোর প্রয়োজন ire
  3. এমন একটি নতুন ভেরিয়েবল তৈরি করুন যার সুযোগটি অ্যাক্সেস হতে পারে।

যদি হয়

  1. সুযোগ অ্যাক্সেস করতে পারবেন না।
  2. বিবৃতি ফেরার দরকার নেই। তবে আমরা লিখতে পারি

দ্রষ্টব্য: Bothচ্ছিক ভেরিয়েবল আন-র্যাপ করতে উভয়ই ব্যবহৃত হয়।



2

পাহারা

  • guardএক বা একাধিক শর্ত পূরণ না হলে প্রোগ্রামের নিয়ন্ত্রণকে সুযোগের বাইরে স্থানান্তর করতে একটি বিবৃতি ব্যবহৃত হয়।

  • একটি guardবিবৃতিতে যে কোনও শর্তের মান অবশ্যই প্রকারের Bool বা এক প্রকারের ব্রিজড হতে হবে Bool। শর্তটি একটি alচ্ছিক বাধ্যবাধকতা ঘোষণাও হতে পারে।

একজন প্রহরী বিবৃতিতে নিম্নলিখিত ফর্ম রয়েছে:

guard condition else {
    //Generally return
}

যদি হয়

  • Alচ্ছিক বাঁধাই হিসাবেও জনপ্রিয় ।
  • Useচ্ছিক বস্তু অ্যাক্সেসের জন্য আমরা ব্যবহার করি if let
if let roomCount = optionalValue {
    print("roomCount available")
} else {
    print("roomCount is nil")
}

1

আমি বব এর সাথে দ্রুত থেকে এটি শিখেছি ..

সাধারণ অন্যথায় - যদি

 func checkDrinkingAge() {
      let canDrink = true

     if canDrink {
        print("You may enter")
       // More Code
        // More Code
      // More Code

         } else {
         // More Code
    // More Code
    // More Code
    print("Let me take you to the jail")
          }
     }

অন্যথায় যদি ইস্যু

  1. নেস্টেড বন্ধনী
  2. ত্রুটি বার্তাটি চিহ্নিত করতে প্রতিটি লাইন পড়তে হবে

গার্ড স্টেটমেন্ট একটি গার্ড ব্লক শুধুমাত্র শর্তটি মিথ্যা হলে চালিত হয় এবং এটি ফিরতি দিয়ে ফাংশন থেকে বেরিয়ে আসবে। যদি অবস্থাটি সত্য হয় তবে সুইফ্ট গার্ড ব্লকটিকে উপেক্ষা করে। এটি প্রাথমিক প্রস্থান এবং আরও কম বন্ধনী সরবরাহ করে provides

func checkDrinkProgram() {
       let iCanDrink = true

           guard iCanDrink else {
        // if iCanDrink == false, run this block
         print("Let's me take you to the jail")
          return
        }

         print("You may drink")
           // You may move on
                  // Come on.
                 // You may leave
                // You don't need to read this.
                 // Only one bracket on the bottom: feeling zen.
       }

অন্যথায়-যদি বিকল্প অপরিচ্ছন্ন

গার্ড স্টেটমেন্টটি কেবলমাত্র শর্তযুক্ত ব্লককে অন্য কোনও-ইফ স্টেটমেন্টের সাথে প্রতিস্থাপনের জন্য দরকারী নয়, তবে বন্ধনীর সংখ্যা হ্রাস করে বিকল্পগুলি আন-র্যাপিংয়ের জন্যও দুর্দান্ত। তুলনা করতে, প্রথমে শুরু করা যাক কীভাবে অন্য-সঙ্গে একাধিক বিকল্প আন-rapেকে রাখা যায়। প্রথমে আসুন আমরা তিনটি বিকল্প তৈরি করি যা মোড়ানো হবে।

var publicName: String? = "Bob Lee"
var publicPhoto: String? = "Bob's Face"
var publicAge: Int? = nil

সবচেয়ে খারাপ দুঃস্বপ্ন

func unwrapOneByOne() {
         if let name = publicName {
              if let photo = publicPhoto {
                     if let age = publicAge {
                        print("Bob: \(name), \(photo), \(age)")
                                  } else {
                          print("age is mising")
                           }
                  } else {
                      print("photo is missing")
                         }
                  } else {
                        print("name is missing")
                         }
                  }

উপরের কোডটি অবশ্যই কাজ করে তবে ডিআরওয়াই নীতি লঙ্ঘন করে। এটা নৃশংস। আসুন এটি ভেঙে দিন

সামান্য আরও ভাল নীচের কোডটি উপরের চেয়ে বেশি পঠনযোগ্য +

func unwrapBetter() {
         if let name = publicName {
       print("Yes name")
                   } else {
               print("No name")
        return
      }

         if let photo = publicPhoto {
             print("Yes photo")
            } else {
           print("No photo")
       return
             }

        if let age = publicAge {
            print("Yes age")
                      } else {
                print("No age")
            return
                           }
     }

গার্ডের সাথে আন-rapাকা অন্যথায়-যদি বিবৃতিগুলি গার্ডের সাথে প্রতিস্থাপন করা যায় +

 func unwrapOneByOneWithGuard() {
             guard let name = publicName else {
                  print("Name missing")
              return
                                        }

              guard let photo = publicPhoto else {
              print("Photo missing")
                return
                                            }

                  guard let age = publicAge else {
                   print("Age missing")
                                     return
                                                 }
                 print(name)
                 print(photo)
                 print(age)
         }

অন্যথায় যদি একাধিক বিকল্পগুলি আন-র্যাপ করা যায় তবে এখন পর্যন্ত, আপনি একের পর এক বিকল্পগুলি আন-র্যাপ করে চলেছেন । সুইফট আমাদের একসাথে একাধিক বিকল্প আনারপ্ট করতে দেয়। যদি তাদের কোনওটিতে শূন্য থাকে তবে এটি অন্য ব্লকটি কার্যকর করে।

func unwrap() {
  if let name = publicName, let photo = publicPhoto, let age = publicAge {
    print("Your name is \(name). I see your face right here, \(photo), you are \(age)")
  } else {
    // if any one of those is missing
    print("Something is missing")
  }
}

সচেতন থাকুন যে আপনি যখন একসাথে একাধিক বিকল্প আন-

গার্ডের সাথে একাধিক বিকল্পগুলি মোড়ক করা আবশ্যক , আমাদের অন্য-যদি-তে গার্ড ব্যবহার করা উচিত +

func unwrapWithGuard() {
  guard let name = publicName, let photo = publicPhoto, let age = publicAge else {
    // if one or two of the variables contain "nil"
    print("Something is missing")
    return
  }

  print("Your name is \(name). I see your, \(photo). You are \(age).")
  // Animation Logic
  // Networking
  // More Code, but still zen
}

দয়া করে ফিরে যান এবং আপনার কোড ফর্ম্যাটিং / ইন্ডেন্টেশন ঠিক করুন!
পকেম্ব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.