2012-02-27 73 views
5

例如我需要訪問函數def a[A:ClassManifest]中的清單來獲取擦除類。我可以使用Predef.implicitly函數,但在這種情況下,我的代碼將會像使用完整形式def a[A](implicit b:ClassManifest[A])一樣長。 那麼這些隱式參數是否有方便生成的名稱?如何訪問隱式「隱式」即def a [A:B]或def a [A <%B]?

+1

您可以隨時聲明一個名稱較小的方法,但不應該依賴Scalac生成的魔術名稱。 – 2012-02-28 14:43:06

回答

5

有在Predef三個預定義的方法,將做到這一點對Manifest S,ClassManifest S和OptManifest S:manifest[T],分別classManifest[T]optManifest[T]。您可以根據相同的模式爲其他類型編寫自己的這種「隱式獲取器」。這裏是例如manifest[T]

def manifest[T](implicit m: Manifest[T]) = m 

因此,這裏是你如何可以編寫自己:

trait UsefulTypeclass[A] { 
    def info = 42 // sample method 
} 

// the 「implicit getter」 
def usefulTypeclass[A](implicit tc: UsefulTypeclass[A]) = tc 

// a method that uses the implicit getter 
def foo[A: UsefulTypeclass] = 
    usefulTypeclass[A].info 
+2

作爲一個巧妙的技巧:如果您將隱式getter命名爲「apply」並將其放在UsefulTypeclass的伴隨對象上,則可以使用「UsefulTypeclass [T]」作爲代表T類類型實例的值,而不必導入任何超過類型類本身。 – 2012-02-27 21:51:36

+0

@RM好戲。我想它必須是'UsefulTypeclass [T]()'(帶額外的'()')。 – 2012-02-28 09:43:44

+0

其實它不需要parens。如果你有(赦免缺少格式)對象TC {def apply [T](implicit x:TC [T])= x},你可以從字面上用「TC [SomeClass]」來調用它,因爲正在定義「apply」作爲帶有隱式參數列表的無參數方法,並且[SomeClass]僅從對TC對象的引用中消除歧義。它desugars到TC.apply [SomeClass](theImplicitValue) – 2012-02-28 15:23:47

0

scalap來救援!

我把這個代碼:

object TestThing extends App { 
    def one { println("one") } 
    def two[T] { println("two") } 
    def three[T : Manifest] { println("three") } 
    def four[T: Manifest, U : Manifest] { println("four") } 
} 

並運行它通過scalap。下面是我的了:

object TestThing extends java.lang.Object with scala.App with scala.ScalaObject { 
    def this() = { /* compiled code */ } 
    def one : scala.Unit = { /* compiled code */ } 
    def two[T] : scala.Unit = { /* compiled code */ } 
    def three[T](implicit evidence$1 : scala.Predef.Manifest[T]) : scala.Unit = { /* compiled code */ } 
    def four[T, U](implicit evidence$2 : scala.Predef.Manifest[T], evidence$3 : scala.Predef.Manifest[U]) : scala.Unit = { /* compiled code */ } 
} 

正如你所看到的,第一個隱含的清單被稱爲evidence$1。第二個和第三個雖然在不同的範圍!-被稱爲evidence$2evidence$3。所以......這就是你如何參考清單。

儘管如此,對我而言,刪除類中較高級的Manifest會更改位於文件較低位置的Manifest的名稱,這似乎有點可怕。同樣,IntelliJ Scala插件的語法突出顯示似乎也認爲four()範圍內的清單變量是evidence$1evidence$2,並且它認爲evidence$3不是那裏的有效變量(儘管它是,和evidence$1不是)。總體而言,也許這些事情應該被視爲關於使用隱式Manifest變量的警告信號?

+2

當然,這些名稱應該是一個內部實現細節,而不是依賴! – Ben 2012-02-27 20:23:53

+0

@Ben你不會在那裏反對我...... – Destin 2012-02-27 20:27:36

+1

這就是爲什麼你使用'implicitly' ......試圖在代碼中使用'evidence $ 1'等等不會編譯的原因。 – 2012-02-27 23:50:49

相關問題