2016-11-29 73 views
3

下面的代碼:斯卡拉直列不應用提取

object Test { 
    @inline def unapply(i: Int): Option[String] = 
    i match { 
     case 1 => Some("Got 1") 
     case 2 => Some("Got 2") 
     case 3 => throw new Exception("Should not test 3") 
     case _ => None 
    } 
    def test(i: Int) = i match { 
    case Test(k) => k 
    case 4 => "Another 4" 
    case _ => "" 
    } 
} 
Test.test(3) 

導致以下錯誤:

... 
at Test$.unapply(<console>:13) 
at Test$.test(<console>:17) 
... 

注意,很顯然在錯誤的來源。但是,錯誤顯示unapply方法沒有按照我的意圖進行內聯。
我該如何內聯這種不適用的方法?這是出於性能原因以及代碼重用。

+0

我不確定,但即使該方法是內聯的,Scala可以保持原始的堆棧跟蹤嗎? – marstran

+0

你期待什麼水平的性能改進? – Pavel

+1

@marstran我檢查了反彙編,我可以確認該方法沒有內聯。事實上,JVM允許在內聯函數上生成調試代碼。 –

回答

3

@inline只有請求表示編譯器試圖內聯一個方法,但它不必,在某些情況下它不能。我並不認爲編譯器有什麼可以或不可以內聯的規範(儘管如果存在的話我很樂意看到它),但我敢打賭編譯器根本不會在這種情況下,不會不管你做什麼。

總的來說,無論如何,你只需要內嵌一些常數或較小的東西並且不太可能改變。否則,Test.unapply的許多用途將導致編譯後的代碼快速增加,並且對內聯方法的更改將遍及所有引用它的內容。

This answer來自@RexKerr說夠了。