2017-01-02 40 views
3

我已經閱讀過案例類可以用於模式匹配。但是,我也可以使用模式匹配的常規類。 This question給出了一個正規的scala透視圖。我希望從scala以及這個特定代碼的akka​​角度來看它。 例如:阿卡的案例課有什麼特別之處?

演員類:雙

class TestActor extends Actor { 

    def receive={ 
    case One(num)=>println("One "+num) 
    case t:Two=>println("Two "+t.num) 
    case _=>println("Another") 
    } 
} 

object TestActor{ 
    case class One(num:Int) 
} 

類別:

class Two(var num:Int){ } 

主要:

object Main2 extends App{ 

    val system=ActorSystem("t") 
    val testActor=system.actorOf(Props[TestActor],"test") 

    val t=new Two(200) 
    val o=TestActor.One(100) 

    testActor!o 
    testActor!t 

} 

輸出是:

One 100 
Two 200 

我知道我錯過了這裏的東西,可能是我對模式匹配的理解。有人可以幫我嗎?

+0

請注意,您不能寫'case Two(t)',因爲case類帶有一個默認的'unapply'方法來啓用,而普通類不會(儘管您可以編寫一個)。 –

+0

如果我的代碼適用於案例t:二,爲什麼我需要案例類? – codingsplash

+1

行爲當然是相同的 - 在這種情況下,它主要是可讀性問題 - 「Two(num)」允許您指定內部變量,但不管您想要如何 - 在此特定上下文中使_intent_更清晰,例如'案例二(receivedNum)'或其他。正如你引用的答案所指出的那樣,case類還有其他好處(例如默認的'equals'和'hashCode'),但是這些特定的代碼都沒有使用它們。儘管如此,對於「數據容器」類使用case類是一個很好的做法 - 如果它們的使用方式不同,它們可能會派上用場。 –

回答

4

正如您已經注意到的,與Akka中的案例類別的主要區別在於匹配時可以使用它們的提取器(不適用的方法)(除了您獲得的案例類別的常用功能,例如hashCodeequals,並與他們一起作爲產品類型)。

有了一個更大的例子,你可以看到這是如何發揮出色。例如,假設您使用Akka-HTTP客戶端向第三方服務發出HTTP請求,並且您希望以不同的方式運行,如果您獲得StatusCode.OK或任何其他狀態代碼。因爲HttpResponse提供了一個unapply方法,你可以這樣做:

case HttpResponse(StatusCodes.OK, _, entity, _)) => // We're good, parse the data. 
case HttpResponse(statusCode, _, _, _)) => // Operate on status code != OK 

相反的:

case response: HttpResponse => 
    if (response.statusCode != StatusCodes.OK) { 
    // Stuff 
    } 
    else { 
    // Other stuff 
    } 

當你的邏輯變得更加複雜,只提取你想要可以是非常有益和更簡潔的值。在我們的代碼庫,我們有一些具有多個值較複雜,是這樣的:

case (Foo(bar, baz), [email protected](statusCode, _, _, _)) 

當然,你總是可以創建一個陪伴的unapply方法反對自己,並得到一個case類自己相同的語義,但你通常不想寫這個樣板文件,讓編譯器爲你做。總之,在Akka中使用case class作爲您的數據容器可以簡化模式匹配工作,這通常是您在實施receive方法時所做的工作。

相關問題