يحتوي نطاق سكالا على (العنصر:أي) الطريقة
سؤال
فيما يبدو Range
لديه طريقة تتحقق مما إذا كان يحتوي على قيمة من النوع Any.أنا أفهم أنه من SeqLike
, ولكن يسبب بعض المشاكل
على سبيل المثال، كنت أطابق الساعات من joda.DateTime:
DateTime.now match {
case d if 0 to 12 contains d.hourOfDay() => ...
هنا تقوم d.hourOfDay() بإرجاع DateTime.Property، وليس Int، ولكن لا يزال يتم تجميع التعليمات البرمجية، بسبب contains(elem: Any)
.هل هناك أي طريقة للتحقق من مثل هذه المكالمات في وقت الترجمة؟
المحلول
أنت تستطيع عرسة Range
لإضافة طريقة تحتوي على نوع أكثر أمانًا:
class SafeRange( range: Range ) {
def safeContains( i: Int ) = range contains i
}
object SafeRange {
implicit def safer( range: Range ) = new SafeRange( range )
}
استيراد ضمني والاتصال safeContains
على أي مثيل النطاق:
scala> import SafeRange._
import SafeRange._
scala> (0 until 10) safeContains 3
res2: Boolean = true
scala> (0 until 10) safeContains 100
res3: Boolean = false
scala> (0 until 10) safeContains "foo"
<console>:18: error: type mismatch;
found : java.lang.String("foo")
required: Int
(0 until 10) safeContains
نصائح أخرى
يمكنك استخدام typesafe الخاص بـ Scalaz يساوي (===
) بالتزامن مع exists
طريقة على TraversableOnce
.
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> 1 to 5 exists { _ === 2 }
res1: Boolean = true
scala> 1 to 5 exists { _ === "Hullo" }
<console>:14: error: type mismatch;
found : java.lang.String("Hullo")
required: Int
1 to 5 exists { _ === "Hullo" }
^
مرتكز على المخاريط لـ Range يبدو أنه لا توجد طريقة نطاق أفضل يمكنك استخدامها.يبدو أن الخيارات المتاحة أمامك
استخدم توقيعًا صريحًا من النوع:
case d if 0 to 12 contains (d.hourOfDay(): Int) => ...
اصنع طريقتك الخاصة:
def containsInt(r: Range, i: Int) = ...
يبدو أن هذا تم الاحتفاظ به من Java equals
كونها أدوية ما قبل الأدوية العامة، وهي مجرد واحدة من المضايقات التي تسببها هذه الحقيقة لسكالا.