2016-02-29 175 views
1

消除返回類型考慮下面的Scala代碼片段:通過擦除斯卡拉

def func(param: Any): Int = param match { 
    case f: (String => Int) => f("apple") 
    case i: Int => i 
} 

println(func((s: String) => s.length)) 

正常工作,但是,在編譯時,我得到以下警告:

<console>:11: warning: non-variable type argument String in type pattern String => Int is unchecked since it is eliminated by erasure 
     case f: (String => Int) => f("apple") 

我怎樣才能擺脫此警告訊息?

感謝您的幫助提前!

回答

3

收到消息的原因是因爲Java的通用type erasure。在這種情況下,您的Function[String, Int]類型的功能將與任何Function[A, B]匹配。

爲了擺脫這個警告,你應該使用scala typetags這將允許你區分不同的功能類型。

的代碼片段是以下,

import scala.reflect.runtime.universe._ 

object Answer { 
def function[A](param: A)(implicit tt: TypeTag[A]): String = param match { 
    case f: (String => Int) @unchecked if typeOf[String => Int] =:= typeOf[A] => f("apple").toString 
    case f: (Int => String) @unchecked if typeOf[Int => String] =:= typeOf[A] => f(32 + 1) 
    case s: String => s"hello $s" 
    } 

    def main (args: Array[String]) { 
    println(function((s: String) => s.length)) 
    println(function((i: Int) => i.toString)) 
    println(function("world")) 
    } 
} 

的關鍵部分是有一個implicitTypeTag[A]它是在編譯時,其包括該功能typeOf需要檢查類型的A針對別的元數據添加。

+0

感謝您的解釋和鏈接!我試圖解決警告但失敗。現在我對'TypeTag'的含義有了一個理論上的認識,而且我知道'case f:((_)=>(_))=>'不會抱怨。但是,在後一種情況下,'f(...)'會導致編譯器錯誤。請您這麼友好地給我一些進一步的提示如何繼續?謝謝! –

+0

用代碼片段更新。 – yw3410

+0

感謝您的解釋性代碼!它確實更精確,因爲我們現在可以區分String => Int和Int => String。我已經嘗試過了,但不幸的是現在有兩次同樣的警告。 我嘗試了以下方法:'type oneParamFuncType = _ => _',並且在兩種情況下都使用'case f:oneParamFuncType ...',但是,這會導致函數調用時發生編譯器錯誤。如果沒有函數調用,編譯器會很高興。你有沒有想法如何將通用'oneParamFuncType'轉換爲特定的? –