"স্পষ্টভাবে" স্কেল সনাক্তকারী কী?


169

আমি implicitlyস্কালার উদাহরণগুলিতে ব্যবহৃত একটি ফাংশন দেখেছি । এটি কী এবং এটি কীভাবে ব্যবহৃত হয়?

উদাহরণ এখানে :

scala> sealed trait Foo[T] { def apply(list : List[T]) : Unit }; object Foo {
     |                         implicit def stringImpl = new Foo[String] {
     |                             def apply(list : List[String]) = println("String")
     |                         }
     |                         implicit def intImpl = new Foo[Int] {
     |                             def apply(list : List[Int]) =  println("Int")
     |                         }
     |                     } ; def foo[A : Foo](x : List[A]) = implicitly[Foo[A]].apply(x)
defined trait Foo
defined module Foo
foo: [A](x: List[A])(implicit evidence$1: Foo[A])Unit

scala> foo(1)
<console>:8: error: type mismatch;
 found   : Int(1)
 required: List[?]
       foo(1)
           ^
scala> foo(List(1,2,3))
Int
scala> foo(List("a","b","c"))
String
scala> foo(List(1.0))
<console>:8: error: could not find implicit value for evidence parameter of type
 Foo[Double]
       foo(List(1.0))
          ^

নোট করুন যে আমাদের লিখতে হবে implicitly[Foo[A]].apply(x)যেহেতু সংকলকটি মনে করে তার implicitly[Foo[A]](x)অর্থ আমরা implicitlyপরামিতি সহ কল করি ।

এছাড়াও কীভাবে বস্তু / প্রকার / ইত্যাদি তদন্ত করতে হয় তা দেখুন স্কেল রিপ্লে থেকে? এবং স্কালা কোথায় বোঝায়?

উত্তর:


206

আনন্দদায়ক সহজ পদ্ধতিটি ব্যবহার করার কয়েকটি কারণ এখানে রয়েছে implicitly

অন্তর্নিহিত দর্শনগুলি বোঝার / সমস্যা সমাধানের জন্য

নির্বাচনের উপসর্গ (উদাহরণস্বরূপ বিবেচনা করুন, প্রযোজ্য the.prefix.selection(args)এমন কোনও সদস্যকে ধারণ করে না এমন selectionক্ষেত্রে args( উদাহরণস্বরূপ বিবেচনা করুন) ইমপ্লিপ ভিউ ট্রিগার করা যেতে পারে argsthis এক্ষেত্রে সংকলক অন্তর্ভুক্ত সদস্যদের সন্ধান করে, স্থানীয়ভাবে সংজ্ঞায়িত বর্তমান বা সংলগ্ন স্কোপগুলিতে, উত্তরাধিকার সূত্রে প্রাপ্ত বা আমদানি করা, সেগুলি হ'ল প্রকার থেকে নির্ধারিত, বা সমতুল্য অন্তর্নিহিত পদ্ধতিগুলির the.prefixসাথে প্রকারভেদ selection

scala> 1.min(2) // Int doesn't have min defined, where did that come from?                                   
res21: Int = 1

scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>

scala> res22(1) // 
res23: AnyRef{def min(i: Int): Int} = 1

scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt

অন্তর্নির্মিত দর্শনগুলিও যখন ট্রিগার করা যায় যখন কোনও অভিব্যক্তি প্রত্যাশিত ধরণের সাথে খাপ খায় না, নীচের মতো:

scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1

সংকলকটি এখানে এই ফাংশনটির সন্ধান করে:

scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>

একটি প্রসঙ্গে বাউন্ড দ্বারা প্রবর্তিত একটি অন্তর্নিহিত প্যারামিটার অ্যাক্সেস করা

অন্তর্নিহিত প্যারামিটারগুলি ইম্পিলিটি ভিউয়ের চেয়ে স্ক্যালালের আরও গুরুত্বপূর্ণ বৈশিষ্ট্য। তারা ধরণের শ্রেণি নিদর্শনকে সমর্থন করে। মানক পাঠাগারটি scala.Orderingএটি কয়েকটি জায়গায় ব্যবহার করে - দেখুন এবং এটি কীভাবে ব্যবহৃত হয় SeqLike#sorted। অন্তর্নিহিত প্যারামিটারগুলি অ্যারে উদ্ভাসিত করতে এবং CanBuildFromউদাহরণগুলি ব্যবহার করতেও ব্যবহৃত হয় ।

স্কেলা ২.৮ সূক্ষ্ম প্যারামিটারগুলির জন্য একটি শর্টহ্যান্ড সিনট্যাক্সের অনুমতি দেয়, যা কনটেক্সট বাউন্ডস বলে। সংক্ষেপে, একটি টাইপ প্যারামিটার সহ Aএমন একটি পদ্ধতি যার জন্য প্রকারের একটি অন্তর্নিহিত পরামিতি প্রয়োজন M[A]:

def foo[A](implicit ma: M[A])

এটি আবার লিখতে পারেন:

def foo[A: M]

তবে অন্তর্নিহিত প্যারামিটারটি পাস করার তবে এটির নামকরণ কী? পদ্ধতিটি কার্যকর করার সময় এটি কীভাবে কার্যকর হতে পারে foo?

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

def foo[A: M] = {
   val ma = implicitly[M[A]]
}

সুস্পষ্টভাবে অন্তর্নিহিত পরামিতিগুলির একটি উপসেট পাস করা

ধরুন আপনি কোনও পদ্ধতিতে কল করছেন যা কোনও ব্যক্তিকে প্রিন্ট করে, টাইপ শ্রেণীবদ্ধ পদ্ধতির ব্যবহার করে:

trait Show[T] { def show(t: T): String }
object Show {
  implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
  implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }

  def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}

case class Person(name: String, age: Int)
object Person {
  implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
    def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
  }
}

val p = Person("bob", 25)
implicitly[Show[Person]].show(p)

আমরা যদি নামটি আউটপুট হিসাবে পরিবর্তন করতে চাই তবে কী হবে? আমরা স্পষ্টভাবে কল করতে পারি PersonShow, স্পষ্টভাবে একটি বিকল্প পাস করতে পারি Show[String], তবে আমরা সংকলকটি পাস করতে চাই Show[Int]

Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)

2
স্কালা> ১.মিনি (২) রেজিল: ইনট = ১ স্কালায় ২.১০.৩ এ আমি একটি ত্রুটি পেয়েছি: স্কেলা> স্পষ্টতই [ইন্ট => {ডিফ মিনিট (i: আন্ত): যে কোনও}] <কনসোল>: 8: ত্রুটি: অন্তর্নির্মিত => AnyRef {Def মিনিট (i: অন্তর্গত): যে কোনও from থেকে কোনও অন্তর্নিহিত দর্শন পাওয়া যায় না} অন্তর্নিহিতভাবে [অন্তর্গত>> {ডিফ মিনিট (i:
অন্তর্

এই উত্তরটি সর্বশেষ সংস্করণের জন্য আপডেট করা হবে।

1
স্পষ্টতই [Int => যেকোনও {Def মিনিট (i: Int): Int}] কাজ করবে। উত্তরে স্থির করা উচিত।
মালক্যাভিয়ানো

211

ImplicitlyScala 2.8 মধ্যে এখনে এবং সংজ্ঞায়িত করা হয় Predef হিসাবে:

def implicitly[T](implicit e: T): T = e

এটি সাধারণত কোনও প্রকারের অন্তর্নিহিত মান কিনা তা পরীক্ষা করতে ব্যবহৃত হয়T পাওয়া যায় এবং যদি এরকম হয় তবে তা ফেরত দিন

রেট্রোনিয়ামের উপস্থাপনা থেকে সরল উদাহরণ :

scala> implicit val a = "test" // define an implicit value of type String
a: java.lang.String = test
scala> val b = implicitly[String] // search for an implicit value of type String and assign it to b
b: String = test
scala> val c = implicitly[Int] // search for an implicit value of type Int and assign it to c
<console>:6: error: could not find implicit value for parameter e: Int
       val c = implicitly[Int]
                         ^

6
পদ্ধতিটি ঠিক পরীক্ষা করে না; এটি কোনও সংকলন ত্রুটির কারণ বলে মনে হয় যদি কোনও অন্তর্ভুক্ত মান উপলব্ধ না হয় এবং যদি থাকে তবে এটি পুনরুদ্ধার করে। আমি কেন কখনও এটি ব্যবহার করতে চাই তার উপর আপনি আরও কিছু প্রসঙ্গ সরবরাহ করতে পারেন?
davetron5000

17
implicitly[Ordering[(Int, String)]].compare( (1, "b"), (1, "a") ):, বিশেষ করে একটি অন্তর্নিহিত প্যারামিটারটি প্রসঙ্গ চালু বাউন্ড পুনরুদ্ধার করতেdef foo[A: Ordering](a1: A, a2: A) = implicitly[Ordering[A]].compare(a1, a2)
retronym

1
উপরের ভিডিও লিঙ্কে রেট্রোনিয়ামের আলোচনাটি দেখতে, 13:50 পয়েন্টটিতে যান।
বিশৃঙ্খল 3 কিলিব্রিয়াম

-2

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


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


4
টাইপ স্বাক্ষর নথি এটি বেশ ভাল।
retronym

21
implicitস্কালায় একটি গুরুত্বপূর্ণ ভাষা-বৈশিষ্ট্য বলে মনে হয় এবং যথাযথ ব্যাখ্যা দেওয়ার উপযুক্ত explanation কেবলমাত্র একটি স্বাক্ষর গণনা বিশদ সম্পর্কিত ডক্স ভাবা সত্যিকারের উত্তরের চেয়ে বৌদ্ধিক স্ব-সন্তুষ্টির মতো বলে মনে হয়। ওপি কর্তৃক জিজ্ঞাসা করা নির্দিষ্ট প্রশ্নগুলি দেখুন - এটি কী এবং এটি কীভাবে ব্যবহৃত হয়? এর দ্বারা উত্তর দেওয়া হয় নি, বা রাতে ডক্সে যা আপনি এমনকি কোনও আসল লিঙ্ক সরবরাহ করে না। scala-lang.org/files/archive/nightly/docs/library/… এটি কিছুই শেখায় না। জেনুইন ডক্সের উদাহরণগুলির জন্য নিক্লাস রাইথ বা টার্বো প্যাসকাল দেখুন। -1
থমাস ডব্লিউ

3
implicit এবং implicitly সম্পর্কিত, কিন্তু বেশ স্বতন্ত্র। implicitশব্দ ভাষা অংশ। implicitlyস্ট্যান্ডার্ড লাইব্রেরিতে স্কেলা কোডে সংজ্ঞায়িত করা হয়। যেহেতু অন-লাইন ডক্সে উত্সের লিঙ্কগুলি অন্তর্ভুক্ত রয়েছে, তাই আমি বিশ্বাস করি যে প্রশ্নকর্তাদের সেই নথি এবং লিঙ্কযুক্ত উত্সের দিকে উল্লেখ করা ভাল best
র‌্যান্ডাল স্কুল্জ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.