স্কালায় পদ্ধতি এবং ফাংশনের মধ্যে পার্থক্য


254

আমি স্কালা ফাংশনগুলি ( স্কালার আরেকটি সফরের অংশ ) পড়েছি । সেই পোস্টে তিনি বলেছিলেন:

পদ্ধতি এবং ফাংশন একই জিনিস নয়

তবে তিনি এ সম্পর্কে কিছুই ব্যাখ্যা করেননি। সে কী বলার চেষ্টা করছিল?




ভাল উত্তর সহ একটি ফলো-আপ প্রশ্ন: স্কালায় ফাংশন বনাম পদ্ধতি
জোশিয়াহ ইয়্ডার

উত্তর:


238

জিম এটি তার ব্লগ পোস্টে বেশ কভার পেয়েছে তবে আমি এখানে একটি ব্রিফিং পোস্ট করছি রেফারেন্সের জন্য।

প্রথমে আসুন দেখুন স্কালা স্পেসিফিকেশন আমাদের কী বলে। অধ্যায় 3 (প্রকার) আমাদের ফাংশন প্রকারগুলি (3.2.9) এবং পদ্ধতি প্রকারগুলি (3.3.1) সম্পর্কে বলুন । অধ্যায় 4 (বেসিক ঘোষণা) মান ঘোষণা এবং সংজ্ঞা (4.1), পরিবর্তনশীল ঘোষণা এবং সংজ্ঞা (4.2) এবং কার্যকারিতা ঘোষণা এবং সংজ্ঞা (4.6) সম্পর্কে কথা বলে। অধ্যায় 6 (এক্সপ্রেশন) অজ্ঞাতনামা ফাংশন (6.23) এবং পদ্ধতি মানগুলি (6.7) সম্পর্কে কথা বলে। কৌতূহলজনকভাবে, ফাংশন মানগুলি 3.2.9 এ এক সময়ের কথা বলা হয় এবং অন্য কোথাও হয় না।

একটি ফাংশন টাইপ (মোটামুটিভাবে) ফর্মের একটি ধরণ (টি 1, ..., টিএন) => ইউ , যা FunctionNস্ট্যান্ডার্ড লাইব্রেরির বৈশিষ্ট্যের জন্য একটি শর্টহ্যান্ড । বেনামে ফাংশন এবং পদ্ধতি মানগুলিতে ফাংশনের ধরণ রয়েছে এবং ফাংশন প্রকারগুলি মান, পরিবর্তনশীল এবং ফাংশন ঘোষণা এবং সংজ্ঞাগুলির অংশ হিসাবে ব্যবহার করা যেতে পারে। আসলে, এটি কোনও পদ্ধতির ধরণের অংশ হতে পারে।

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

মান ঘোষণা এবং সংজ্ঞা এবং পরিবর্তনীয় ঘোষণা এবং সংজ্ঞা হয় valএবং varঘোষণা, উভয় সহ প্রকার ও মান - যা হতে পারে, যথাক্রমে ফাংশন ধরণ এবং বেনামী কার্যাবলী বা পদ্ধতি মানগুলি । নোট করুন, জেভিএম-এ, এই (পদ্ধতির মানগুলি) জাভা যা "পদ্ধতি" বলে ডাকে তা প্রয়োগ করা হয়।

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

অবশেষে, একটি বেনামী ফাংশন একটি একটি দৃষ্টান্ত হল ফাংশন ধরণ (অর্থাত, বৈশিষ্ট্যের একটি দৃষ্টান্তFunctionN ), এবং একটি পদ্ধতি মূল্য একই কথা! পার্থক্যটি হ'ল পদ্ধতিগুলি থেকে একটি মেথড মান তৈরি করা হয়, হয় একটি আন্ডারস্কোর পোস্টফিক্স করে ( m _"ফাংশন ডিক্লেয়ারেশন" ( def) এর সাথে সম্পর্কিত একটি পদ্ধতি মান m), বা এটি -প্রসারণ নামক প্রক্রিয়া দ্বারা , যা পদ্ধতি থেকে স্বয়ংক্রিয় কাস্টের মতো is কাজ করা।

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

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

সুতরাং, পরিভাষায় উপরের পরিবর্তনটি দেওয়া, এখানে পার্থক্যের একটি বাস্তব ব্যাখ্যা দেওয়া হল।

একটি ফাংশন একটি বস্তু যে এক রয়েছে FunctionXযেমন বৈশিষ্ট্যগুলো, Function0, Function1, Function2, ইত্যাদিতে সহ করা যেতে পারে PartialFunctionহিসাবে ভাল যা আসলে প্রসারিত, Function1

আসুন এই বৈশিষ্টগুলির মধ্যে একটির জন্য স্বাক্ষরের প্রকারটি দেখুন:

trait Function2[-T1, -T2, +R] extends AnyRef

এই বৈশিষ্ট্যের একটি বিমূর্ত পদ্ধতি রয়েছে (এটিতে কয়েকটি কংক্রিট পদ্ধতিও রয়েছে):

def apply(v1: T1, v2: T2): R

এবং এটি আমাদের সম্পর্কে যা জানার আছে তা সবই বলি। একটি ফাংশনটিতে এমন একটি applyপদ্ধতি রয়েছে যা টি 1 , টি 2 , ..., টিএন প্রকারের N পরামিতিগুলি গ্রহণ করে এবং টাইপের কিছু দেয় R। এটি প্রাপ্ত প্যারামিটারগুলির তুলনায় এটি বৈকল্পিক এবং ফলাফলের সহ-বৈকল্পিক।

তারতম্যটির অর্থ Function1[Seq[T], String]হ'ল a এর একটি উপপ্রকার Function1[List[T], AnyRef]। সাব টাইপ হওয়ার অর্থ এটি এর জায়গায় ব্যবহার করা যেতে পারে । যে কেউ কল করতে চলেছি তা সহজেই দেখতে পাবেf(List(1, 2, 3)) এবং AnyRefপিছনে প্রত্যাশা করতে চাইলে উপরের দুটি ধরণের উভয়ই কাজ করবে।

এখন, একটি পদ্ধতি এবং একটি ফাংশনের মিল কী ? ঠিক আছে, যদি fকোনও ফাংশন হয় এবং mকোনও ক্ষেত্রের স্থানীয় পদ্ধতি হয় তবে উভয়কেই এটির মতো বলা যেতে পারে:

val o1 = f(List(1, 2, 3))
val o2 = m(List(1, 2, 3))

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

val o1 = f.apply(List(1, 2, 3))

যা অবশ্যই অবজেক্টে একটি মেথড কল f। ফাংশনগুলিতে এর সুবিধার জন্য অন্যান্য সিনট্যাকটিক শর্করাও রয়েছে: ফাংশন আক্ষরিক (এর মধ্যে দুটি আসলে) এবং (T1, T2) => Rস্বাক্ষরগুলি টাইপ করুন। উদাহরণ স্বরূপ:

val f = (l: List[Int]) => l mkString ""
val g: (AnyVal) => String = {
  case i: Int => "Int"
  case d: Double => "Double"
  case o => "Other"
}

একটি পদ্ধতি এবং একটি ফাংশনের মধ্যে আরেকটি মিল হ'ল প্রাক্তনটিকে সহজেই পরবর্তীকালে রূপান্তর করা যায়:

val f = m _

স্কেলা এটিকে প্রসারিত করবে , ধরে নিলে mধরণের (List[Int])AnyRefধরণটি (স্কেলা ২.7):

val f = new AnyRef with Function1[List[Int], AnyRef] {
  def apply(x$1: List[Int]) = this.m(x$1)
}

স্কেলা ২.৮ এ এটি আসলে একটি ব্যবহার করে AbstractFunction1 শ্রেণীর আকার হ্রাস ক্লাস করে।

লক্ষ্য করুন যে একটি অন্য পদ্ধতিতে - কোনও ফাংশন থেকে কোনও পদ্ধতিতে রূপান্তর করতে পারে না।

পদ্ধতিগুলির তবে একটি বড় সুবিধা রয়েছে (ভাল, দুটি - তারা কিছুটা দ্রুত হতে পারে): তারা টাইপ পরামিতিগুলি গ্রহণ করতে পারে । উদাহরণস্বরূপ, উপরেরটি fঅগত্যা Listএটি প্রাপ্তির ধরণটি নির্দিষ্টভাবে নির্দিষ্ট করতে পারে ( List[Int]উদাহরণস্বরূপ), mএটি প্যারামিটারাইজ করতে পারে:

def m[T](l: List[T]): String = l mkString ""

আমি মনে করি এটি বেশ কিছুটা কভার করে, তবে আমি যে কোনও প্রশ্নের উত্তর দিয়ে এটি পরিপূর্ণ করতে পেরে খুশি হব।


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

4
@ আমি জানি, আমি জানি - পিনএস হ'ল বইটি আমাকে স্কেলা শিখিয়েছিল। আমি শক্তভাবে আরও ভাল শিখলাম, অর্থাত্ পলপ আমাকে সোজা করে দিয়েছে।
ড্যানিয়েল সি সোব্রাল

4
দুর্দান্ত ব্যাখ্যা! আমার একটি যুক্ত করার দরকার আছে: আপনি যখন val f = mসংকলক দ্বারা সম্প্রসারণের উদ্ধৃতি দিয়েছিলেন যখন আপনি val f = new AnyRef with Function1[List[Int], AnyRef] { def apply(x$1: List[Int]) = this.m(x$1) }উল্লেখ করতে হবে যে thisঅভ্যন্তরীণ applyপদ্ধতিটি AnyRefবস্তুকে নির্দেশ করে না , তবে সেই পদ্ধতিতে যার পদ্ধতিতে val f = m _মূল্যায়ন করা হয় ( বাহ্যিক this , তাই বলে) ), যেহেতু thisক্লোজারের মাধ্যমে ধরা পড়া মানগুলির মধ্যে রয়েছে (যেমন returnনীচের দিকে নির্দেশিত হিসাবে)
হলগার পাইন

1
@ ড্যানিয়েলসি.সোব্রাল, আপনি উল্লেখ করেছেন পিনস বইটি কী? আমি স্কেলা শিখতে আগ্রহী, এবং সেই নামের কোনও বইও খুঁজে পাইনি,
tldr

5
ও্ডারস্কি এবং সমস্তের মাধ্যমে স্কালায় @tldr প্রোগ্রামিং । এটি এর সাধারণ সংক্ষেপণ (তারা আমাকে বলেছিল যে তারা কোনও কারণে পাইসকে পছন্দ করেন না! :)
ড্যানিয়েল সি সোব্রাল

67

একটি পদ্ধতি এবং একটি ফাংশন মধ্যে একটি বড় ব্যবহারিক পার্থক্য returnমানে কি । returnকেবল কখনও কোনও পদ্ধতি থেকে ফিরে আসে। উদাহরণ স্বরূপ:

scala> val f = () => { return "test" }
<console>:4: error: return outside method definition
       val f = () => { return "test" }
                       ^

কোনও পদ্ধতিতে সংজ্ঞায়িত কোনও ক্রিয়াকলাপ থেকে ফিরে আসা কোনও স্থানীয় নয় return

scala> def f: String = {                 
     |    val g = () => { return "test" }
     | g()                               
     | "not this"
     | }
f: String

scala> f
res4: String = test

যেখানে স্থানীয় পদ্ধতি থেকে ফিরে আসা কেবল সেই পদ্ধতি থেকে ফিরে আসে।

scala> def f2: String = {         
     | def g(): String = { return "test" }
     | g()
     | "is this"
     | }
f2: String

scala> f2
res5: String = is this

9
কারণ রিটার্নটি বন্ধ হয়ে ধরা পড়ে।
ড্যানিয়েল সি সোব্রাল

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

2
@ রুট - এ এর ​​ভিতরে থেকে ফিরে কি হবে for (a <- List(1, 2, 3)) { return ... }? এটি বন্ধ হয়ে যায়-
বেন লিংস

হুম ... হ্যাঁ, এটি যুক্তিসঙ্গত ব্যবহারের ক্ষেত্রে। এখনও ভয়ঙ্কর কঠিন থেকে ডিবাগ সমস্যার দিকে পরিচালিত করার সম্ভাবনা রয়েছে তবে এটি এটিকে আরও বুদ্ধিমান প্রসঙ্গে ফেলে।
রুটটি

1
সত্যিই আমি আলাদা সিনট্যাক্স ব্যবহার করতাম। আছে returnফাংশন থেকে একটি মান ফিরে আসুন, এবং কিছু ফর্ম escapeবা breakবা continueপদ্ধতি থেকে ফেরত আসবে।
রায়ান দি লিচ

38

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

স্কালার দ্বিতীয় সংস্করণে প্রোগ্রামিং। মার্টিন ওডারস্কি - লেক্স চামচ - বিল ভেনার্স


1
একটি ফাংশন ডিএফ বা মান / ভের হিসাবে শ্রেণীর অন্তর্ভুক্ত হতে পারে। শুধুমাত্র ডিএফ এর পদ্ধতি।
জোশিয়ার যোদার 14 ই

29

বলুন আপনার একটি তালিকা আছে

scala> val x =List.range(10,20)
x: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19)

একটি পদ্ধতি নির্ধারণ করুন

scala> def m1(i:Int)=i+2
m1: (i: Int)Int

একটি ফাংশন সংজ্ঞায়িত করুন

scala> (i:Int)=>i+2
res0: Int => Int = <function1>

scala> x.map((x)=>x+2)
res2: List[Int] = List(12, 13, 14, 15, 16, 17, 18, 19, 20, 21)

তর্ক গ্রহণ করার পদ্ধতি

scala> m1(2)
res3: Int = 4

ভাল সঙ্গে ফাংশন সংজ্ঞায়িত

scala> val p =(i:Int)=>i+2
p: Int => Int = <function1>

কাজ করার পক্ষে যুক্তি ptionচ্ছিক

 scala> p(2)
    res4: Int = 4

scala> p
res5: Int => Int = <function1>

আর্গুমেন্ট টু মেথড বাধ্যতামূলক

scala> m1
<console>:9: error: missing arguments for method m1;
follow this method with `_' if you want to treat it as a partially applied function

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


13

ফাংশনগুলি প্যারামিটার ডিফল্ট সমর্থন করে না। পদ্ধতিগুলি করেন। কোনও পদ্ধতি থেকে কোনও ফাংশনে রূপান্তর করা প্যারামিটারের ডিফল্টগুলি হারাবে। (স্কেলা ২.৮.১)


5
এর কি কারণ আছে?
কোরাজা

7

এখানে একটি সুন্দর নিবন্ধ আছে যা থেকে আমার বিবরণ অধিকাংশ নেয়া হয়। আমার বোঝাপড়া সম্পর্কে ফাংশন এবং পদ্ধতিগুলির একটি সংক্ষিপ্ত তুলনা। আশা করি এটা সাহায্য করবে:

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

val f1 = (x: Int) => x + x
f1(2)  // 4

উপরের লাইনটি কোনও বস্তুকে অন্য 1 যেমন অবজেক্ট 1 = অবজেক্ট 2 হিসাবে বরাদ্দ করা ছাড়া কিছুই নয়। প্রকৃতপক্ষে আমাদের উদাহরণের অবজেক্ট 2 একটি বেনাম ফাংশন এবং বাম দিকটি কোনও কারণে একটি বস্তুর ধরণ পায়। অতএব, এখন f1 একটি অবজেক্ট (ফাংশন)। বেনামে ফাংশনটি আসলে ফাংশন 1 [ইন্ট, ইনট] এর একটি উদাহরণ, যার অর্থ ইনপ টাইপের 1 পরামিতি এবং ইনট টাইপের রিটার্ন মান সহ একটি ফাংশন। আর্গুমেন্ট ছাড়াই এফ 1 কল করা আমাদের বেনামে ফাংশনটির স্বাক্ষর দেবে (আন্ত => অন্তঃ =)

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

def m1(x: Int) = x + x
m1(2)  // 4

উপরের লাইনটি কোনও সাধারণ মূল্য নির্ধারণ নয় তবে একটি পদ্ধতির সংজ্ঞা। আপনি যখন দ্বিতীয় লাইনের মতো 2 এর মান সহ এই পদ্ধতিটি চালু করবেন, এক্সটি 2 এর সাথে প্রতিস্থাপিত হবে এবং ফলাফল গণনা করা হবে এবং আপনি আউটপুট হিসাবে 4 পাবেন। এখানে কেবল এম 1 লিখলে আপনি একটি ত্রুটি পাবেন কারণ এটি পদ্ধতি এবং ইনপুট মানটি প্রয়োজন। _ ব্যবহার করে আপনি বেলোয়ের মতো কোনও কার্যে একটি পদ্ধতি নির্ধারণ করতে পারেন:

val f2 = m1 _  // Int => Int = <function1>

"একটি ফাংশনে একটি পদ্ধতি নির্ধারণ" এর অর্থ কী? এর অর্থ কি এই যে কেবল এখন আপনার কাছে এমন একটি অবজেক্ট রয়েছে যা পদ্ধতিটির মতোই আচরণ করে?
কে এম এম

@ কেএম: ভাল এফ 2 = এম 1 _ ভাল এফ 2 এর সমতুল্য = নতুন ফাংশন 1 [ইন্ট, ইনট] {ডিফ এম 1 (এক্স: ইনট) = এক্স + এক্স};
সাসউকে :

3

এখানে রব নরিসের একটি দুর্দান্ত পোস্ট যা পার্থক্যটি ব্যাখ্যা করে, এখানে একটি টিএল; ডিআর

স্কালায় পদ্ধতিগুলি মান নয়, তবে ফাংশনগুলি। আপনি এমন একটি ফাংশন নির্মাণ করতে পারেন যা method-বিস্তারের মাধ্যমে কোনও পদ্ধতিতে প্রতিনিধিত্ব করে (আন্ডারস্কোর জিনিসটিকে অনুসরণ করে) y

নিম্নলিখিত সংজ্ঞা সহ:

একটি পদ্ধতি ডিএফ দ্বারা সংজ্ঞায়িত কিছু এবং মান একটি মান যা আপনি একটি ভালকে নির্ধারণ করতে পারেন

সংক্ষেপে ( ব্লগ থেকে এক্সট্রাক্ট ):

আমরা যখন কোনও পদ্ধতি সংজ্ঞায়িত করি তখন আমরা দেখতে পাই যে আমরা এটিকে এটি নির্ধারণ করতে পারি না val

scala> def add1(n: Int): Int = n + 1
add1: (n: Int)Int

scala> val f = add1
<console>:8: error: missing arguments for method add1;
follow this method with `_' if you want to treat it as a partially applied function
       val f = add1

আরো উল্লেখ্য টাইপ এর add1, যা স্বাভাবিক মনে হচ্ছে না; আপনি টাইপের একটি ভেরিয়েবল ঘোষণা করতে পারবেন না (n: Int)Int। পদ্ধতির মান হয় না।

যাইহোক, expansion-বিস্তৃতি পোস্টফিক্স অপারেটর যুক্ত করে (η উচ্চারণ করা হয় "এটা"), আমরা পদ্ধতিটিকে একটি ফাংশন মান হিসাবে রূপান্তর করতে পারি। এর প্রকারটি নোট করুন f

scala> val f = add1 _
f: Int => Int = <function1>

scala> f(3)
res0: Int = 4

এর প্রভাব _নীচের সমতুল্য সম্পাদন করা হয়: আমরা একটি Function1উদাহরণ তৈরি করি যা আমাদের পদ্ধতিতে প্রতিনিধিত্ব করে।

scala> val g = new Function1[Int, Int] { def apply(n: Int): Int = add1(n) }
g: Int => Int = <function1>

scala> g(3)
res18: Int = 4

1

স্কেলা ২.১।-এ, ফাংশনগুলির বিপরীতে পদ্ধতিগুলি গ্রহণ করতে বা ফিরে আসতে পারে

  • টাইপ পরামিতি (বহুবিধ পদ্ধতি)
  • অন্তর্নিহিত পরামিতি
  • নির্ভরশীল প্রকার

যাইহোক, এই বিধিনিষেধগুলি পলিমারফিক ফাংশন প্রকার # 4672 দ্বারা ডটটিতে (স্কালা 3) তুলে নেওয়া হয়েছে , উদাহরণস্বরূপ, ডটি সংস্করণ 0.23.0-আরসি 1 নীচের বাক্য গঠনটি সক্ষম করে

পরামিতি টাইপ করুন

def fmet[T](x: List[T]) = x.map(e => (e, e))
val ffun = [T] => (x: List[T]) => x.map(e => (e, e))

অন্তর্নিহিত পরামিতি ( প্রসঙ্গের পরামিতি)

def gmet[T](implicit num: Numeric[T]): T = num.zero
val gfun: [T] => Numeric[T] ?=> T = [T] => (using num: Numeric[T]) => num.zero

নির্ভরশীল প্রকার

class A { class B }
def hmet(a: A): a.B = new a.B
val hfun: (a: A) => a.B = hmet

আরও উদাহরণের জন্য পরীক্ষা / চালানো / পলিমারফিক-ফাংশন.স্কালা দেখুন


0

ব্যবহারিকভাবে, একটি স্কালা প্রোগ্রামারকে সঠিকভাবে ফাংশন এবং পদ্ধতিগুলি সঠিকভাবে ব্যবহার করতে নিম্নলিখিত তিনটি বিধি জানতে হবে:

  • দ্বারা সংজ্ঞায়িত পদ্ধতি defএবং ফাংশন আক্ষরিক দ্বারা সংজ্ঞায়িত =>ফাংশনগুলি। এটি স্কেল ইন প্রোগ্রামিংয়ের বইয়ের 143 পৃষ্ঠা, অধ্যায় 8 এ সংজ্ঞায়িত হয়েছে, চতুর্থ সংস্করণ।
  • ফাংশন মানগুলি এমন বস্তু যা কোনও মান হিসাবে ঘুরে যায়। ফাংশন আক্ষরিক এবং আংশিক প্রয়োগিত ফাংশনগুলি ফাংশন মান।
  • কোডের একটি বিন্দুতে কোনও ফাংশনের মান প্রয়োজন হলে আপনি আংশিক প্রয়োগ ফাংশনের আন্ডারস্কোরটি ছেড়ে দিতে পারেন। উদাহরণ স্বরূপ:someNumber.foreach(println)

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

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