2013-12-12 21 views
1

我想動態地將變量轉換爲Option[T]。語義是:如果變量x匹配T類型,則投射應返回Some(x),否則應返回None。使用單個地圖調用比使用isInstanceOf[T]伴隨asInstanceOf[T]或構建怪異的外殼開關要乾淨得多。如何動態地將變量轉換爲選項

我曾嘗試一些簡單的代碼下面

object OptionCast { 
    def apply[T](source : Any) : Option[T] = source match { 
    case s : T => Some(s) 
    case _ => None 
    } 
} 

但它實際上忽略了類型:OptionCast[Int]("some").map(_ + 2)給我的錯誤類型。

我該如何重寫這段代碼?

+0

try:source:T instead? –

+0

@StefanKunze問題是應用結果類型被刪除(選項[T]),而不是輸入 –

+0

動態投射需要從任何類型投射 – ayvango

回答

4

您的代碼存在的問題是T被擦除 - 字節碼中的方法沒有類型參數,所以T被清除爲Object,因此對於所有內容都是正確的。

這工作,有一些限制:

import scala.reflect.ClassTag 
object OptionCast { 
    def apply[T : ClassTag](source : Any) : Option[T] = source match { 
    case s : T => Some(s) 
    case _ => None 
    } 
} 

這裏有兩個重要的限制:

  1. 它不能檢查類型參數,因爲類型參數被擦除的運行時間。這意味着你可以撥打OptionCast.apply[List[Int]](List("a")),它將返回Some(List("a"))。爲了解決這個問題,你必須避免類型擦除。
  2. 任何AnyVal類將被裝箱,所以你必須檢查java.lang.Integer趕上Int,依此類推。