ছদ্মবেশের প্রকারগুলি
স্কালায় প্রভাবগুলি হয় এমন কোনও মানকে বোঝায় যা "স্বয়ংক্রিয়ভাবে" উত্তীর্ণ হতে পারে, তাই কথা বলতে বা এক ধরণের থেকে অন্য ধরণের রূপান্তর যা স্বয়ংক্রিয়ভাবে তৈরি হয়।
অন্তর্নিহিত রূপান্তর
পরের ধরণের সম্পর্কে খুব সংক্ষেপে কথা বললে, যদি কোনও শ্রেণীর m
কোনও বস্তুর উপর কোনও পদ্ধতি কল করে এবং সেই শ্রেণিটি পদ্ধতিটিকে সমর্থন করে না , তবে স্কালা কোনও কিছুকে সমর্থন করে এমন একটি রূপান্তর রূপান্তর খুঁজবে । একটি সহজ উদাহরণ পদ্ধতি হবে :o
C
m
C
m
map
String
"abc".map(_.toInt)
String
পদ্ধতি অবলম্বন পাওয়া যায়নি map
, কিন্তু StringOps
না, এবং সেখান থেকে একটি অন্তর্নিহিত রূপান্তর এর String
থেকে StringOps
উপলব্ধ (দেখুন implicit def augmentString
উপর Predef
)।
অন্তর্নিহিত পরামিতি
অন্য ধরণের ইমপ্লিট প্যারামিটার । এগুলি অন্য কোনও প্যারামিটারের মতো পদ্ধতি কলগুলিতে পাস করা হয় তবে সংকলক সেগুলি স্বয়ংক্রিয়ভাবে পূরণ করার চেষ্টা করে। এটি না পারলে অভিযোগ করবে। কেউ এই প্যারামিটারগুলি স্পষ্টভাবে পাস করতে পারে, যা এটি কীভাবে ব্যবহার করে breakOut
, উদাহরণস্বরূপ ( breakOut
কোনও দিন আপনি কোনও চ্যালেঞ্জের জন্য অনুভব করছেন সে সম্পর্কে প্রশ্ন দেখুন )।
এক্ষেত্রে, কোনও ব্যক্তিকে প্রয়োজনের ঘোষণা দিতে হবে, যেমন foo
পদ্ধতি ঘোষণার মতো:
def foo[T](t: T)(implicit integral: Integral[T]) {println(integral)}
সীমা দেখুন
এখানে একটি পরিস্থিতি রয়েছে যেখানে অন্তর্নিহিত হ'ল অন্তর্নিহিত রূপান্তর এবং অন্তর্নিহিত পরামিতি উভয়ই। উদাহরণ স্বরূপ:
def getIndex[T, CC](seq: CC, value: T)(implicit conv: CC => Seq[T]) = seq.indexOf(value)
getIndex("abc", 'a')
পদ্ধতিটি getIndex
কোনও অবজেক্ট গ্রহণ করতে পারে, যতক্ষণ না তার শ্রেণি থেকে কোনও অন্তর্নিহিত রূপান্তর উপলব্ধ থাকে Seq[T]
। যে কারণে, আমি পাস করতে পারেন String
থেকে getIndex
, এবং এটি কাজ করবে।
পর্দার আড়ালে, সংকলকটিতে পরিবর্তিত seq.IndexOf(value)
হয় conv(seq).indexOf(value)
।
এটি এতটাই কার্যকর যে এগুলি লেখার জন্য সিনট্যাকটিক চিনি রয়েছে। এই সিনট্যাকটিক চিনি ব্যবহার করে, এটির getIndex
মতো সংজ্ঞা দেওয়া যেতে পারে:
def getIndex[T, CC <% Seq[T]](seq: CC, value: T) = seq.indexOf(value)
এই অন্বিত চিনি হিসেবে বর্ণনা করা হয়েছে দৃশ্য আবদ্ধ , এর একটি সদৃশ উপরের আবদ্ধ ( CC <: Seq[Int]
ক) বা নিম্ন মুখী ( T >: Null
)।
প্রসঙ্গ সীমা
অন্তর্নিহিত পরামিতিগুলির আর একটি সাধারণ প্যাটার্ন হ'ল ধরণ শ্রেণির ধরণ । এই প্যাটার্নটি ক্লাসগুলিতে সাধারণ ইন্টারফেসের বিধানকে সক্ষম করে যা তাদের ঘোষণা করে না। এটি উভয়ই একটি সেতুর প্যাটার্ন হিসাবে পরিবেশন করতে পারে - উদ্বেগের পৃথকীকরণ - এবং অ্যাডাপ্টারের নিদর্শন হিসাবে।
আপনি যে Integral
শ্রেণীর কথা উল্লেখ করেছেন তা হ'ল ধরণের শ্রেণিবদ্ধের নমুনা। স্কালার স্ট্যান্ডার্ড লাইব্রেরির আর একটি উদাহরণ Ordering
। এখানে একটি লাইব্রেরি রয়েছে যা এই প্যাটার্নটির ভারী ব্যবহার করে যার নাম স্কালাজ।
এটি এর ব্যবহারের একটি উদাহরণ:
def sum[T](list: List[T])(implicit integral: Integral[T]): T = {
import integral._ // get the implicits in question into scope
list.foldLeft(integral.zero)(_ + _)
}
এর জন্য সিনট্যাকটিক চিনিও রয়েছে, যাকে প্রসঙ্গবদ্ধ বাউন্ড বলা হয়, যা অন্তর্নিহিতকে উল্লেখ করার প্রয়োজনে কম দরকারী করে তোলে। এই পদ্ধতির একটি সরল রূপান্তর এইরকম দেখাচ্ছে:
def sum[T : Integral](list: List[T]): T = {
val integral = implicitly[Integral[T]]
import integral._ // get the implicits in question into scope
list.foldLeft(integral.zero)(_ + _)
}
প্রসঙ্গ সীমা আরো উপযোগী যখন আপনি শুধু প্রয়োজন হয় পাস তাদের অন্যান্য পদ্ধতি যে তাদের ব্যবহার করতে। উদাহরণস্বরূপ, পদ্ধতি sorted
উপর Seq
একটি অন্তর্নিহিত প্রয়োজন Ordering
। একটি পদ্ধতি তৈরি করতে reverseSort
, কেউ লিখতে পারেন:
def reverseSort[T : Ordering](seq: Seq[T]) = seq.sorted.reverse
যেহেতু Ordering[T]
অন্তর্নিহিতভাবে প্রেরণ করা হয়েছিল reverseSort
, এটি পরে এটি সম্পূর্ণরূপে প্রেরণ করতে পারে sorted
।
ইমপ্লিটস কোথা থেকে আসে?
যখন সংকলক কোনও অন্তর্নিহিতের প্রয়োজনীয়তাটি দেখেন, হয় আপনি এমন কোনও পদ্ধতির জন্য যা যা বস্তুর শ্রেণীর অস্তিত্ব নেই, বা আপনি কোনও এমন পদ্ধতির জন্য আহ্বান করছেন যা একটি অন্তর্নিহিত প্যারামিটারের প্রয়োজন হয়, এটি এমন একটি অন্তর্নিহিত অনুসন্ধান করবে যা প্রয়োজনীয়তার সাথে উপযুক্ত হবে ।
এই অনুসন্ধানটি নির্দিষ্ট বিধিগুলি মেনে চলে যা সংজ্ঞায়িত করে যে কোন ফলগুলি দৃশ্যমান এবং কোনটি নয়। নিম্নলিখিত সারণীটি বোঝাচ্ছে যেখানে সংকলক জড়িতদের জন্য অনুসন্ধান করবে তা জোশ সুরেথের দ্বারা প্রভাবিত হওয়া সম্পর্কে একটি দুর্দান্ত উপস্থাপনা থেকে নেওয়া হয়েছিল , যা আমি তাদের স্কাল জ্ঞানের উন্নতি করতে চাইলে আন্তরিকভাবে সুপারিশ করি। প্রতিক্রিয়া এবং আপডেটের পরে এটি পরিপূরক হয়েছে।
নীচে ১ নম্বর নীচে থাকা ইমপ্লিটগুলি 2 নং এর অধীনগুলির চেয়ে বেশি প্রাধান্য পেয়েছে that এটির বাইরেও যদি বেশ কয়েকটি যোগ্য যুক্তি থাকে যা অন্তর্নিহিত প্যারামিটারের ধরণের সাথে মেলে, স্থিতিশীল ওভারলোডিং রেজোলিউশনের নিয়ম ব্যবহার করে একটি সুনির্দিষ্ট নির্দিষ্টটি বেছে নেওয়া হবে (স্কেলা দেখুন) নির্দিষ্টকরণ .6.26.3) .3 এই উত্তরটির শেষে আমি সংযুক্ত একটি প্রশ্নের মধ্যে আরও বিস্তারিত তথ্য পাওয়া যাবে।
- বর্তমানের সুযোগে প্রথম চেহারা
- প্রভাব বর্তমানের স্কোপে সংজ্ঞায়িত
- সুস্পষ্ট আমদানি
- ওয়াইল্ডকার্ড আমদানি
অন্যান্য ফাইলগুলিতে একই সুযোগ
- এখন সম্পর্কিত প্রকারগুলি দেখুন
- এক প্রকারের সহযোগী বস্তু
- একটি আর্গুমেন্টের ধরণের অন্তর্নিহিত সুযোগ (২.৯.১)
- ধরণের আর্গুমেন্টের অন্তর্নিহিত সুযোগ (২.৮.০)
- নেস্টেড প্রকারের জন্য বাহ্যিক বস্তু
- অন্যান্য মাত্রা
আসুন তাদের জন্য কয়েকটি উদাহরণ দিন:
ফলস্বরূপ ব্যাপ্তিতে সংজ্ঞা দেওয়া
implicit val n: Int = 5
def add(x: Int)(implicit y: Int) = x + y
add(5) // takes n from the current scope
সুস্পষ্ট আমদানি
import scala.collection.JavaConversions.mapAsScalaMap
def env = System.getenv() // Java map
val term = env("TERM") // implicit conversion from Java Map to Scala Map
ওয়াইল্ডকার্ড আমদানি
def sum[T : Integral](list: List[T]): T = {
val integral = implicitly[Integral[T]]
import integral._ // get the implicits in question into scope
list.foldLeft(integral.zero)(_ + _)
}
অন্যান্য ফাইলগুলিতে একই সুযোগ
সম্পাদনা : দেখে মনে হচ্ছে এর আলাদা নজির নেই। আপনার যদি এমন কিছু উদাহরণ রয়েছে যা একটি নজিরের পার্থক্য দেখায়, দয়া করে একটি মন্তব্য করুন। অন্যথায়, এই এক উপর নির্ভর করবেন না।
এটি প্রথম উদাহরণের মতো, তবে অনুমানযোগ্য সংজ্ঞাটি এর ব্যবহারের চেয়ে আলাদা ফাইলে রয়েছে। কীভাবে প্যাকেজ অবজেক্টগুলি কার্যকর করতে আনতে ব্যবহৃত হতে পারে তা দেখুন ।
এক প্রকারের কম্পেনিয়ান অবজেক্টস
এখানে নোটের দুটি অবজেক্ট সহচর রয়েছে। প্রথমে "উত্স" প্রকারের অবজেক্টের সহচরটিকে সন্ধান করা হবে। উদাহরণস্বরূপ, অবজেক্টের অভ্যন্তরে Option
একটি অন্তর্নিহিত রূপান্তর রয়েছে Iterable
, সুতরাং কেউ Iterable
পদ্ধতিগুলিতে কল করতে পারে Option
বা কোনওটি Option
প্রত্যাশা করে পাস করতে পারে Iterable
। উদাহরণ স্বরূপ:
for {
x <- List(1, 2, 3)
y <- Some('x')
} yield (x, y)
এই অভিব্যক্তিটি অনুবাদক দ্বারা অনুবাদ করেছেন
List(1, 2, 3).flatMap(x => Some('x').map(y => (x, y)))
যাইহোক, List.flatMap
একটি আশা TraversableOnce
, যা Option
হয় না। সংকলকটি তখন Option
এর অবজেক্টের সহচরের অভ্যন্তরের দিকে তাকায় এবং রূপান্তরটি সন্ধান করে Iterable
যা একটি TraversableOnce
, যা এই অভিব্যক্তিটিকে সঠিক করে তোলে।
দ্বিতীয়ত, প্রত্যাশিত ধরণের সহযোগী অবজেক্ট:
List(1, 2, 3).sorted
পদ্ধতিটি sorted
নিহিত থাকে Ordering
। এই ক্ষেত্রে, এটি বস্তুর ভিতরে দেখায় Ordering
, শ্রেণীর সহকর্মী Ordering
এবং Ordering[Int]
সেখানে একটি অন্তর্নিহিত খুঁজে পায় ।
নোট করুন যে সুপার ক্লাসগুলির সহযোগী অবজেক্টগুলিও অনুসন্ধান করা হয়। উদাহরণ স্বরূপ:
class A(val n: Int)
object A {
implicit def str(a: A) = "A: %d" format a.n
}
class B(val x: Int, y: Int) extends A(y)
val b = new B(5, 2)
val s: String = b // s == "A: 2"
এভাবেই স্ক্যালাল অন্তর্নিহিত Numeric[Int]
এবং Numeric[Long]
আপনার প্রশ্নের মধ্যে খুঁজে পেয়েছিল, যেমন তারা ভিতরে খুঁজে পাওয়া যায় Numeric
, না Integral
।
একটি আর্গুমেন্টের প্রকারের অন্তর্নিহিত ব্যাপ্তি
আপনার যদি একটি আর্গুমেন্ট টাইপ সহ কোনও পদ্ধতি থাকে A
তবে প্রকারের অন্তর্নিহিত সুযোগটিও A
বিবেচনা করা হবে। "অন্তর্নিহিত সুযোগ" দ্বারা আমি বোঝাতে চাইছি যে এই সমস্ত বিধিগুলি পুনরাবৃত্তির সাথে প্রয়োগ করা হবে - উদাহরণস্বরূপ, A
উপরের নিয়ম অনুসারে এর সহকর্মী অবজেক্টগুলি নিদর্শনগুলির জন্য অনুসন্ধান করা হবে।
নোট করুন যে এর অর্থ এই নয় যে এই A
পরামিতিটির রূপান্তরগুলির জন্য অন্তর্নিহিত সুযোগটি অনুসন্ধান করা হবে, তবে পুরো অভিব্যক্তিটি। উদাহরণ স্বরূপ:
class A(val n: Int) {
def +(other: A) = new A(n + other.n)
}
object A {
implicit def fromInt(n: Int) = new A(n)
}
// This becomes possible:
1 + new A(1)
// because it is converted into this:
A.fromInt(1) + new A(1)
এটি স্কেলা ২.৯.১ থেকে উপলব্ধ।
প্রকার আর্গুমেন্টের অন্তর্নিহিত সুযোগ
প্রকারের শ্রেণীর প্যাটার্নটি সত্যই কার্যকর করতে এটি প্রয়োজন। Ordering
উদাহরণস্বরূপ বিবেচনা করুন : এটি এর সহযোগী অবজেক্টে কিছু জড়িত নিয়ে আসে তবে আপনি এতে স্টাফ যোগ করতে পারবেন না। তাহলে আপনি কীভাবে Ordering
নিজের ক্লাসের জন্য একটি স্বয়ংক্রিয়ভাবে সন্ধান করতে পারেন?
এর বাস্তবায়ন দিয়ে শুরু করা যাক:
class A(val n: Int)
object A {
implicit val ord = new Ordering[A] {
def compare(x: A, y: A) = implicitly[Ordering[Int]].compare(x.n, y.n)
}
}
সুতরাং, আপনি কল করলে কী হয় তা বিবেচনা করুন
List(new A(5), new A(2)).sorted
যেমনটি আমরা দেখেছি, পদ্ধতিটি sorted
একটি প্রত্যাশা করে Ordering[A]
(আসলে, এটি একটি Ordering[B]
, কোথায় প্রত্যাশা করে B >: A
)। ভিতরে এরকম কোনও জিনিস নেই Ordering
, এবং কোনও "উত্স" টাইপ নেই যা দেখতে হবে। একথাও ঠিক যে, এটা ভিতরে খুঁজে পেতে হয় A
, যা একটি হল টাইপ যুক্তি এর Ordering
।
বিভিন্ন সংগ্রহের পদ্ধতিগুলিও কীভাবে প্রত্যাশার CanBuildFrom
কাজটি করে: এর প্রকারের পরামিতিগুলির ক্ষেত্রে সহকর্মী অবজেক্টগুলির মধ্যে ফলস্বরূপগুলি পাওয়া যায় CanBuildFrom
।
দ্রষ্টব্য : Ordering
সংজ্ঞায়িত করা হয় trait Ordering[T]
, যেখানে T
একটি টাইপ পরামিতি। পূর্বে, আমি বলেছিলাম যে স্কালা প্রকারের প্যারামিটারগুলির ভিতরে দেখেছিল, যা বেশি বোঝায় না। অন্তর্নিহিত উপরে জন্য লাগছিল Ordering[A]
, যেখানে A
, একটি প্রকৃত ধরনের পরামিতি টাইপ না: এটা হল টাইপ যুক্তি করতে Ordering
। স্কালার স্পেসিফিকেশনের 7.2 বিভাগ দেখুন।
এটি স্কেলা ২.৮.০ থেকে উপলব্ধ।
নেস্টেড টাইপের জন্য আউটার অবজেক্টস
আমি আসলে এর উদাহরণ দেখিনি। কেউ যদি ভাগ করে নিতে পারে তবে আমি কৃতজ্ঞ থাকব। নীতিটি সহজ:
class A(val n: Int) {
class B(val m: Int) { require(m < n) }
}
object A {
implicit def bToString(b: A#B) = "B: %d" format b.m
}
val a = new A(5)
val b = new a.B(3)
val s: String = b // s == "B: 3"
অন্যান্য মাত্রা
আমি নিশ্চিত যে এটি একটি রসিকতা ছিল, তবে এই উত্তরটি আপ টু ডেট নাও হতে পারে। তাই এই প্রশ্নটি যা হচ্ছে তার চূড়ান্ত সালিশী হিসাবে গ্রহণ করবেন না এবং যদি আপনি লক্ষ্য করেন যে এটি পুরানো হয়ে গেছে, দয়া করে আমাকে জানান যাতে আমি এটি ঠিক করতে পারি।
সম্পাদনা
আগ্রহের সম্পর্কিত প্রশ্ন: