كيفية كتابة "asInstanceOfOption" في سكالا
-
05-07-2019 - |
سؤال
هل من الممكن كتابة طريقة "asInstanceOfOption" التي من شأنها أن تفعل ما هو المقصود بالكود (الزائف) التالي؟
def asInstanceOfOption[T](o: Any): Option[T] =
if (o.isInstanceOf[T]) Some(o.asInstanceOf[T]) else None
المحلول
يحرر فيما يلي إجابتي الأصلية ولكن يمكنك تحقيق ذلك الآن باستخدام
def asInstanceOfOption[T: ClassTag](o: Any): Option[T] =
Some(o) collect { case m: T => m}
يمكنك استخدام البيانات للالتفاف على حقيقة أن النوع T
يكون تمحى في وقت التجميع:
scala> import scala.reflect._
import scala.reflect._
scala> def asInstanceOfOption[B](x : Any)(implicit m: Manifest[B]) : Option[B] = {
| if (Manifest.singleType(x) <:< m)
| Some(x.asInstanceOf[B])
| else
| None
| }
asInstanceOfOption: [B](x: Any)(implicit m: scala.reflect.Manifest[B])Option[B]
ثم يمكن استخدام هذا:
scala> asInstanceOfOption[Int]("Hello")
res1: Option[Int] = None
scala> asInstanceOfOption[String]("World")
res2: Option[String] = Some(World)
يمكنك حتى استخدام التحويلات الضمنية للحصول على هذا ليكون وسيلة متاحة على Any
.أعتقد أنني أفضل اسم الطريقة matchInstance
:
implicit def any2optionable(x : Any) = new { //structural type
def matchInstance[B](implicit m: Manifest[B]) : Option[B] = {
if (Manifest.singleType(x) <:< m)
Some(x.asInstanceOf[B])
else
None
}
}
الآن يمكنك كتابة كود مثل:
"Hello".matchInstance[String] == Some("Hello") //true
"World".matchInstance[Int] == None //true
يحرر:كود محدث لـ 2.9.x، حيث لا يمكن استخدامه Any
لكن فقط AnyRef
:
implicit def any2optionable(x : AnyRef) = new { //structural type
def matchInstance[B](implicit m: Manifest[B]) : Option[B] = {
if (Manifest.singleType(x) <:< m)
Some(x.asInstanceOf[B])
else
None
}
}
نصائح أخرى
وإليك التفصيل في الإجابة oxbow_lake المحدثة، محدثة المزيد تتطلب سكالا 2.10:
// Implicit value class
implicit class Castable(val obj: AnyRef) extends AnyVal {
def asInstanceOfOpt[T <: AnyRef : ClassTag] = {
obj match {
case t: T => Some(t)
case _ => None
}
}
}
ويمكن استخدام هذا عن طريق القيام:
"Hello".asInstanceOfOpt[String] == Some("Hello") // true
"foo".asInstanceOfOpt[List[_]] == None // true
ولكن كما ذكر في إجابات أخرى هذا لا يعمل من أجل البدائيون بسبب قضايا الملاكمة، كما أنها لا تعامل مع الأدوية بسبب المحو. عدم السماح البدائيون، وأنا مقيدة obj
وT
تمديد AnyRef
. للحصول على حل الذي يعالج الأوليات، الرجوع إلى الإجابة عن السؤال متابعة مات R ل:
كيفية كتابة asInstanceOfOpt [T] حيث T <: أي أ >
بشع الصورة Typeable، الذي يعالج الأوليات فضلا عن العديد من حالات المحو:
وفي وقت كتابة الجواب oxbow_lakes وكان (أواخر '09)، وأعتقد scala.util.Try
غير متوفرة، ولكن الآن (أي اعتبارا من 2.10) وأعتقد scala.util.Try
هو يفضل (أو أيضا على الأقل تبحث أجمل) الطريقة للقيام بذلك:
scala> Try((3).asInstanceOf[String]).toOption
res0: Option[String] = None
scala> Try("hello".asInstanceOf[String]).toOption
res1: Option[String] = Some(hello)