স্কালায় একটি ভেরি এবং ভাল সংজ্ঞা মধ্যে পার্থক্য কি?


301

স্কালায় একটি varএবং valসংজ্ঞা মধ্যে পার্থক্য কী এবং ভাষা উভয়ের কেন প্রয়োজন? আপনি কেন একটি valওভার varএবং তার বিপরীতে নির্বাচন করবেন?

উত্তর:


331

যেমনটি আরও অনেকে বলেছেন, ক্যানকে বরাদ্দ করা বস্তু valপ্রতিস্থাপন করা যায় না এবং ক্যানকে বরাদ্দ করা বস্তুটিও প্রতিস্থাপন করা যায় varনা। তবে, বলেন বস্তুটির এর অভ্যন্তরীণ অবস্থা পরিবর্তন করা যেতে পারে। উদাহরণ স্বরূপ:

class A(n: Int) {
  var value = n
}

class B(n: Int) {
  val value = new A(n)
}

object Test {
  def main(args: Array[String]) {
    val x = new B(5)
    x = new B(6) // Doesn't work, because I can't replace the object created on the line above with this new one.
    x.value = new A(6) // Doesn't work, because I can't replace the object assigned to B.value for a new one.
    x.value.value = 6 // Works, because A.value can receive a new object.
  }
}

সুতরাং, যদিও আমরা নির্ধারিত অবজেক্টটি পরিবর্তন করতে পারি না x, আমরা সেই অবজেক্টের অবস্থা পরিবর্তন করতে পারি। এর মূলে অবশ্য ক var

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

x = new B(0)
f(x)
if (x.value.value == 0)
  println("f didn't do anything to x")
else
  println("f did something to x")

এটি মাল্টিথ্রেডেড সিস্টেমগুলির সাথে বিশেষভাবে গুরুত্বপূর্ণ হয়ে ওঠে। বহুবিবাহিত সিস্টেমে নিম্নলিখিতগুলি ঘটতে পারে:

x = new B(1)
f(x)
if (x.value.value == 1) {
  print(x.value.value) // Can be different than 1!
}

যদি আপনি valএকচেটিয়াভাবে ব্যবহার করেন এবং কেবলমাত্র অপরিবর্তনীয় ডেটা স্ট্রাকচার ব্যবহার করেন (এটি হ'ল অ্যারে, সমস্ত কিছু এড়ানো scala.collection.mutableইত্যাদি) তবে আপনি নিশ্চিন্ত থাকতে পারেন যে এটি ঘটবে না। এটি হ'ল কিছু কোড না থাকলে, সম্ভবত একটি কাঠামো, প্রতিবিম্বের কৌশলগুলি না করে - প্রতিচ্ছবি দুর্ভাগ্যক্রমে "অপরিবর্তনীয়" মান পরিবর্তন করতে পারে।

এটি একটি কারণ, তবে এর আরও একটি কারণ রয়েছে। আপনি যখন ব্যবহার করবেন তখন একাধিক উদ্দেশ্যে varএকই ব্যবহার করতে প্রলুব্ধ হতে পারেন var। এতে কিছু সমস্যা রয়েছে:

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

সহজ কথায় বলতে গেলে, ব্যবহার valকরা নিরাপদ এবং আরও পঠনযোগ্য কোডের দিকে নিয়ে যায়।

আমরা তখন অন্য দিকে যেতে পারি। যদি valএটি আরও ভাল হয় তবে কেন varসব কিছু আছে? ঠিক আছে, কিছু ভাষাগুলি সেই পথটি নিয়েছে তবে এমন পরিস্থিতি রয়েছে যেখানে পরিবর্তনের ফলে কর্মক্ষমতা অনেকটা উন্নত হয়।

উদাহরণস্বরূপ, একটি অপরিবর্তনীয় গ্রহণ করুন Queue। আপনি enqueueবা dequeueএটিতে জিনিসগুলি এলে আপনি একটি নতুন Queueঅবজেক্ট পাবেন। তাহলে কীভাবে, আপনি এতে সমস্ত আইটেম প্রক্রিয়াজাতকরণ করবেন?

আমি একটি উদাহরণ দিয়ে যাব। ধরা যাক আপনার কাছে অঙ্কগুলির একটি সারি রয়েছে এবং আপনি সেগুলির মধ্যে একটি সংখ্যা রচনা করতে চান। উদাহরণস্বরূপ, যদি আমার 2, 1, 3 এর সাথে এই ক্রম থাকে তবে আমি 213 নম্বরটি ফিরে পেতে চাই Let's প্রথমে এটির সাথে সমাধান করুন mutable.Queue:

def toNum(q: scala.collection.mutable.Queue[Int]) = {
  var num = 0
  while (!q.isEmpty) {
    num *= 10
    num += q.dequeue
  }
  num
}

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

এখন, এটি একটিতে আবৃত করুন immutable.Queue:

def toNum(q: scala.collection.immutable.Queue[Int]) = {
  def recurse(qr: scala.collection.immutable.Queue[Int], num: Int): Int = {
    if (qr.isEmpty)
      num
    else {
      val (digit, newQ) = qr.dequeue
      recurse(newQ, num * 10 + digit)
    }
  }
  recurse(q, 0)
}

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

তবে নোট করুন, আমি একই কোডটি একই সাথে immutable.Queueএকটি ব্যবহার করতে আবার লিখতে পারি var! উদাহরণ স্বরূপ:

def toNum(q: scala.collection.immutable.Queue[Int]) = {
  var qr = q
  var num = 0
  while (!qr.isEmpty) {
    val (digit, newQ) = qr.dequeue
    num *= 10
    num += digit
    qr = newQ
  }
  num
}

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

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

ব্যক্তিগতভাবে, আমি মনে করি স্কাল আপাতত সঠিক ব্যালেন্সকে আঘাত করে strikes এটি এখন পর্যন্ত নিখুঁত নয়। আমি মনে করি ক্লোজার এবং হাস্কেল উভয়েরই খুব আকর্ষণীয় ধারণা রয়েছে যা স্কালার দ্বারা গৃহীত হয়নি, তবে স্কালার নিজস্ব শক্তিও রয়েছে। ভবিষ্যতে কী ঘটবে তা আমরা দেখব।


কিছুটা দেরি হয়ে গেছে, কিন্তু ... var qr = qএকটি অনুলিপি তৈরি করে q?

5
@ ডেভিপস এটি দ্বারা রেফারেন্স করা বস্তুর অনুলিপি তৈরি করে না q। এটি কোনও অনুলিপি তৈরি করে - স্ট্যাকের উপর, গাদা নয় - সেই বস্তুর উল্লেখ । পারফরম্যান্সের ক্ষেত্রে, আপনি কী "এটি" বলছেন সে সম্পর্কে আপনাকে আরও পরিষ্কার হতে হবে।
ড্যানিয়েল সি সোব্রাল

ঠিক আছে, আপনার সহায়তা এবং কিছু তথ্য ( (x::xs).drop(1)হুবহু xs, এর "অনুলিপি নয়" xs) দিয়ে আমি বুঝতে পারি যে এখানে লিঙ্কটি । tnx!

"এই কোডটি এখনও কার্যকর" - এটি কি? যেহেতু qrঅপরিবর্তনীয় সারি, তাই যতবার অভিব্যক্তি qr.dequeueবলা হয় এটি একটি করে তোলে new Queue(দেখুন < github.com/scala/scala/blob/2.13.x/src/library/scala/collection/… )।
ওয়েন

@ ওঁ হ্যাঁ, তবে লক্ষ্য করুন যে এটি একটি অগভীর জিনিস। কোডটি এখনও ও (এন) পরিবর্তনযোগ্য কিনা, আপনি যদি সারিটি অনুলিপি করেন, বা অপরিবর্তনীয়।
ড্যানিয়েল সি। সোব্রাল

61

valচূড়ান্ত, যে সেট করা যাবে না। জাবা finalভাবি।


3
তবে আমি যদি সঠিকভাবে বুঝতে পারি (কোনও স্কাল বিশেষজ্ঞ নয়), val ভেরিয়েবলগুলি অপরিবর্তনীয়, তবে তারা যে বস্তুগুলি উল্লেখ করে সেগুলি হওয়া উচিত নয়। স্টিফান পোস্ট করা লিংক অনুসারে: "এখানে নামের রেফারেন্সটি অন্য অ্যারেতে চিহ্নিত করার জন্য পরিবর্তন করা যায় না, তবে অ্যারে নিজেই পরিবর্তন করা যায় other অন্য কথায় অ্যারের সামগ্রী / উপাদানগুলি পরিবর্তন করা যায়।" সুতরাং এটি finalজাভাতে কাজ করে।
ড্যানিয়েল প্রাইডেন

3
ঠিক কেন আমি এটি পোস্ট করেছি it আমি ঠিক +=একটি valসূক্ষ্ম হিসাবে সংজ্ঞায়িত একটি পরিবর্তনশীল হ্যাশম্যাপে কল করতে পারি - আমি বিশ্বাস করি finalজাভাতে এটি ঠিক কীভাবে কাজ করে
জ্যাকসন ডেভিস

হ্যাঁ, আমি ভেবেছিলাম বিল্ট-ইন স্কালাল ধরণেরগুলি কেবল পুনরায় নিয়োগের অনুমতি দেওয়ার চেয়ে আরও ভাল করতে পারে। আমার ফ্যাক্ট-চেক করা দরকার
স্টিফান কেন্ডাল

আমি সাধারণ ধারণার সাথে স্কেলার অপরিবর্তনীয় সিকোয়েন্স প্রকারগুলিকে গুলিয়ে ফেলছিলাম। ফাংশনাল প্রোগ্রামিং আমাকে সব ঘুরিয়ে দিয়েছে।
স্টেফান কেন্ডাল

আমি আপনার উত্তরে একটি ডামি চরিত্র যুক্ত করেছি এবং মুছে ফেলেছি যাতে আমি আপনাকে উত্সাহ দিতে পারি।
স্টিফান কেন্ডাল


20

পার্থক্যটি হ'ল varএকটিকে আবার নিয়োগ দেওয়া যেতে পারে যেখানে একটি valপারে না। পরিবর্তন বা অন্যথায় যা যা বাস্তবে নির্ধারিত তা হ'ল একটি পার্শ্ব সমস্যা:

import collection.immutable
import collection.mutable
var m = immutable.Set("London", "Paris")
m = immutable.Set("New York") //Reassignment - I have change the "value" at m.

যেখানে:

val n = immutable.Set("London", "Paris")
n = immutable.Set("New York") //Will not compile as n is a val.

এবং অতঃপর:

val n = mutable.Set("London", "Paris")
n = mutable.Set("New York") //Will not compile, even though the type of n is mutable.

যদি আপনি কোনও ডেটা কাঠামো তৈরি করে থাকেন এবং এর সমস্ত ক্ষেত্র একই হয় val, তবে সেই ডেটা স্ট্রাকচারটি তাই পরিবর্তনযোগ্য, কারণ এর রাজ্য পরিবর্তন করতে পারে না।


1
এটি কেবল সত্য যদি সেই ক্ষেত্রগুলির শ্রেণিগুলি পাশাপাশি অপরিবর্তনীয় হয়।
ড্যানিয়েল সি সোব্রাল

হ্যাঁ - আমি এটি toোকাতে যাচ্ছিলাম তবে আমি ভেবেছিলাম এটি খুব দূরেও হতে পারে! এটি আমি একটি যুক্তিযুক্ত বিষয়ও বলব; এক দৃষ্টিকোণ থেকে (যদিও কার্যকরী নয়) তার রাজ্যটি তার রাজ্যের অবস্থা হলেও পরিবর্তন হয় না।
অক্সবো_লেকস

কেন এখনও জেভিএম ভাষায় একটি অপরিবর্তনীয় বস্তু তৈরি করা এত কঠিন? তদুপরি, স্ক্যালাল কেন ডিফল্টরূপে অবজেক্টগুলিকে অপরিবর্তনীয় করে তুলল না?
ডেরেক মাহর

19

valঅর্থ varপরিবর্তনযোগ্য এবং এর অর্থ পরিবর্তনযোগ্য means

পুরো আলোচনা।


1
এটি ঠিক সত্য নয়। সংযুক্ত নিবন্ধটি একটি পরিবর্তনীয় অ্যারে দেয় এবং একে অপরিবর্তনীয় বলে calls কোন গুরুতর উত্স।
ক্লাউস শুল্জ

সত্য সত্য নয়। যে Val খ = এরে [ইন্টারঅ্যাক্টিভ] (1,2,3) খ (0) = 4 println (b.mkString ( "")) println ( "") ব্যবহার করে দেখুন
Guillaume,

13

সি ++ এর দিক দিয়ে চিন্তা করা,

val x: T

অ-ধ্রুবক ডেটাতে ধ্রুবক পয়েন্টারের সাথে সাদৃশ্য

T* const x;

যখন

var x: T 

অ-ধ্রুবক ডেটার সাথে ধ্রুবক পয়েন্টারটির সাথে সাদৃশ্য

T* x;

পক্ষপাতী valউপরvar কোডবেস যা তার শুদ্ধি, সম্পাতবিন্দু এবং ক্ষমতা বোঝার সুবিধার করতে পারেন অপরিবর্তনীয়তা বৃদ্ধি পায়।

অ-ধ্রুবক ডেটাতে ধ্রুবক পয়েন্টার থাকার অর্থ বোঝার জন্য নিম্নলিখিত স্কাল স্নিপেটটি বিবেচনা করুন:

val m = scala.collection.mutable.Map(1 -> "picard")
m // res0: scala.collection.mutable.Map[Int,String] = HashMap(1 -> picard)

এখানে "পয়েন্টার" val m ধ্রুবক তাই আমরা এর মতো অন্য কোনও কিছুতে এটি পুনর্নির্দিষ্ট করতে পারি না

m = n // error: reassignment to val

তবে আমরা প্রকৃতপক্ষে অ-ধ্রুবক ডেটা নিজেই পরিবর্তন করতে পারি যা mএটি পছন্দ করে

m.put(2, "worf")
m // res1: scala.collection.mutable.Map[Int,String] = HashMap(1 -> picard, 2 -> worf)

1
আমি মনে করি স্কালা তার চূড়ান্ত উপসংহারে অপরিবর্তনীয়তা গ্রহণ করেনি: ধ্রুবক পয়েন্টার এবং ধ্রুবক ডেটা। ডিফল্টরূপে বস্তুগুলি অপরিবর্তনীয় করে তোলার সুযোগটি স্কালার হাতছাড়া হয়। ফলস্বরূপ, স্কালার কাছে হ্যাস্কেলের মতো মানের মতো ধারণা নেই।
ডেরেক মাহর

@ ডেরেকমাহার আপনি ঠিক বলেছেন, তবে কোনও বস্তু নিজেকে পুরোপুরি অপরিবর্তনীয় হিসাবে উপস্থাপন করতে পারে, তবুও তার প্রয়োগের ক্ষেত্রে পরিবর্তনের জন্য যেমন কার্য সম্পাদনের কারণে using সংকলক কীভাবে সত্য পরিবর্তন এবং কেবল অভ্যন্তরীণ-কেবল পরিবর্তনের মধ্যে পৃথক করতে সক্ষম হবে?
ফ্র্যাঙ্কোসার

8

"ভ্যাল মানে অপরিবর্তনীয় এবং ভের অর্থ পরিবর্তনীয়" "

প্যারাফ্রেজ করতে, "ভাল মানে মান এবং ভেরিয়েবলের পরিবর্তনশীল"।

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


এই কারণেই আমি জাফলের চেয়ে হাস্কেলকে পছন্দ করি।
ডেরেক মাহর

6

ভ্যাল অর্থ অপরিবর্তনীয় এবং ভের অর্থ পরিবর্তনীয়

আপনি valজাভা প্রোগ্রামিং ভাষার finalকী ওয়ার্ল্ড বা সি ++ ভাষার constকী ওয়ার্ল্ড হিসাবে ভাবতে পারেন 。


1

Valতার চূড়ান্ত মানে , হতে পারে না পুনরায় নিয়োগ দেওয়া

তবে, পরে পুনরায় নিয়োগ দেওয়াVar যেতে পারে ।


1
ইতিমধ্যে জমা দেওয়া 12 টি উত্তর থেকে এই উত্তর কীভাবে আলাদা?
jwvh

0

এটি নাম হিসাবে এটি সহজ।

var মানে এটি পরিবর্তিত হতে পারে

ভাল মানে অদৃশ্য


0

মান - মানগুলি টাইপ করা স্টোরেজ ধ্রুবক। একবার এটির মান ক্যান্ট তৈরি হয়ে গেলে তাকে পুনরায় নিয়োগ দেওয়া হবে। একটি নতুন মান কীওয়ার্ড ভাল দিয়ে সংজ্ঞায়িত করা যায়।

যেমন। ভাল এক্স: ইন্ট = 5

এখানে টাইপটি alচ্ছিক কারণ স্কেল নির্ধারিত মান থেকে এটি নির্ধারণ করতে পারে।

ভার - ভেরিয়েবলগুলি টাইপ করা স্টোরেজ ইউনিট যা মেমরির স্থান সংরক্ষিত না হওয়া পর্যন্ত আবার মান নির্ধারিত হতে পারে।

যেমন। var x: int = 5

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

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


0

অনেক যদিও ইতিমধ্যে মধ্যে পার্থক্য উত্তর Val, এবং Var । তবে একটি বিষয় লক্ষ্য করুন যে ভালটি চূড়ান্ত কীওয়ার্ডের মতো নয়

আমরা পুনরাবৃত্তি ব্যবহার করে ভ্যালির মান পরিবর্তন করতে পারি তবে আমরা কখনই চূড়ান্তের মান পরিবর্তন করতে পারি না। ফাইনালের চেয়ে ভাল ধ্রুবক।

def factorial(num: Int): Int = {
 if(num == 0) 1
 else factorial(num - 1) * num
}

পদ্ধতির পরামিতিগুলি ডিফল্ট ভাল অনুসারে হয় এবং প্রতিটি কল মানতে পরিবর্তন করা হয়।

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