ios - সুইফটে, আমি কীভাবে উভয় বিকল্প এবং শূন্য বস্তুর উল্লেখগুলি এড়াতে পারি?




macos swift (3)

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

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

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

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

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


অথবা আমার কেবল বিকল্পগুলি ব্যবহার করার কথা, এবং যদি আমি যা করছি তা যদি হয় তবে অন্যান্য ভাষার মতো রেফারেন্সের জন্য কেবল নাল কার্যনির্বাহী থাকার চেয়ে এটি কীভাবে ভাল?

যদি আপনার গণনার কোনও "বিশেষ" মান ফেরত আসতে পারে তবে হ্যাঁ, সুইফটে আপনাকে বিকল্পগুলি ব্যবহার করার কথা রয়েছে। এগুলি স্পষ্টরূপে নালাগুলির চেয়ে ভাল। এমন কোনও ঘটনা সহজে মিস করা যায় যেখানে পয়েন্টারটি nil হতে পারে, nil এটি আরও শক্ত (তবে সম্পূর্ণ সম্ভব)।

আপনি যদি সেগুলিকে নিরাপদে মোড়ানোর জন্য "যদি দিন" ব্যবহার করেন তবে আপনি ক্র্যাশগুলি এড়াতে পারবেন, তবে মানটির সাথে কাজ করতে আপনি যদি "যদি দেওয়া হয়" বিবৃতিটির ক্ষেত্রের মধ্যে আটকে থাকেন, এবং আপনাকে এখনও সম্ভাব্য শূন্যতার বিষয়টি পরিচালনা করতে হবে।

এটি একটি বৈশিষ্ট্য। আমার অর্থ, এটি একটি that'sচ্ছিক ধরণের সম্পূর্ণ বিন্দু: আপনাকে উভয় কেস পরিচালনা করতে হবে ( nil ও নন- nil ) এবং আপনাকে এটি সম্পর্কে স্পষ্ট থাকতে হবে।

একই ধরণের ধারণার উদাহরণের জন্য হাস্কেলের সম্ভবত টাইপ এবং মনড দেখুন। মায়া টাইপটি alচ্ছিক ধরণের যথাযথ সমতুল্য, মায়াড মোডগুলি সর্বদা খালি মূল্যবোধের জন্য ম্যানুয়ালি পরীক্ষা না করেই এই alচ্ছিক মানগুলির সাথে "চেইন" ক্রিয়াকলাপটিকে খুব সহজ করে তোলে।


আপনি ঠিক বলেছেন, বিকল্পগুলি ব্যথা হতে পারে, এজন্য আপনার এগুলি অতিরিক্ত ব্যবহার করা উচিত নয়। ফ্রেমওয়ার্ক ব্যবহার করার সময় সেগুলি আপনাকে মোকাবেলা করার মতো আরও কিছু কিছু নয়। এগুলি একটি অবিশ্বাস্যরকম সাধারণ সমস্যার সমাধান: এমন কলটি কীভাবে পরিচালনা করতে হবে যে কোনও ফলাফলটি ঠিক আছে, বা নাও পারে returns

উদাহরণস্বরূপ, Array.first সদস্যটি নিন। এটি একটি সহজ ইউটিলিটি যা আপনাকে একটি অ্যারের প্রথম উপাদান দেয়। যখন আপনি কেবল a[0] কল করতে পারতেন, তখন a.first কল করতে সক্ষম হওয়া কেন দরকারী? কারণ রানটাইমের সময় অ্যারে খালি থাকতে পারে, সেক্ষেত্রে a[0] বিস্ফোরিত হবে। অবশ্যই আপনি আগেই a.count পরীক্ষা করতে পারেন - তবে তারপরে আবার

ক। আপনি ভুলে যেতে পারেন,

এবং

B ইংরেজী বর্ণমালার দ্বিতীয় অক্ষর. এটি বেশ কুৎসিত কোডে ফলাফল করে।

Array.first an Array.first ফিরে আসার মাধ্যমে এটি নিয়ে কাজ করে। সুতরাং অ্যারের প্রথম উপাদানটি যে মানটি ব্যবহার করতে পারবেন তার আগে আপনাকে alচ্ছিক আনারপ্ট করতে বাধ্য করা হবে।

এখন, ব্লকটির অভ্যন্তরে মোড়ক থাকা মান সম্পর্কে আপনার ইস্যুতে if let হয় if let । সমান্তরাল কোডটি কল্পনা করুন, অ্যারের সংখ্যাটি পরীক্ষা করে দেখুন। এটা ঠিক তাই হবে?

if a.count > 0 {
    // use a[0]
}
// outside the block, no guarantee
// a[0] is valid

if let firstElement = a.first {
    // use firstElement
}
// outside the block, you _can't_
// use firstElement

অবশ্যই, আপনি গণনাটি শূন্য হলে ফাংশন থেকে প্রারম্ভিক রিটার্ন সম্পাদন করার মতো কিছু করতে পারেন। এটি কাজ করে তবে কিছুটা ত্রুটি-প্রবণ - যদি আপনি এটি করতে ভুলে গিয়েছিলেন বা এটি শর্তযুক্ত বিবৃতিতে চালিত করেন যা চালানো হয়নি? মূলত আপনি array.first দিয়ে একই কাজ করতে পারেন: array.first প্রথম দিকে গণনা পরীক্ষা করে দেখুন এবং তারপরে পরে array.first! । কিন্তু যে ! এটি আপনার কাছে সংকেতের মতো - সাবধান, আপনি বিপজ্জনক কিছু করছেন এবং আপনার কোড পুরোপুরি সঠিক না হলে আপনি দুঃখিত হবেন।

বিকল্পগুলি বিকল্পগুলি কিছুটা সুন্দর করতে সহায়তা করে। ধরুন আপনি অ্যারেটি ফাঁকা থাকলে মানটি ডিফল্ট করতে চেয়েছিলেন। এর পরিবর্তে:

array.count > 0 ? a[0] : somedefault

আপনি এটি লিখতে পারেন:

array.first ?? somedefault

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

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

Optionচ্ছিক প্রত্যাবর্তন সন্ধানের সাথে find ঠিক স্বাভাবিক, যখন আপনি alচ্ছিক রীতিটি বুঝতে পারবেন, তখন বুঝতে হবে যে এটির কারণটি কারণটি সম্ভবত সুস্পষ্ট কারণে কার্যকর হতে পারে না। এবং উপরে উল্লিখিত সুরক্ষা সম্পর্কিত সমস্ত একই জিনিসগুলিও প্রযোজ্য - আপনি দুর্ঘটনাক্রমে ভুলতে পারবেন না এবং ফলাফলটিকে একটি সূচক হিসাবে ব্যবহার করতে পারবেন না, কারণ আপনাকে প্রথমে এটি মোড়তে হবে।

এটি বলেছিল, আপনি বিকল্পগুলি অতিরিক্ত ব্যবহার করতে পারেন কারণ এগুলি চেক করা ভার are এ কারণেই অ্যারে সাবস্ক্রিপ্টগুলি বিকল্পগুলি ফেরায় না - এটি নিয়মিত পরীক্ষা করা এবং মোড়কে ফেলতে এত ঝামেলা তৈরি করে, বিশেষত যখন আপনি যে সত্যিকারের জন্য জানেন যে আপনি যে সূচকটি ব্যবহার করছেন তা বৈধ (উদাহরণস্বরূপ, আপনি এতে রয়েছেন) লোকেরা ব্যবহার করবে এমন অ্যারের বৈধ সূচক রেঞ্জের উপরে লুপের জন্য ! অবিচ্ছিন্নভাবে, এবং এভাবে কোনও কোড ছাড়াই তাদের কোডগুলিকে বিশৃঙ্খলা করে। তবে তারপরে প্রথম এবং শেষের মতো সহায়ক পদ্ধতিগুলি সাধারণ কেসগুলি কভার করার জন্য যুক্ত করা হয় যেখানে লোকেরা প্রথমে অ্যারের আকারটি পরীক্ষা না করেই দ্রুত অপারেশন করতে চায় তবে নিরাপদে এটি করতে চায়।

(অন্যদিকে, সুইফ্ট ডিকোচারগুলি অবৈধ সাবস্ক্রিপ্টগুলির মাধ্যমে নিয়মিত অ্যাক্সেস করা হবে বলে আশা করা হচ্ছে, যার কারণে তাদের [key] পদ্ধতিটি alচ্ছিকভাবে ফিরে আসে)

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


সুইফট 2 এবং পরবর্তীটিতে guard let লেটও অন্তর্ভুক্ত রয়েছে যা এই প্রশ্নটিতে উল্লিখিত অনেক সমস্যার সমাধান করে। আপনি চাইলে ভেরিয়েবলের নামটিও আবার ব্যবহার করতে পারেন:

func compute(value: Double?) -> Double? {
    guard let value = value  else { return nil }

    // ... `value` is now a regular Double within this function
}

আপনি যখন প্রথম অংশটি nil করে তখন আপনি একটি এক্সপ্রেশন শর্ট সার্কিট করতে expression চ্ছিক চেইনিং ( ? ) ব্যবহার করতে পারেন:

let answer = compute(value: 5.5)?.rounded()

এবং শূন্যের পরিবর্তে একটি ডিফল্ট মান প্রদান করতে নীল কোলেসেসিং ( ?? ):

let answer:Double = compute(value: 5.5) ?? 0

আমি অন্যান্য পোস্টগুলির সাথে একমত হয়েছি যে প্রতিটি সমস্যার জন্য বিকল্পগুলি সঠিক সরঞ্জাম নয়, তবে এগুলি এড়াতে আপনার প্রয়োজন হবে না। if let ব্যবহার করা if let , guard let , ?? , ইত্যাদি কীভাবে শূন্য মানগুলি পরিচালনা করা হয় বা পাশ দিয়ে যায় তা প্রকাশ করা।