সুইফট: শূন্য জন্য পরীক্ষার বিকল্প


137

আমি এক্সকোড 6 বিটা 4 ব্যবহার করছি I আমার এই অদ্ভুত পরিস্থিতি রয়েছে যেখানে আমি বিকল্পগুলির জন্য কীভাবে যথাযথভাবে পরীক্ষা করতে পারি তা বুঝতে পারি না।

আমার যদি একটি alচ্ছিক xyz থাকে তবে এটি পরীক্ষা করার সঠিক উপায়:

if (xyz) // Do something

অথবা

if (xyz != nil) // Do something

দস্তাবেজগুলি এটি প্রথম উপায়ে করতে বলেছে, তবে আমি খুঁজে পেয়েছি যে কখনও কখনও দ্বিতীয় উপায়টি প্রয়োজন হয় এবং এটি একটি সংকলক ত্রুটি তৈরি করে না, তবে অন্যান্য সময় দ্বিতীয়বার সংকলক ত্রুটি উত্পন্ন করে।

আমার সুনির্দিষ্ট উদাহরণটি জিডিটা এক্সএমএল পার্সার ব্রিজড ব্রিফ্ট ব্যবহার করছে:

let xml = GDataXMLDocument(
    XMLString: responseBody,
    options: 0,
    error: &xmlError);

if (xmlError != nil)

এখানে, আমি যদি এখনই করতাম:

if xmlError

এটা সবসময় সত্য ফিরে আসবে। তবে, আমি যদি:

if (xmlError != nil)

তারপরে এটি কাজ করে (এটি কীভাবে উদ্দেশ্য-সিতে কাজ করে)।

জিডিটা এক্সএমএল এবং এটি যেভাবে অনুপস্থিত তা বিকল্পগুলির সাথে আচরণ করে এমন কিছু আছে কি?


4
আপনার অপ্রত্যাশিত কেস এবং ত্রুটি মামলার জন্য আমরা কী একটি পূর্ণ উদাহরণ দেখতে পারি, দয়া করে? (এবং আমি জানি এটি শক্ত, তবে শর্তসাপকের আশেপাশের বন্ধনীগুলি হারাতে চেষ্টা করুন!)
ম্যাট গিবসন

1
এটি
এক্সকোড


আমি সবেমাত্র অপ্রত্যাশিত ক্ষেত্রেটি দিয়ে প্রশ্নটি আপডেট করেছি।
tng

আমি এখনও বিটা 5 এ আপডেট হয়নি। আমি তাড়াতাড়ি করব; দেখতে সুন্দর ?? সুইফটে এবং আরও নিয়মিত alচ্ছিক আচরণ।
tng

উত্তর:


172

এক্সকোড বিটা 5 এ তারা আপনাকে আর করতে দেয় না:

var xyz : NSString?

if xyz {
  // Do something using `xyz`.
}

এটি একটি ত্রুটি তৈরি করে:

'বুলিয়ান টাইপ.প্রোটোকল' প্রোটোকলের সাথে সামঞ্জস্য নেই

আপনাকে এই ফর্মগুলির একটি ব্যবহার করতে হবে:

if xyz != nil {
   // Do something using `xyz`.
}

if let xy = xyz {
   // Do something using `xy`.
}

5
Xyz == নীল কেন কাজ করছে না সে সম্পর্কে কেউ ব্যাখ্যা করতে পারেন?
ক্রিস্টোফ

দ্বিতীয় উদাহরণটি পড়তে হবে: // xy ব্যবহার করে কিছু করুন (যা দুটি রূপের মধ্যে ব্যবহারের ক্ষেত্রে প্রধান পার্থক্য)
আল্পার

@ ক্রিসটফ: ত্রুটি বার্তাটি হ'ল ইনজিটালাইজ হওয়ার আগে ধ্রুবক 'জাইজেড' ব্যবহার করা হয়। আমি মনে করি xyz ঘোষণার রেখার শেষে আপনাকে '= শূন্য' যুক্ত করতে হবে।
ব্যবহারকারী3207158

যারা আমার মতো দ্রুত গতিতে নতুন যারা ভাবছেন এবং তারা ভাবছেন: আপনার যদি এখনও ব্লকের ভিতরে জাইজেড আনপ্রেপ করতে হয়। এটি নিরাপদ যদিও আপনি জোর করে আনপ্রেট করেন
ওমর

@ ওমর এটি দ্বিতীয় ফর্মের সৌন্দর্য, আপনি ব্লকটির অভ্যন্তরে এক্সওয়াইটি আবদ্ধ না করেই ব্যবহার করেন।
এরিক ডার্নেনবার্গে

24

অন্যান্য উত্তরে যুক্ত করতে ifশর্তের অভ্যন্তরে ভিন্নরূপে পরিবর্তিত ভেরিয়েবলকে নিয়োগের পরিবর্তে :

var a: Int? = 5

if let b = a {
   // do something
}

আপনি একই পরিবর্তনশীল নামটি আবার ব্যবহার করতে পারেন:

var a: Int? = 5

if let a = a {
    // do something
}

এটি আপনাকে সৃজনশীল ভেরিয়েবলের নামগুলি এড়াতে সহায়তা করতে পারে ...

এটি সুইচটিতে সমর্থিত ভেরিয়েবল শেডিংয়ের সুবিধা নেয় ।


18

বিকল্পগুলি ব্যবহারের সর্বাধিক প্রত্যক্ষ উপায়গুলির একটি:

ধরে xyzনেওয়া optionচ্ছিক ধরণের, Int?উদাহরণস্বরূপ।

if let possXYZ = xyz {
    // do something with possXYZ (the unwrapped value of xyz)
} else {
    // do something now that we know xyz is .None
}

এইভাবে আপনি উভয় পরীক্ষা করতে পারেন যদি xyz কোনও মান থাকে এবং তা থাকে তবে তাৎক্ষণিকভাবে সেই মানটি নিয়ে কাজ করুন।

আপনার সংকলক ত্রুটি সম্পর্কিত, টাইপটি alচ্ছিক UInt8নয় (নোট নোট '?') এবং তাই রূপান্তর করা যায় না nil। আপনি যে ভেরিয়েবলটির সাথে কাজ করছেন তা বৈকল্পিকের মতো আচরণ করার আগে তা নিশ্চিত করুন।


1
আমি এই পদ্ধতিটি খারাপ বলে মনে করি কারণ আমি অহেতুকভাবে একটি নতুন পরিবর্তনশীল (ধ্রুবক) তৈরি করি, উত্তরগুলি একটি নতুন নাম তৈরি করতে থাকে যা বেশিরভাগ সময় পূর্বের চেয়ে খারাপ হয়ে যায়। লেখার জন্য এবং পাঠকের জন্য আমাকে আরও সময় দেয়।
লম্বাস

3
এটি আদর্শ পদ্ধতি এবং anচ্ছিক পরিবর্তনশীল মোড়ক করার জন্য প্রস্তাবিত পদ্ধতি। "'if'" মারাত্মকভাবে শক্তিশালী।
gnasher729

@ gnasher729 তবে আপনি যদি কেবলমাত্র অন্য অংশটি ব্যবহার করতে চান
ব্র্যাড থমাস

15

সুইফট 3.0, 4.0

শূন্যতার জন্য checkingচ্ছিক চেক করার প্রধানত দুটি উপায় রয়েছে। এখানে তাদের মধ্যে তুলনার উদাহরণ রয়েছে

1. যদি দেওয়া হয়

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

xএটি ছাড়া অন্যটি যদি শূন্য না হয় তবে যদি বন্ধটি কার্যকর করা x_valহবে এবং এটি ভিতরে উপলব্ধ থাকবে। অন্যথায় অন্য বন্ধটি ট্রিগার করা হয়।

if let x_val = x, x_val > 5 {
    //x_val available on this scope
} else {

}

2. গার্ড দিন

guard letএকই জিনিস করতে পারেন। এটির মূল উদ্দেশ্যটি এটিকে যুক্তিযুক্তভাবে আরও যুক্তিসঙ্গত করা। এটি বলার মতো এটি নিশ্চিত করুন যে পরিবর্তনশীল শূন্য নয়, অন্যথায় ফাংশনটি বন্ধ করুনguard letঅতিরিক্ত শর্ত পরীক্ষা হিসাবে করতে পারেনif let

পার্থক্যগুলি হ'ল মোড়কযুক্ত মানটি একই সুযোগে উপলভ্য হবে যা guard letনীচের মন্তব্যে দেখানো হয়েছে। এই, পয়েন্ট আর অবসান মধ্যে, প্রোগ্রাম বর্তমান সুযোগ থেকে প্রস্থান করার জন্য আছে যা বাড়ে দ্বারা return, breakইত্যাদি

guard let x_val = x, x_val > 5 else {
    return
}
//x_val available on this scope

11

সুইফ্ট প্রোগ্রামিং গাইড থেকে

যদি বিবৃতি এবং জোর করে মোড়ানো

Optionচ্ছিকর কোনও মান রয়েছে কিনা তা জানতে আপনি যদি একটি বিবৃতি ব্যবহার করতে পারেন। যদি কোনও alচ্ছিকের কোনও মান থাকে তবে এটি সত্যকে মূল্যায়ন করে; যদি এর কোনও মূল্য না থাকে তবে এটি মিথ্যাতে মূল্যায়ন করে।

সুতরাং এটি করার সবচেয়ে ভাল উপায়

// swift > 3
if xyz != nil {}

এবং যদি আপনি xyzযদি ইন স্টেটমেন্ট ব্যবহার করে থাকেন তবে xyzআপনি যদি ধ্রুবক পরিবর্তনশীল হিসাবে বিবৃতিটি আনপ্রেপ করতে পারেন xyz। সুতরাং যেখানে স্টেটমেন্ট ব্যবহার করা হয়েছে সেখানে আপনাকে প্রতিটি স্থান মোড়ানো দরকার হবে না ।

if let yourConstant = xyz{
      //use youtConstant you do not need to unwrap `xyz`
}

এই কনভেনশনটি দ্বারা প্রস্তাবিত appleএবং এটি ডিভলপাররা অনুসরণ করবে।


2
সুইফ্ট 3 এ আপনাকে করতে হবে if xyz != nil {...}
PSmythirl

সুইফটে 3 বিকল্পগুলি বুলিয়ান হিসাবে ব্যবহার করা যায় না। প্রথম কারণ এটি একটি সি-ইসেম যা ভাষায় প্রথম স্থানে থাকা উচিত ছিল না এবং দ্বিতীয় কারণ এটি বৈকল্পিক বুলের সাথে নিখুঁত বিভ্রান্তির কারণ ঘটায়।
gnasher729

9

যদিও আপনাকে অবশ্যই nilতার মানটি অতিরিক্তভাবে বের করার জন্য একটি alচ্ছিক তুলনামূলকভাবে বা alচ্ছিক বাইন্ডিং ব্যবহার করতে হবে (উদাহরণস্বরূপ বিকল্পগুলি স্পষ্টভাবে বুলিয়ান মানগুলিতে রূপান্তরিত হয় না), এটি লক্ষণীয় যে সুইফট 2 স্টুডেন্টের পিরামিড এড়ানোর জন্য guardবিবৃতি যুক্ত করেছে কাজ করার সময় একাধিক alচ্ছিক মান সহ।

অন্য কথায়, আপনার বিকল্পগুলির মধ্যে এখন স্পষ্টভাবে পরীক্ষা করা অন্তর্ভুক্ত রয়েছে nil:

if xyz != nil {
    // Do something with xyz
}

Ptionচ্ছিক বাঁধাই:

if let xyz = xyz {
    // Do something with xyz
    // (Note that we can reuse the same variable name)
}

এবং guardবিবৃতি:

guard let xyz = xyz else {
    // Handle failure and then exit this code block
    // e.g. by calling return, break, continue, or throw
    return
}

// Do something with xyz, which is now guaranteed to be non-nil

নোট করুন যখন একাধিক isচ্ছিক মান থাকে তখন সাধারণ ordinaryচ্ছিক বাঁধাই কীভাবে আরও বেশি প্রসারণ করতে পারে:

if let abc = abc {
    if let xyz = xyz {
        // Do something with abc and xyz
    }        
}

আপনি guardবিবৃতি দিয়ে এই বাসা এড়াতে পারেন :

guard let abc = abc else {
    // Handle failure and then exit this code block
    return
}

guard let xyz = xyz else {
    // Handle failure and then exit this code block
    return
}

// Do something with abc and xyz

1
উপরে উল্লিখিত হিসাবে, আপনি নেস্টেড alচ্ছিক স্ট্যাটামেটগুলি থেকে মুক্তি পেতে এটিও করতে পারেন। যদি abc = abc? .xyz?। কিছু {}
সুহাইব

1
@ সুহাইব আহ, সত্য: আপনি খুব সহজে নেস্টেড বৈশিষ্ট্য অ্যাক্সেস করতে alচ্ছিক শৃঙ্খলা ( বিকাশকারী। অ্যাপ্লিকেশন / লাইব্রেরি / প্রিরিলেস / কনটেন্ট / ডকুমেন্টেশন/… ) ব্যবহার করতে পারেন । আমি এখানে এটি উল্লেখ করিনি কারণ আমি ভেবেছিলাম এটি আসল প্রশ্ন থেকে খুব বেশি স্পর্শকাতর হতে পারে।
ক্রিস ফ্রেডরিক

দুর্দান্ত উত্তর! তবে সুইফ্ট, ওএমজি ... প্রোগ্রামার বান্ধব হওয়া থেকে এখনও অনেক দূরে!
11:53

@ ট্যুরটেস্টেড ধন্যবাদ! আসলে, আমি মনে করি এটি প্রোগ্রামার বান্ধব এই অর্থে যে এটি গ্যারান্টি দেয় যে আপনি দুর্ঘটনাক্রমে কোনও nilমান ব্যবহার করার চেষ্টা করবেন না , তবে আমি সম্মত হই যে শিক্ষার বক্ররেখাটি কিছুটা খাড়া ste :)
ক্রিস ফ্রেডেরিক

4

সুইফট 5 প্রোটোকল এক্সটেনশন

প্রোটোকল এক্সটেনশান ব্যবহার করে এখানে একটি পদ্ধতির যাতে আপনি সহজেই একটি বিকল্প anচ্ছিক চেক ইনলাইন করতে পারেন:

import Foundation

public extension Optional {

    var isNil: Bool {

        guard case Optional.none = self else {
            return false
        }

        return true

    }

    var isSome: Bool {

        return !self.isNil

    }

}

ব্যবহার

var myValue: String?

if myValue.isNil {
    // do something
}

if myValue.isSome {
    // do something
}

আমি এই উত্তরে কয়েকটি ডাউনভোট পেয়েছি এবং কেন তা জানতে চাই। কমপক্ষে মন্তব্য করুন যদি আপনি ডাউনটাতে যাচ্ছেন।
ব্রডি রবার্টসন

1
এটি সম্ভবত এর swiftঅ্যানালগ pythonistasযা ভাষাটিকে পাইথোনিক বিশুদ্ধতার কোনও আকারে রাখার চেষ্টা করে। আমার নে? আমি আপনার কোডটি আমার ইউটিস মিক্সিনে সরিয়েছি into
জাভাদবা

2

এখন আপনি নিম্নোক্ত জিনিসটি দ্রুত করতে পারবেন যা আপনাকে উদ্দেশ্য-সি এর কিছুটা পুনরুদ্ধার করতে দেয় if nil else

if textfieldDate.text?.isEmpty ?? true {

}

2

পরিবর্তে if, টর্নারি অপারেটর কার্যকর হতে পারে যখন আপনি কোনও কিছু শুল্কের ভিত্তিতে কোনও মান পেতে চান:

func f(x: String?) -> String {
    return x == nil ? "empty" : "non-empty"
}

xyz == nilএক্সপ্রেশন কাজ করে না, কিন্তু x != nilকাজ করে। কেন জানি না।
অ্যান্ড্রু

2

Or চ্ছিক বাঁধাই করতে ifবা guardবিবৃতি ব্যবহারের পাশাপাশি অন্য পদ্ধতির Optionalসাথে প্রসারিত করা:

extension Optional {

    func ifValue(_ valueHandler: (Wrapped) -> Void) {
        switch self {
        case .some(let wrapped): valueHandler(wrapped)
        default: break
        }
    }

}

ifValueএকটি ক্লোজার প্রাপ্ত হয় এবং যখন এটি alচ্ছিক শূন্য না হয় তখন তাকে আর্গুমেন্ট হিসাবে মান সহ কল ​​করে। এটি এভাবে ব্যবহার করা হয়:

var helloString: String? = "Hello, World!"

helloString.ifValue {
    print($0) // prints "Hello, World!"
}

helloString = nil

helloString.ifValue {
    print($0) // This code never runs
}

আপনার সম্ভবত সম্ভবত একটি ifবা এটি ব্যবহার করা উচিত guardকারণ এগুলি স্যুইফ্ট প্রোগ্রামারদের দ্বারা ব্যবহৃত প্রচলিত (এইভাবে পরিচিত) পদ্ধতির।


2

একটি বিকল্প যা বিশেষভাবে আবৃত হয়নি তা হ'ল সুইফ্টের উপেক্ষা করা মান সিনট্যাক্সটি:

if let _ = xyz {
    // something that should only happen if xyz is not nil
}

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


1

এছাড়াও আপনি ব্যবহার করতে পারেন Nil-Coalescing Operator

nil-coalescing operator( a ?? b) একটি ঐচ্ছিক unwraps aযদি এটা রয়েছে aমান, বা আয় aডিফল্ট মান bযদি aহয় nil। একটি এক্সপ্রেশনটি সর্বদা একটি alচ্ছিক ধরণের। ভাবটি bঅবশ্যই ভিতরে সঞ্চিত ধরণের সাথে মেলে a

let value = optionalValue ?? defaultValue

যদি optionalValueহয় nil, এটি স্বয়ংক্রিয়ভাবে মান নির্ধারণdefaultValue


আমি এটি পছন্দ করি কারণ এটি একটি ডিফল্ট মান নির্দিষ্ট করার জন্য সহজ বিকল্প দেয়।
থোয়া

0
var xyz : NSDictionary?

// case 1:
xyz = ["1":"one"]
// case 2: (empty dictionary)
xyz = NSDictionary() 
// case 3: do nothing

if xyz { NSLog("xyz is not nil.") }
else   { NSLog("xyz is nil.")     }

এই পরীক্ষাটি সব ক্ষেত্রেই প্রত্যাশার মতো কাজ করেছিল। বিটিডাব্লু, আপনার বন্ধনী প্রয়োজন নেই ()


2
কেস ওপি সম্পর্কে উদ্বিগ্ন হল: if (xyz != nil)
জাফ

0

যদি আপনার শর্তসাপেক্ষ থাকে এবং আনরোপ করে তুলনা করতে চান তবে কীভাবে যৌগিক বুলিয়ান এক্সপ্রেশনটির শর্ট সার্কিট মূল্যায়নের সুবিধা নেওয়ার বিষয়ে

if xyz != nil && xyz! == "some non-nil value" {

}

মঞ্জুর, এটি অন্যান্য প্রস্তাবিত পোস্টগুলির মতো পড়ার মতো নয়, তবে কাজটি করা এবং অন্যান্য প্রস্তাবিত সমাধানগুলির চেয়ে কিছুটা সাফল্য অর্জন করে।

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