স্ক্যালায় ডিএফ, ভাল এবং ভ্যার ব্যবহার করুন


158
class Person(val name:String,var age:Int )
def person = new Person("Kumar",12)
person.age = 20
println(person.age)

কোড আউটপুটগুলির এই লাইনগুলি সফলভাবে কার্যকর করা 12হলেও person.age=20। আমি আবিষ্কার করেছি যে এটি ঘটেছিল কারণ আমি ডিফ ইন ব্যবহার করেছি def person = new Person("Kumar",12)। আমি যদি var বা ভাল ব্যবহার করি তবে আউটপুট হয় 20। আমি বুঝতে পারছি স্ক্যালায় ডিফল্টটি ভাল। এই:

def age = 30
age = 45

... একটি সংকলন ত্রুটি দেয় কারণ এটি ডিফল্টরূপে ভাল is উপরের লাইনের প্রথম সেটটি কেন সঠিকভাবে কাজ করে না এবং তবুও ত্রুটি করে না?

উত্তর:


254

স্কালায় জিনিস নির্ধারণের তিনটি উপায় রয়েছে:

  • defএকটি পদ্ধতি সংজ্ঞায়িত করে
  • valএকটি নির্দিষ্ট মান নির্ধারণ করে (যা সংশোধন করা যায় না)
  • varএকটি পরিবর্তনশীল সংজ্ঞায়িত (যা পরিবর্তন করা যেতে পারে)

আপনার কোডটি দেখছেন:

def person = new Person("Kumar",12)

এটি একটি নতুন পদ্ধতি নামক সংজ্ঞা দেয় person। আপনি এই পদ্ধতিটি কেবলমাত্র কল করতে পারেন ()কারণ এটি প্যারামিটারলেস পদ্ধতি হিসাবে সংজ্ঞায়িত করা হয়েছে। খালি-প্যারেন পদ্ধতির জন্য, আপনি এটিকে '()' এর সাথে বা ছাড়াই কল করতে পারেন। আপনি যদি সহজভাবে লিখেন:

person

তারপরে আপনি এই পদ্ধতিটি কল করছেন (এবং যদি আপনি ফেরতের মান নির্ধারণ না করেন তবে এটি কেবল বাতিল করা হবে)। কোডের এই লাইনে:

person.age = 20

যা ঘটে তা হ'ল আপনি প্রথমে personপদ্ধতিটি কল করুন এবং রিটার্ন ভ্যালুতে (শ্রেণীর উদাহরণ Person) আপনি ageসদস্যের পরিবর্তনশীল পরিবর্তন করছেন।

এবং শেষ লাইন:

println(person.age)

এখানে আপনি আবার সেই personপদ্ধতিতে কল দিচ্ছেন যা ক্লাসের একটি নতুন উদাহরণ দেয় Person( age12 টি সেট সহ )। এটি এর মতোই:

println(person().age)

27
জিনিসগুলিকে বিভ্রান্ত করার জন্য, একটিটির অভ্যন্তরীণ অবস্থা valপরিবর্তন করা যেতে পারে তবে একটি ভাল দ্বারা উল্লিখিত বস্তুটি পারে না। ক valএকটি ধ্রুবক নয়।
পেফারেল 21

5
জিনিসগুলিকে আরও বিভ্রান্ত করার জন্য, ভাল (এবং সম্ভবত বিভিন্নরকমও, আমি এটি চেষ্টা করে দেখিনি) কোনও ফাংশন সংজ্ঞায়িত করতে ব্যবহার করা যেতে পারে। কোনও ফাংশন / পদ্ধতি সংজ্ঞায়িত করতে যখন ডিফ ব্যবহার করা হয় তখন প্রতিবার ডাকে যখন ডেকে আনা হয় তখন তার শরীরে মূল্যায়ন করা হয়। ভাল ব্যবহার করার সময় এটি শুধুমাত্র সংজ্ঞা সংস্থায় মূল্যায়ন করা হয়। দেখুন stackoverflow.com/questions/18887264/...
melston

1
@ মেলস্টন হ্যাঁ, তবে একটি পদ্ধতি এবং একটি ফাংশনও ঠিক একই জিনিস নয়
জেস্পার

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

2
@ স্পেরেল সত্যিই বিভ্রান্তিকর নয়। জাভার ফাইনাল হিসাবে একই। আপনি একটি Listহিসাবে চিহ্নিত করতে পারেন final, তবে এর বিষয়বস্তুগুলিকে সংশোধন করতে পারেন।
jFrenetic

100

আমি পার্থক্য যে মধ্যবর্তী Scala বিদ্যমান করে শুরু চাই Def , Val এবং Var

  • Def - ডান পাশের সামগ্রীর জন্য একটি অপরিবর্তনীয় লেবেল সংজ্ঞায়িত করে যা অলসভাবে মূল্যায়ন করা হয় - নাম দ্বারা মূল্যায়ন করুন।

  • ভাল - ডান পাশের সামগ্রীর জন্য একটি অপরিবর্তনীয় লেবেল সংজ্ঞায়িত করে যা উত্সাহ / তাত্ক্ষণিকভাবে মূল্যায়ন করা হয় - মান দ্বারা মূল্যায়ন করা হয়।

  • var - একটি পরিবর্তনীয় পরিবর্তনশীল সংজ্ঞা দেয় , প্রাথমিকভাবে মূল্যায়িত ডান পাশের সামগ্রীগুলিতে সেট করুন।

উদাহরণ, Def

scala> def something = 2 + 3 * 4 
something: Int
scala> something  // now it's evaluated, lazily upon usage
res30: Int = 14

উদাহরণ, ভাল

scala> val somethingelse = 2 + 3 * 5 // it's evaluated, eagerly upon definition
somethingelse: Int = 17

উদাহরণ, বর্ণ

scala> var aVariable = 2 * 3
aVariable: Int = 6

scala> aVariable = 5
aVariable: Int = 5

উপরে মতে, থেকে লেবেলগুলি Def এবং Val পুনরায় নির্ধারণ করা যাবে না, এবং কোন প্রয়াস ক্ষেত্রে নীচে মত একটি ত্রুটি উত্থাপিত হবে:

scala> something = 5 * 6
<console>:8: error: value something_= is not a member of object $iw
       something = 5 * 6
       ^

ক্লাসটি যখন এর মতো সংজ্ঞায়িত হয়:

scala> class Person(val name: String, var age: Int)
defined class Person

এবং তারপরে তাত্ক্ষণিকভাবে:

scala> def personA = new Person("Tim", 25)
personA: Person

ব্যক্তির সেই নির্দিষ্ট উদাহরণের জন্য (যেমন 'personA') একটি অপরিবর্তনীয় লেবেল তৈরি করা হয়। যখনই পরিবর্তনযোগ্য ক্ষেত্র 'বয়স' সংশোধন করা দরকার, এ জাতীয় প্রচেষ্টা ব্যর্থ হয়:

scala> personA.age = 44
personA.age: Int = 25

প্রত্যাশিত হিসাবে, 'বয়স' একটি অ-পরিবর্তনীয় লেবেলের অংশ। এটির সাথে কাজ করার সঠিক উপায়টি নীচের উদাহরণের মতো একটি পরিবর্তনীয় ভেরিয়েবল ব্যবহারের সাথে জড়িত:

scala> var personB = new Person("Matt", 36)
personB: Person = Person@59cd11fe

scala> personB.age = 44
personB.age: Int = 44    // value re-assigned, as expected

পরিষ্কার হিসাবে, পরিবর্তনীয় পরিবর্তনশীল রেফারেন্স থেকে (অর্থাত্ 'personB') শ্রেণি পরিবর্তনযোগ্য ক্ষেত্র 'বয়স' পরিবর্তন করা সম্ভব।

আমি এখনও এই বিষয়টিকে জোর দিয়ে বলব যে সমস্ত কিছু উপরোক্ত বর্ণিত পার্থক্য থেকে এসেছে, এটি কোনও স্কালার প্রোগ্রামারকে মনে রাখতে হবে clear


উপরের ব্যাখ্যাটি সঠিক বলে আমি মনে করি না। অন্যান্য উত্তর দেখুন।
প্রতি মাইল্ডনার

@ পারমিল্ডনার আপনি কি দয়া করে উপরের উত্তরের ভুলটি ব্যাখ্যা করতে পারেন?
সৈয়দ সৌবান

আমার আসল অভিযোগটি কী ছিল তা আমার মনে নেই। যাইহোক, উত্তরের শেষ অংশটি, personAএট আল সম্পর্কে । বন্ধ মনে হচ্ছে। পরিবর্তন কিনা ageসদস্য কাজ করে বা না আপনি ব্যবহার কিনা স্বাধীন def personAবা var personB। পার্থক্যটি হ'ল def personAক্ষেত্রে আপনি যখন Personআপনার প্রথম মূল্যায়ন থেকে ফিরে এসেছেন-ইনস্ট্যান্টটি সংশোধন করছেন personA। এই উদাহরণস্বরূপ হয় পরিবর্তন, কিন্তু এটি যখন আপনি আবার মূল্যায়নের কি ফিরিয়ে দেওয়া হয় নয় personA। পরিবর্তে, দ্বিতীয়বার personA.ageআপনি কার্যকরভাবে করছেন new Person("Tim",25).age
প্রতি মাইল্ডনার

29

সঙ্গে

def person = new Person("Kumar", 12) 

আপনি একটি ফাংশন / অলস ভেরিয়েবল সংজ্ঞায়িত করছেন যা সর্বদা "কুমার" এবং বয়স ১২ নাম দিয়ে নতুন ব্যক্তির উদাহরণ দেয় This এটি পুরোপুরি বৈধ এবং সংকলকটির অভিযোগ করার কোনও কারণ নেই। Person.age- এ কল করা নতুনভাবে তৈরি হওয়া এই ব্যক্তির উদাহরণ ফিরিয়ে দেবে, যা সর্বদা 12।

লেখার সময়

person.age = 45

আপনি বর্গ ব্যক্তিতে বয়সের সম্পত্তিতে একটি নতুন মান নির্ধারণ করেন, যা বয়স হিসাবে হিসাবে ঘোষিত হওয়ার পরে বৈধ var। আপনি যদি personনতুন কোনও ব্যক্তির মতো বিষয়টিকে পুনরায় সাইন করার চেষ্টা করেন তবে সংকলকটি অভিযোগ করবে

person = new Person("Steve", 13)  // Error

হ্যাঁ. এই বিন্দুটি সহজে উপর হ্যাশকোড পদ্ধতি কলিং দ্বারা প্রদর্শিত করা যাবে পারসোনা
Nilanjan সরকার

26

অন্য একটি দৃষ্টিকোণ সরবরাহ করার জন্য, স্কালায় "ডিএফ" এর অর্থ এমন একটি জিনিস যা ব্যবহারের সময় প্রতিটি সময় মূল্যায়ন করা হবে , যখন ভাল এমন কিছু যা অবিলম্বে এবং একবার একবার মূল্যায়ন করা হয় । এখানে, অভিব্যক্তিটি def person = new Person("Kumar",12)জোর দেয় যে আমরা যখনই "ব্যক্তি" ব্যবহার করি আমরা new Person("Kumar",12)কল পাই get অতএব এটি স্বাভাবিক যে দুটি "person.age" সম্পর্কযুক্ত নয়।

এইভাবেই আমি স্ক্যালাকে বুঝতে পারি (সম্ভবত আরও "কার্যকরী" পদ্ধতিতে)। আমি নিশ্চিত না

def defines a method
val defines a fixed value (which cannot be modified)
var defines a variable (which can be modified)

যদিও স্ক্যালার অর্থ হ'ল এটিই। আমি কমপক্ষে সেভাবে ভাবতে পছন্দ করি না ...


20

কিন্তারো যেমন ইতিমধ্যে বলেছেন, ব্যক্তি একটি পদ্ধতি (ডিএফ এর কারণে) এবং সর্বদা একটি নতুন ব্যক্তির উদাহরণ প্রদান করে। আপনি যেমনটি আবিষ্কার করেছেন এটি কার্যকর হবে যদি আপনি পদ্ধতিটি কোনও ভেরি বা ভ্যালিতে পরিবর্তন করেন:

val person = new Person("Kumar",12)

আর একটি সম্ভাবনা হ'ল:

def person = new Person("Kumar",12)
val p = person
p.age=20
println(p.age)

যাইহোক, person.age=20আপনার কোডটিতে অনুমোদিত, যেমন আপনি পদ্ধতিটি Personথেকে কোনও উদাহরণ ফিরে পান personএবং এই উদাহরণে আপনাকে এর মান পরিবর্তন করার অনুমতি দেওয়া হয় var। সমস্যাটি হ'ল, সেই লাইনের পরে আপনার কাছে সেই দৃষ্টান্তের আর কোনও রেফারেন্স নেই (প্রতিটি কল যেমন personএকটি নতুন উদাহরণ তৈরি করবে)।

এটি বিশেষ কিছু নয়, জাভাতে আপনার ঠিক একই আচরণ থাকবে:

class Person{ 
   public int age; 
   private String name;
   public Person(String name; int age) {
      this.name = name;  
      this.age = age;
   }
   public String name(){ return name; }
}

public Person person() { 
  return new Person("Kumar", 12); 
}

person().age = 20;
System.out.println(person().age); //--> 12

8

আসুন এটি নেওয়া যাক:

class Person(val name:String,var age:Int )
def person =new Person("Kumar",12)
person.age=20
println(person.age)

এবং এটি সমমানের কোড সহ পুনর্লিখন করুন

class Person(val name:String,var age:Int )
def person =new Person("Kumar",12)
(new Person("Kumar", 12)).age_=(20)
println((new Person("Kumar", 12)).age)

দেখুন, defএকটি পদ্ধতি। এটি যতবার বলা হয় ততক্ষণে কার্যকর করা হবে এবং প্রত্যেকবার এটি ফিরে আসবে (ক) new Person("Kumar", 12)। এবং এগুলি "অ্যাসাইনমেন্ট" এ কোনও ত্রুটি নেই কারণ এটি সত্যই কোনও অ্যাসাইনমেন্ট নয়, তবে age_=পদ্ধতির কাছে কেবল একটি কল (সরবরাহিত var)।

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