سؤال

هل من الممكن كتابة طريقة "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)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top