অপশন [টি] শ্রেণীর বিন্দুটি কী?


83

Option[T]স্কালায় আমি ক্লাসের বিন্দুটি বুঝতে পারি না । মানে আমি Noneওভারের কোনও অগ্রগতি দেখতে পাচ্ছি না null

উদাহরণস্বরূপ, কোডটি বিবেচনা করুন:

object Main{
  class Person(name: String, var age: int){
    def display = println(name+" "+age)
  }

  def getPerson1: Person = {
    // returns a Person instance or null
  }

  def getPerson2: Option[Person] = {
    // returns either Some[Person] or None
  }

  def main(argv: Array[String]): Unit = {
    val p = getPerson1
    if (p!=null) p.display

    getPerson2 match{
      case Some(person) => person.display
      case None => /* Do nothing */
    }
  }
}

এখন ধরুন, পদ্ধতিটি getPerson1ফিরে আসে null, তারপরে displayপ্রথম লাইনে করা কলটি mainব্যর্থ হতে বাধ্য NPE। একইভাবে যদি getPerson2ফিরে আসে None, displayকলটি আবার কিছু অনুরূপ ত্রুটির সাথে ব্যর্থ হবে।

যদি তা হয় তবে স্কেল Option[T]জাভাতে ব্যবহৃত সাধারণ পদ্ধতির অনুসরণ না করে কেন নতুন মান র‌্যাপার ( ) প্রবর্তন করে জিনিসগুলিকে জটিল করে তোলে ?

হালনাগাদ:

আমি @ মিচের পরামর্শ অনুসারে আমার কোডটি সম্পাদনা করেছি । আমি এখনও এর কোনও বিশেষ সুবিধা দেখতে পাচ্ছি না Option[T]। আমাকে ব্যতিক্রমী nullবা Noneউভয় ক্ষেত্রেই পরীক্ষা করতে হবে। :(

আমি যদি @ মাইকেল এর উত্তর থেকে সঠিকভাবে বুঝতে পারি তবে এর একমাত্র সুবিধা Option[T]হ'ল এটি স্পষ্টভাবে প্রোগ্রামারকে বলে যে এই পদ্ধতিটি কোনওটিই ফিরিয়ে দিতে পারে না ? এই নকশা পছন্দ পিছনে পিছনে শুধুমাত্র এই কারণ?


23
প্রকৃতপক্ষে, বিকল্প "টি" তে "get" পদ্ধতিটি উচ্চারণ করা হয়েছে: "কেন আপনি এইটির সাথে মিলে যাচ্ছেন না?"
মিচ ব্লেভিনস

4
মিচ ঠিক আছে। ব্যবহার না করে আপনার উদাহরণ পুনরায় লিখে দেওয়ার চেষ্টা করুন getএবং আপনি এটি পেয়ে যাবেন । :-)
ড্যানিয়েল সি সোব্রাল

আপনার কাছে পার্সোন পি আছে .. যা জাভা .. .ট্রাট ভল পি = ... এছাড়াও নীচে ড্যানিয়েল এবং সিনেসো দ্বারা দেখানো বিকল্পের মতো আরও কিছু রয়েছে - এখানে কিছু দুর্দান্ত উত্তর রয়েছে।
মাইকেল নীল

@ মিশেল: উফ! নির্দেশ করার জন্য ধন্যবাদ; এটি সংশোধন।
মিসিংফ্যাক্টর

উত্তর:


72

আপনি Optionনিজেকে কখনই, কখনও ব্যবহার না করার জন্য বাধ্য করলে আপনি আরও ভালো পয়েন্ট পাবেন get। এটি কারণ get"ঠিক আছে, আমাকে নাল-জমিতে ফিরিয়ে দিন" এর সমতুল্য।

সুতরাং, আপনার যে উদাহরণ নিতে। আপনি কিভাবে displayব্যবহার না করে কল করবেন get? এখানে কিছু বিকল্প রয়েছে:

getPerson2 foreach (_.display)
for (person <- getPerson2) person.display
getPerson2 match {
  case Some(person) => person.display
  case _ =>
}
getPerson2.getOrElse(Person("Unknown", 0)).display

এই বিকল্পগুলির কোনওটিই আপনাকে displayএমন কিছুতে কল করতে দেবে না যার অস্তিত্ব নেই।

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


আপনি এখানে পেরেক দিয়েছিলেন:

অপশন [টি] এর একমাত্র সুবিধা হ'ল এটি প্রোগ্রামারকে স্পষ্টভাবে বলে যে এই পদ্ধতিটি কোনওটিই ফিরিয়ে দিতে পারে না?

"শুধুমাত্র" বাদে। তবে আমাকে অন্য উপায়ে এটি পুনরায় ফিরিয়ে আনতে দিন: ওভারের প্রধান সুবিধা হ'ল টাইপ সুরক্ষা। এটি নিশ্চিত করে যে আপনি কোনও কোনও অস্তিত্বের কাছে কোনও পদ্ধতি প্রেরণ করবেন না যা উপস্থিত থাকতে পারে না, কারণ সংকলক আপনাকে অনুমতি দেবে না।Option[T]TT

আপনি বলেছিলেন যে উভয় ক্ষেত্রেই আপনাকে নালিয়াবলীর জন্য পরীক্ষা করতে হবে, তবে আপনি যদি ভুলে যান - বা জানেন না - আপনাকে নাল পরীক্ষা করতে হবে, সংকলক আপনাকে কি বলবে? না আপনার ব্যবহারকারীরা?

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

Optionআমি ভাবতে পারি এর অন্যান্য দুটি গুরুত্বপূর্ণ সুবিধা হ'ল :

  • ডকুমেন্টেশন: কোনও পদ্ধতির ধরণের স্বাক্ষর আপনাকে জানিয়ে দেবে যে কোনও বস্তু সর্বদা ফিরে আসে কি না।

  • মোনাডিক সামঞ্জস্য।

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

for {
  person <- getUsers
  email <- person.getEmail // Assuming getEmail returns Option[String]
} yield (person, email)

4
"নিজেকে কখনই, কখনও ব্যবহার করতে বাধ্য করুন না get" -> সুতরাং, অন্য কথায়: "আপনি এটি করেন না get!" :)
ফ্রেডওভারফ্লো

31

তুলনা করা:

val p = getPerson1 // a potentially null Person
val favouriteColour = if (p == null) p.favouriteColour else null

সঙ্গে:

val p = getPerson2 // an Option[Person]
val favouriteColour = p.map(_.favouriteColour)

পরমাণুসদৃশ্য সম্পত্তি বেঁধে , যা Scala প্রদর্শিত মানচিত্র ফাংশন, কিনা তারা 'নাল' বা না উদ্বেজক ছাড়া বস্তুর উপর চেইন অপারেশন করতে আমাদের পারেন।

এই সাধারণ উদাহরণটি আরও খানিকটা এগিয়ে নিন। বলুন আমরা মানুষের তালিকার সমস্ত পছন্দসই রঙ খুঁজে পেতে চেয়েছিলাম।

// list of (potentially null) Persons
for (person <- listOfPeople) yield if (person == null) null else person.favouriteColour

// list of Options[Person]
listOfPeople.map(_.map(_.favouriteColour))
listOfPeople.flatMap(_.map(_.favouriteColour)) // discards all None's

বা সম্ভবত আমরা কোনও ব্যক্তির পিতার মায়ের বোনের নাম খুঁজে পেতে চাই:

// with potential nulls
val father = if (person == null) null else person.father
val mother = if (father == null) null else father.mother
val sister = if (mother == null) null else mother.sister

// with options
val fathersMothersSister = getPerson2.flatMap(_.father).flatMap(_.mother).flatMap(_.sister)

আমি আশা করি এটি কীভাবে বিকল্পগুলি জীবনকে আরও সহজ করে তুলতে পারে সে সম্পর্কে কিছুটা আলোকপাত করবে।


আপনার শেষ উদাহরণে যদি ব্যক্তির পিতা শূন্য হয়? mapফিরে আসবে Noneএবং কলটি কিছু ত্রুটির সাথে ব্যর্থ হবে। এটি nullপদ্ধতির চেয়ে কীভাবে ভাল ?
মিসিংফ্যাক্টর


6
আমি মনে করি আপনি মানচিত্রের চেয়ে ফ্ল্যাটম্যাপ বলতে চাইছেন।
পুনঃপ্রকাশ

ড্যানিয়েল সম্পাদনার জন্য ধন্যবাদ। কোড পোস্ট করার আগে আমি চেষ্টা করেছিলাম না। পরের বার আরও ভাল করবে।
সিনেসো

4
ভাল ফেভারিটর কলর = যদি (পি == নাল) পি.ফ্যাভারাইটক্লোর অন্য নাল // অবিকল ঠিক যে ত্রুটিটি আপনাকে এড়াতে সহায়তা করে! কেউ এই ত্রুটি চিহ্নিত না করে এই উত্তরটি এখানে বছরের পর বছর ধরে রয়েছে!
মার্ক লিস্টার

22

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

তবে, ব্যবহারিক অর্থে, আপনি যখন এমন কোনও ফাংশন কল করেন যা optionচ্ছিকভাবে কিছু ফিরিয়ে দেয়, আপনি যা করবেন:

getPerson2 match {
   case Some(person) => //handle a person
   case None => //handle nothing 
}

মঞ্জুর, আপনি শূন্যের সাথেও অনুরূপ কিছু করতে পারেন - তবে getPerson2এটি প্রত্যাবর্তনের সত্যতার কারণে কলিংয়ের শব্দার্থকে স্পষ্ট করে তোলে Option[Person](একটি দুর্দান্ত ব্যবহারিক জিনিস, ডকটি পড়ার সাথে কারও উপর নির্ভর করা এবং এনপিই পাওয়ার কারণ অন্যথায় তারা পড়েনি) ডক)।

আমি চেষ্টা করব এবং একটি কার্যনির্বাহী প্রোগ্রামার খনন করব যিনি আমার চেয়ে কড়া উত্তর দিতে পারেন।


4
এটি অপশন সম্পর্কে আমার বোঝাপড়া। এটি স্পষ্টভাবে প্রোগ্রামারকে বলেছে যে আমরা কোনওটিই পেতে পারি না এবং আপনি যদি কিছু (টি) করার কথা মনে রাখার মতো বোকাম হন তবে কোনওটিই ধরেন না তবে আপনি সমস্যায় পড়েছেন।
cflewis

4
লুইশাম - আমি মনে করি সংকলকটি আপনাকে / হিসাবে কোনটি বীজগণিতের ডেটা টাইপ (বিমূর্ত সিল করা বৈশিষ্ট্য ...) তৈরি করে (কিন্তু আমি এখানে স্মৃতি থেকে যাচ্ছি) হিসাবে আপনাকে একটি সতর্কতা দেবে।
মাইকেল নীল

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

15

আমার জন্য বিকল্পগুলি বোধগম্য সিনট্যাক্সের সাথে পরিচালিত হলে সত্যই আকর্ষণীয়। পূর্ববর্তী উদাহরণ সিনেসো গ্রহণ :

// with potential nulls
val father = if (person == null) null else person.father
val mother = if (father == null) null else father.mother
val sister = if (mother == null) null else mother.sister

// with options
val fathersMothersSister = for {
                                  father <- person.father
                                  mother <- father.mother
                                  sister <- mother.sister
                               } yield sister

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


4
এটি লজ্জার বিষয় যে স্কালায় <-সিনট্যাক্সটি "তালিকা বোঝার সিনট্যাক্স" এর মধ্যে সীমাবদ্ধ, কারণ এটি doহ্যাশেল থেকে আরও সাধারণ বাক্য গঠন বা domonadক্লোজারের মনাদ লাইব্রেরির ফর্মের মতোই । তালিকাগুলিতে এটি বেঁধে দেওয়া এটি স্বল্প বিক্রি করে।
সেহ

11
স্কেলে "বোঝার জন্য" মূলত হাস্কেলের "কর" হ'ল, সেগুলি তালিকাগুলির মধ্যে সীমাবদ্ধ নয়, আপনি যে কোনও প্রয়োগ করে তা ব্যবহার করতে পারেন: ডিএফ মানচিত্র [বি] (চ: এ => বি): সি [বি] ডিফ ফ্ল্যাটম্যাপ [বি] (চ: এ => সি [বি]): সি [বি] ডিএফ ফিল্টার (পি: এ => বুলিয়ান): সি [এ]।
আইওডাব্লু

4
@ সেঃ আমি @ জিসারামুন্টের মন্তব্যকে সমর্থন করেছিলাম, তবে আমি তার বক্তব্যটির পক্ষে যথেষ্ট জোর দিতে পারি না। নেই কোন সাবেক সঙ্গে চিঠি আবার ব্যবহারযোগ্য ছাড়া - স্কেল এ জন্য-comprehensions এবং তালিকা মধ্যে সংযোগ। আমি আপনাকে স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি ১০০৪২7676//২ উল্লেখ করি ।
ড্যানিয়েল সি সোব্রাল

হ্যাঁ, আমি জানি যে কোনও সম্পর্ক নেই, তবে আমি সম্মত হই যে এটি উল্লেখ করার মতো; আমি এই উত্তরের প্রথম লাইনে মন্তব্য করছিলাম, যেখানে প্যারাডিজমেটিক "তালিকা বোঝার সিনট্যাক্স" উল্লেখ করেছে। এটি ভাষা শেখার সমস্যার বিপরীতে, এটি একটি শিক্ষণ সমস্যা problem
সেহ

9

অপশন সহ আপনার কাছে বেশ শক্তিশালী রচনা ক্ষমতা রয়েছে:

def getURL : Option[URL]
def getDefaultURL : Option[URL]


val (host,port) = (getURL orElse getDefaultURL).map( url => (url.getHost,url.getPort) ).getOrElse( throw new IllegalStateException("No URL defined") )

আপনি এই পুরোপুরি ব্যাখ্যা করতে পারেন?
জেসভিন জোস

8

হয়তো অন্য কেউ এটি দেখিয়েছিল, কিন্তু আমি এটি দেখতে পাইনি:

অপশন [টি] বনাম নাল চেকিংয়ের সাথে প্যাটার্ন-মিলের একটি সুবিধা হ'ল বিকল্পটি সিল করা শ্রেণি, সুতরাং স্কাল সংকলক একটি সতর্কতা জারি করবে যদি আপনি কোনওটি বা কোনওটি নয় ক্ষেত্রেই অবহেলা করেন। সংকলকটিতে একটি সংকলক পতাকা রয়েছে যা সতর্কতাগুলিকে ত্রুটিতে পরিণত করবে। সুতরাং রানটাইমের পরিবর্তে সংকলন সময়ে "অস্তিত্ব নেই" কেস পরিচালনা করতে ব্যর্থতা রোধ করা সম্ভব। নাল মানটি ব্যবহারের ক্ষেত্রে এটি একটি বিশাল সুবিধা।


7

নাল চেক এড়াতে সাহায্য করার জন্য এটি নেই, নাল চেকটি জোর করার জন্য এটি রয়েছে। আপনার ক্লাসে 10 টি ক্ষেত্র থাকলে বিষয়টি পরিষ্কার হয়ে যায়, এর মধ্যে দুটি শূন্য হতে পারে। এবং আপনার সিস্টেমে 50 টি একই জাতীয় ক্লাস রয়েছে। জাভা বিশ্বে, আপনি সেই ক্ষেত্রগুলিতে কিছু মানসিক horesep শক্তি, নামকরণ কনভেনশন, বা এমনকি টীকাগুলি ব্যবহার করে এনপিইগুলিকে প্রতিরোধ করার চেষ্টা করছেন। এবং প্রতিটি জাভা দেব এটিতে একটি গুরুত্বপূর্ণ ডিগ্রীতে ব্যর্থ হয়। বিকল্প শ্রেণীটি কোনও বিকাশকারীকে কোড বোঝার চেষ্টা করছে না শুধুমাত্র "নল" মানগুলি দৃশ্যমানভাবে পরিষ্কার করে না, তবে সংকলকটিকে এই পূর্বে অব্যক্ত চুক্তিটি প্রয়োগ করার অনুমতি দেয়।


6

[থেকে অনুলিপি এই মন্তব্যটি দ্বারা ড্যানিয়েল Spiewak ]

যদি Optionমানগুলি বের করার জন্য যদি একমাত্র উপায় প্যাটার্ন ম্যাচ হয় তবে হ্যাঁ, আমি সম্মত হই যে এটি কোনওভাবেই নষ্ট হয় না। তবে আপনি এর কার্যকারিতাটির একটি বিশাল * শ্রেণি অনুপস্থিত। Optionআপনি যদি এর উচ্চতর-আদেশের ইউটিলিটি ফাংশন ব্যবহার করেন তবে কেবলমাত্র বাধ্য করার কারণ । কার্যকরভাবে, আপনি এর monadic প্রকৃতি ব্যবহার করা প্রয়োজন। উদাহরণস্বরূপ (একটি নির্দিষ্ট পরিমাণের API ট্রিমিং অনুমান করে):

val row: Option[Row] = database fetchRowById 42
val key: Option[String] = row flatMap { _ get “port_key” }
val value: Option[MyType] = key flatMap (myMap get)
val result: MyType = value getOrElse defaultValue

সেখানে, নিফটি ছিল না? আমরা যদি forসংজ্ঞাগুলি ব্যবহার করি তবে আমরা আসলে আরও অনেক কিছু করতে পারি:

val value = for {
row <- database fetchRowById 42
key <- row get "port_key"
value <- myMap get key
} yield value
val result = value getOrElse defaultValue

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

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

আমার অর্থ ট্রোল হাতুড়ি হওয়ার অর্থ নয়, তবে ভাষা ব্যবহারের বৈশিষ্ট্যগুলি কীভাবে * বাস্তবে * আপনাকে ব্যবহারহীন বলে দোষ দেওয়ার আগে অনুশীলনে ব্যবহৃত হয় তা আপনার সত্যই দেখতে হবে। আমি পুরোপুরি সম্মত হই যে বিকল্পটি * আপনি এটি ব্যবহার করার সাথে সাথে একেবারেই আপত্তিজনক নয় তবে আপনি এটি যেভাবে ডিজাইন করেছিলেন সেভাবে ব্যবহার করছেন না।


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

4
আমি মনে করি আপনি স্কালার বোঝার জন্য ভুল বোঝেন। দ্বিতীয় উদাহরণটি দৃ emp়রূপে একটি লুপ নয়, এটি প্রথম উদাহরণ অনুসারে এটি সংকলক দ্বারা ফ্ল্যাটম্যাপ ক্রিয়াকলাপগুলির একটি সিরিজে অনুবাদ করেছে।
কেভিন রাইট

আমি এখানে আমার মন্তব্য লেখার পরে অনেক দিন হয়েছে, তবে আমি কেবল কেভিনের দেখেছি। কেভিন, আপনি যখন লেখেন "আপনি ভুল বোঝেন?" আপনি কাকে উল্লেখ করছেন? আমি দেখতে পাচ্ছি না কিভাবে এটা হতে পারত আমাকে , আমি একটি লুপ সম্পর্কে কিছু উল্লেখ না।
Seh

6

একটি বিষয় যা এখানে অন্য কেউ উত্থাপিত হয়েছে বলে মনে হচ্ছে তা হ'ল আপনার নাল রেফারেন্স থাকতে পারে, অপশনটি একটি পার্থক্য প্রবর্তন করে।

যে আপনি করতে পারেন Option[Option[A]], বাস করা হবে যা None, Some(None)এবং Some(Some(a))যেখানে aস্বাভাবিক বাসিন্দাদের অন্যতম A। এর অর্থ হ'ল যদি আপনার কাছে কোনও ধরণের ধারক থাকে এবং আপনি এটিতে নাল পয়েন্টারগুলি সঞ্চয় করতে এবং সেগুলি পেতে সক্ষম হতে চান তবে আপনাকে আসলে কোনও মান খুঁজে পেয়েছে কিনা তা জানার জন্য আপনাকে কিছু অতিরিক্ত বুলিয়ান মান ফিরে করতে হবে। ভালো warts উড়া জাভা পাত্রে API গুলিতে এবং কিছু লক-বিনামূল্যে রূপগুলো এমনকি তাদের প্রদান করতে পারেন না।

null এটি একটি একযোগে নির্মাণ, এটি নিজের সাথে রচনা করে না, এটি কেবলমাত্র রেফারেন্স ধরণের জন্য উপলভ্য, এবং এটি আপনাকে একটি সম্পূর্ণ-সম্পূর্ণ ফ্যাশনে যুক্তি দিতে বাধ্য করে forces

উদাহরণস্বরূপ, আপনি যখন পরীক্ষা করেন

if (x == null) ...
else x.foo()

আপনাকে পুরো elseশাখা জুড়ে আপনার মাথায় নিয়ে যেতে হবে এবং x != nullএটি ইতিমধ্যে যাচাই করা হয়েছে। যাইহোক, বিকল্প কিছু ব্যবহার করার সময়

x match {
case None => ...
case Some(y) => y.foo
}

আপনি জানেন যেNone নির্মাণের দ্বারা নয় - এবং আপনি যদি জানতেন nullযে এটি হ'র বিলিয়ন ডলার ভুল না হয়ে থাকে তবে তা হয় না ।


3

বিকল্প [টি] একটি মোনাড, যা আপনি যখন মানগুলি হেরফের করার জন্য উচ্চ-অর্ডার ফাংশনগুলি ব্যবহার করেন তখন সত্যিই কার্যকর।

আমি আপনাকে নীচের তালিকাভুক্ত নিবন্ধগুলি পড়ার পরামর্শ দিচ্ছি, সেগুলি সত্যিই ভাল নিবন্ধ যা আপনাকে দেখায় যে বিকল্প [টি] কেন কার্যকর এবং এটি কীভাবে কার্যকরী উপায়ে ব্যবহার করা যেতে পারে।


আমি সুপারিশ পঠন তালিকায় টনি মরিস যোগ করব 'সম্প্রতি প্রকাশিত টিউটোরিয়াল "কি একসংখ্যা মানে?": Projects.tmorris.net/public/what-does-monad-mean/artifacts/1.0/...
রান্ডাল Schulz

3

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

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


ধন্যবাদ লিঙ্কের জন্য অনেক। এটা সত্যিই দরকারী ছিল। :)
অনুপস্থিত ফ্যাক্টর

থ্রেডে আপনার মন্তব্যটি এত সংক্ষিপ্ত ছিল আমি এর বক্তব্যটি প্রায় মিস করেছি। আমি সত্যিই নাল নিষিদ্ধ হতে পারে ইচ্ছুক।
আলাইন ও'ডিয়া

2

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

নাল সমস্যাটি হ'ল এটি কোনও জিনিসের অভাব । এর কোনও পদ্ধতি নেই যা আপনাকে এটির মোকাবেলায় সহায়তা করতে পারে (যদিও ভাষা ডিজাইনার হিসাবে আপনি আপনার ভাষায় বৈশিষ্ট্যগুলির ক্রমবর্ধমান দীর্ঘ তালিকা যুক্ত করতে পারেন যা কোনও বস্তুকে অনুকরণ করে যদি আপনি সত্যিই এটির মতো অনুভব করেন)।

অপশনটি যে কাজটি করতে পারে তা যেমন আপনি প্রদর্শন করেছেন, তা হল নালাকে অনুকরণ করা; তারপরে আপনাকে অসাধারণ মান "নাল" এর পরিবর্তে অসাধারণ মান "কিছুই নয়" পরীক্ষা করতে হবে। যদি আপনি ভুলে যান তবে উভয় ক্ষেত্রেই খারাপ জিনিসগুলি ঘটবে। বিকল্পটি দুর্ঘটনার কারণে এটি হওয়ার সম্ভাবনা কম করে তোলে, যেহেতু আপনাকে "get" টাইপ করতে হবে (এটি আপনাকে মনে করিয়ে দেবে যে এটি নাল হতে পারে , আমার অর্থ কিছুই নয়), তবে এটি অতিরিক্ত র‍্যাপার অবজেক্টের বিনিময়ে এটি একটি ছোট সুবিধা benefit ।

অপশনটি সত্যই এর শক্তিটি প্রদর্শন করতে শুরু করে যেখানে আপনাকে আই-ওয়ান্টড-কিছু-তবে-আমি-না-আসলে-ধারণার সাথে ডিল করতে সহায়তা করে helping

আসুন এমন কিছু জিনিস বিবেচনা করুন যা আপনি শূন্য হতে পারে এমন জিনিসগুলির সাথে করতে পারেন।

আপনার যদি শূন্য থাকে তবে আপনি একটি ডিফল্ট মান সেট করতে চান। আসুন জাভা এবং স্কালার তুলনা করা যাক:

String s = (input==null) ? "(undefined)" : input;
val s = input getOrElse "(undefined)"

কিছুটা অসুবিধার জায়গায়?: আমাদের একটি পদ্ধতি রয়েছে যা "আমি যদি নਾਲ হয় তবে একটি ডিফল্ট মান ব্যবহার করি" এই ধারণার সাথে মিলিত হয় ruct এটি আপনার কোডটি কিছুটা সাফ করে।

আপনার যদি সত্যিকারের মান থাকে তবেই আপনি একটি নতুন অবজেক্ট তৈরি করতে চান। তুলনা করা:

File f = (filename==null) ? null : new File(filename);
val f = filename map (new File(_))

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

এটি কোনও বিস্তৃত উন্নতি নয়, তবে আপনি যদি সমস্ত কিছু যুক্ত করেন তবে সর্বত্র এটি খুব উপযুক্ত very

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

val a = List(Some("Hi"),None,Some("Bye"));
a match {
  case List(Some(x),_*) => println("We started with " + x)
  case _ => println("Nothing to start with.")
}

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


2

নাল রিটার্ন মানগুলি কেবল জাভার সাথে সামঞ্জস্যের জন্য উপস্থিত। আপনার অন্যথায় এটি ব্যবহার করা উচিত নয়।


1

এটি সত্যিই একটি প্রোগ্রামিং শৈলীর প্রশ্ন। ফাংশনাল জাভা ব্যবহার করে বা আপনার নিজের সহায়ক পদ্ধতিগুলি লিখে আপনার জাতির বিকল্পটি কার্যকর করতে পারে তবে জাভা ভাষাটি বর্জন করতে পারবেন না:

http://functionaljava.org/example/#Option.bind

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


0

অগ্রিম স্বীকার করে নেওয়া যে এটি একটি গ্লীব উত্তর, অপশনটি একটি মোনাদ।


আমি জানি এটি একটি মোনাড। কেন আমি প্রশ্নে একটি "মোনাড" ট্যাগ অন্তর্ভুক্ত করব?
অনুপস্থিত ফ্যাক্টর

Above উপরের বিবৃতিটির অর্থ এই নয় যে আমি বুঝতে পারি যে একটি মোনাড কী। : ডি
মিসিংফ্যাক্টর

4
মনডস শীতল। আপনি যদি সেগুলি ব্যবহার না করেন বা কমপক্ষে বোঝার ভান না করেন তবে আপনি শীতল নন ;-)
প্যারডিজমেটিক

0

আসলে আমি সন্দেহটি আপনার সাথে ভাগ করে নিই। অপশন সম্পর্কে এটি সত্যিই আমাকে বিরক্ত করে যে 1) ওভারহেডের একটি পারফরম্যান্স রয়েছে, কারণ সেখানে প্রত্যেকের তৈরি "কিছু" র‌্যাপার রয়েছে। 2) আমার কোডে আমাকে প্রচুর ও বিকল্প ব্যবহার করতে হবে।

সুতরাং এই ভাষা নকশা সিদ্ধান্তের সুবিধার এবং অসুবিধাগুলি দেখার জন্য আমাদের বিকল্পগুলি বিবেচনা করা উচিত। জাভা যেমন শূন্যতার সমস্যাটিকে উপেক্ষা করে, এটি বিকল্প নয়। আসল বিকল্পটি ফ্যান্টম প্রোগ্রামিং ভাষা সরবরাহ করে। সেখানে nullable এবং নন-অকেজো প্রকার রয়েছে এবং? ?: স্কেলার মানচিত্র / ফ্ল্যাটম্যাপ / getOrElse এর পরিবর্তে অপারেটরগুলি। তুলনা করে আমি নীচের বুলেটগুলি দেখছি:

বিকল্পের সুবিধা:

  1. সহজ ভাষা - কোনও অতিরিক্ত ভাষা নির্মাণের প্রয়োজন নেই
  2. অন্যান্য monadic ধরণের সঙ্গে ইউনিফর্ম

নলেবলের সুবিধা:

  1. সাধারণ ক্ষেত্রে সংক্ষিপ্ত বাক্য গঠন
  2. আরও ভাল পারফরম্যান্স (যেমন আপনাকে মানচিত্রের জন্য নতুন অপশন অবজেক্ট এবং ল্যাম্বডাস তৈরি করতে হবে না, ফ্ল্যাটম্যাপ)

সুতরাং এখানে কোন সুস্পষ্ট বিজয়ী নেই। এবং আরও একটি নোট। অপশনটি ব্যবহারের জন্য কোনও প্রধান সিন্থেটিক সুবিধা নেই। আপনি এর মতো কিছু সংজ্ঞায়িত করতে পারেন:

def nullableMap[T](value: T, f: T => T) = if (value == null) null else f(value)

বা বিন্দু দিয়ে pritty সিনট্যাক্স পেতে কিছু অন্তর্নিহিত রূপান্তর ব্যবহার করুন।


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

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

0

সুস্পষ্ট বিকল্পের ধরণের আসল সুবিধা হ'ল আপনি এগুলিকে সব জায়গাতেই 98% ব্যবহার করতে পারবেন না এবং এভাবে স্থিরভাবে নাল ব্যতিক্রমগুলি সরিয়ে ফেলতে পারবেন। (এবং অন্যান্য 2% তে টাইপ সিস্টেম আপনাকে প্রকৃতপক্ষে অ্যাক্সেস করার সময় সঠিকভাবে পরীক্ষা করার জন্য মনে করিয়ে দেয়))


-3

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

জাভাতে আপনার এই ধরণের বাক্সযুক্ত সংস্করণগুলি (পূর্ণসংখ্যা, ...) ব্যবহার করা দরকার to

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