স্কালায় প্রয়োগের কাজটি কী?


311

আমি এটি কখনই অবলম্বনহীন আনমশালিং এবং ভার্চিং বিশেষ্যগুলি থেকে বুঝতে পারি নি (একটি AddTwoশ্রেণীর applyদুটিতে যোগ হয়!) উদাহরণগুলি।

আমি বুঝতে পারি যে এটি সিনট্যাকটিক চিনি, সুতরাং (আমি প্রসঙ্গ থেকে অনুমিত করেছি) এটি অবশ্যই কিছু কোডকে আরও স্বজ্ঞাত করতে তৈরি করা হয়েছে।

একটি applyফাংশন সহ একটি বর্গ কি অর্থ দেয় ? এটি কীসের জন্য ব্যবহৃত হয় এবং কী উদ্দেশ্যে এটি কোডকে আরও ভাল করে তোলে (নিরশাসন, ভার্চিং বিশেষ্য ইত্যাদি)?

কোনও সহযোগী অবজেক্টে এটি কীভাবে সাহায্য করবে?


4
এমনকি একটি দ্রুত গুগলও প্রচুর চমৎকার নিবন্ধ নিয়ে আসে। এখানে একটি: jackcoughonsoftware.blogspot.com/2009/01/…
ওম-নাম-মনোনীত


6
আসলে জাভা / C ++ একটি কন্সট্রাকটর হিসাবে একই কিন্তু মান আসতে পারেন এবং 'প্রয়োগ' নামে আছে
এসইএস

এটি একটি পদ্ধতি, কোনও ফাংশন নয়। পদ্ধতি এবং কার্যাবলির মধ্যে পার্থক্য স্কালায় খুব গুরুত্বপূর্ণ।
ডানফোন

1
Zoidberg সম্প্রসারিত করার জন্য, "পদ্ধতি মাত্র ফাংশন যে ক্লাসের রাষ্ট্র অ্যাক্সেস করতে পারেন হল" twitter.github.io/scala_school/basics.html সাধারণভাবে এই Scala চেয়ে বেশি প্রযোজ্য stackoverflow.com/questions/155609/...
DharmaTurtle

উত্তর:


640

গণিতবিদদের নিজস্ব মজার উপায় আছে, সুতরাং প্রোগ্রামাররা যেমন বলতেন "তখন আমরা ফাংশনটিকে প্যারামিটার হিসাবে fপাস xকরার কথা বলি না" fতার পরিবর্তে তারা " তার যুক্তিতে ফাংশন প্রয়োগ করার" বিষয়ে কথা বলে x

গণিত এবং কম্পিউটার বিজ্ঞানে, প্রয়োগ এমন একটি ফাংশন যা আর্গুমেন্টগুলিতে ফাংশন প্রয়োগ করে।
উইকিপিডিয়া

applyস্কালায় অবজেক্ট-ওরিয়েন্টড এবং ফাংশনাল দৃষ্টান্তগুলির মধ্যে ব্যবধানটি বন্ধ করার উদ্দেশ্যে কাজ করে। স্কালার প্রতিটি ফাংশন একটি অবজেক্ট হিসাবে উপস্থাপন করা যেতে পারে। প্রতিটি ফাংশনটিতে একটি ওও টাইপ থাকে: উদাহরণস্বরূপ, এমন একটি ফাংশন যা Intপরামিতি নেয় এবং একটি ফেরত Intদেয় ওও প্রকারের হবে Function1[Int,Int]

 // define a function in scala
 (x:Int) => x + 1

 // assign an object representing the function to a variable
 val f = (x:Int) => x + 1

যেহেতু সমস্ত স্ক্যালায় একটি অবজেক্ট তাই fএখন Function1[Int,Int]অবজেক্টের রেফারেন্স হিসাবে বিবেচনা করা যেতে পারে । উদাহরণস্বরূপ, আমরা toStringউত্তরাধিকার সূত্রে প্রাপ্ত পদ্ধতিটিকে কল করতে Anyপারি, খাঁটি ফাংশনের পক্ষে এটি অসম্ভব হত, কারণ ফাংশনগুলির কোনও পদ্ধতি নেই:

  f.toString

অথবা আমরা পদ্ধতিতে Function1[Int,Int]কল composeকরে fএবং দুটি পৃথক ফাংশন একসাথে শৃঙ্খলাবদ্ধ করে অন্য কোনও বস্তুর সংজ্ঞা দিতে পারি :

 val f2 = f.compose((x:Int) => x - 1)

এখন যদি আমরা আসলে ফাংশনটি সম্পাদন করতে চাই, বা গণিতবিদ হিসাবে "তার যুক্তিগুলিতে কোনও ফাংশন প্রয়োগ করুন" বলে আমরা বস্তুটিতে applyপদ্ধতিটি কল করব Function1[Int,Int]:

 f2.apply(2)

f.apply(args)আপনি যখনই কোনও বস্তু হিসাবে উপস্থাপিত কোনও ক্রিয়াকলাপ সম্পাদন করতে চান প্রতিটি সময় লেখার বিষয়টি অবজেক্ট-ওরিয়েন্টেড উপায়, তবে কোডের সাথে অতিরিক্ত অতিরিক্ত তথ্য যুক্ত না করে প্রচুর বিশৃঙ্খলা যুক্ত করতে পারে এবং আরও বেশি স্ট্যান্ডার্ড স্বরলিপি ব্যবহার করতে সক্ষম হতে ভাল লাগবে যেমন যেমন f(args)। স্ক্যালায়ার সংকলকটি সেখানেই পদক্ষেপ নিয়ে আসে এবং যখনই আমাদের fকোনও ফাংশন অবজেক্টের রেফারেন্স থাকে এবং f (args)উপস্থাপিত ফাংশনে যুক্তি প্রয়োগ করতে লিখি কম্পাইলারটি নিঃশব্দে f (args)অবজেক্ট পদ্ধতি কলটিতে প্রসারিত করে f.apply (args)

স্কেলার প্রতিটি ফাংশনকে একটি অবজেক্ট হিসাবে বিবেচনা করা যেতে পারে এবং এটি অন্যভাবেও কাজ করে - প্রতিটি বস্তুকে একটি ফাংশন হিসাবে বিবেচনা করা যেতে পারে, তবে এর applyপদ্ধতি থাকলে শর্ত থাকে । এই জাতীয় জিনিসগুলি ফাংশন স্বরলিপিটিতে ব্যবহার করা যেতে পারে:

// we will be able to use this object as a function, as well as an object
object Foo {
  var y = 5
  def apply (x: Int) = x + y
}


Foo (1) // using Foo object in function notation 

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

List(1,2,3) // same as List.apply(1,2,3) but less clutter, functional notation

// the way the factory method invocation would have looked
// in other languages with OO notation - needless clutter
List.instanceOf(1,2,3) 

সুতরাং applyপদ্ধতিটি স্কালায় ফাংশন এবং অবজেক্টগুলির মধ্যে ব্যবধানটি বন্ধ করার এক সহজ উপায় is


1
আপনি কীভাবে কোনও বস্তুর সাথে কাস্টম ভেরিয়েবল টাইপ করবেন। আফাইক এটি সম্ভব নয়। এখানে একটি উদাহরণ: আপনার এই শ্রেণি আছে class Average[YType](yZeroValue:YType)। অবজেক্টস টাইপ প্যারাম নিতে পারে না বলে আপনি কীভাবে এর অবজেক্ট থেকে ওয়াইটাইপ পাস করবেন?
অ্যাড্রিয়ান

স্কালায় প্রকারগুলি সাধারণত আর্গুমেন্টের ভিত্তিতে অনুমান করা যায়, তবে তা না পারলে আপনি স্কোয়ার বন্ধনীগুলির মাধ্যমে সরবরাহ করতে পারেন। সুতরাং কোনও গড় অবজেক্ট ইনস্ট্যান্ট করার সময় আপনি "ভাল গড় = নতুন গড় [ইনট] (0)" বলতে পারেন
অ্যাঞ্জেলো জেনোভেস

4
কেস ক্লাস এখানে উল্লেখ করা মূল্যবান। কেস ক্লাসগুলি সুবিধামতভাবে, স্বয়ংক্রিয়ভাবে এবং অদৃশ্যভাবে ক্লাসের কোনও সহযোগী অবজেক্টে (অন্যান্য জিনিসগুলির মধ্যে) যুক্ত applyএবং unapplyপদ্ধতিগুলি। এভাবে শুধু একটা লাইন দিয়ে একটি বর্গ সংজ্ঞায়িত তাই case class Car(make:String, model: String, year: Short, color: String)এটা সম্ভব শুধু দ্বারা গাড়ি ক্লাসের নতুন বস্তু উত্পাদন করতে তোলে: val myCar = Car("VW","Golf",1999,"Blue")। এটি সংক্ষিপ্তরূপেCar.apply(...)
কেজেটিল এস

1
every object can be treated as a function, provided it has the apply method- এখন অনেক কিছু বোধগম্য হয়।
আরজ


51

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

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

class MyAdder(x: Int) {
  def apply(y: Int) = x + y
}

val adder = new MyAdder(2)
val result = adder(4) // equivalent to x.apply(4)

এটি প্রায়শই সঙ্গী অবজেক্টে ব্যবহার করা হয়, ক্লাস বা বৈশিষ্ট্যের জন্য একটি দুর্দান্ত কারখানার পদ্ধতি সরবরাহ করার জন্য, এখানে একটি উদাহরণ রয়েছে:

trait A {
  val x: Int
  def myComplexStrategy: Int
}

object A {
  def apply(x: Int): A = new MyA(x)

  private class MyA(val x: Int) extends A {
    val myComplexStrategy = 42
  }
}

স্কেল স্ট্যান্ডার্ড লাইব্রেরি থেকে, আপনি কীভাবে scala.collection.Seqপ্রয়োগ করা হয়েছে তা দেখতে পারেন : Seqএটি একটি বৈশিষ্ট্য, এইভাবে new Seq(1, 2)সংকলন করবে না তবে সহকর্মী অবজেক্ট এবং প্রয়োগের জন্য ধন্যবাদ, আপনি কল করতে পারেন Seq(1, 2)এবং বাস্তবায়নটি সহযোগী অবজেক্ট দ্বারা চয়ন করা হয়েছে।


প্রয়োগের সমতুল্য এছাড়াও ইমপ্লিট ব্যবহার করেও সম্পন্ন করা যায়?
jayunit100

11

যারা দ্রুত বোধ করতে চান তাদের জন্য এখানে একটি ছোট উদাহরণ

 object ApplyExample01 extends App {


  class Greeter1(var message: String) {
    println("A greeter-1 is being instantiated with message " + message)


  }

  class Greeter2 {


    def apply(message: String) = {
      println("A greeter-2 is being instantiated with message " + message)
    }
  }

  val g1: Greeter1 = new Greeter1("hello")
  val g2: Greeter2 = new Greeter2()

  g2("world")


} 

আউটপুট

একটি গ্রিটার -১ হ্যালো বার্তা সহ ইনস্ট্যান্ট করা হচ্ছে

একটি গ্রিটার -২ বার্তা জগতের সাথে ইনস্ট্যান্ট করা হচ্ছে


2
জি 2 এর জন্য বার্তাটি কি সঠিক? বাস্তবে তা ইনস্ট্যান্টেশনে ঘটছে, নাকি বাস্তবে তা ইনস্ট্যান্টেশন হওয়ার পরেও (এটি অলসভাবে তাত্ক্ষণিক হলেও)?
টিম ব্যারাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.