2014-12-02 45 views
1

在一個模型類,我有一個簡單getter功能,像這樣:爲什麼scalac會因爲匹配/個案返回類型而推斷`Foo with Bar`而不僅僅是'Foo`?

def geoLoc = { 
    geoQuant match { 
     case "COUNTRY" => Country.find.byId(geoLocId) 
     case "PROVICE" => Province.find.byId(geoLocId.toLong) 
     case "CITY" => City.find.byId(geoLocId.toLong) 
     case "STREET" => Street.find.byId(geoLocId.toLong) 
    } 
    } 

的想法是獲取對象的地理位置 - 它可以是任四種類型。從我所看到的功能geoLoc有一個返回類型,它是所有的超類:Country,Province,City & Street - 它們擴展了Model類。

取而代之的是函數的返回類型是Model with GeoEntity,其中GeoEntity是一個特性,每個類都與Model一起。

爲什麼會發生這種情況?我能做些什麼來使函數返回具有模式匹配的特定類型?

回答

2

斯卡拉推斷它可以最具體的類型。這四個實例中的每一個都是ModelGeoEntity,所以這是推斷的類型:Model with GeoEntity。如果您想要函數返回不太具體的類型Model(所有Model with GeoEntity都是Model s,但不是所有Models都是Model with GeoEntity s),只需註釋該類型的函數:def geoLoc: Model = ...

該函數只能有一個返回類型,並且在編譯時無法知道它將會遇到的四種情況中的哪一種。如果你想爲每個case返回一個更具體的類型,那麼關於這個對象具有哪種類型的信息需要成爲對象類型的一部分(或者你可以使用依賴類型,但是類型信息仍然來自某個地方) 。例如。你可以使你的對象成爲一個抽象的泛型類型,並且具有特定實例的子類:

class MyObject[LocationType <: Model] { 
    def geoLoc: LocationType 
} 
class MyObjectCountry extends MyObject[Country] { 
    def geoLoc: Country = ... 
} 
class MyObjectProvice extends MyObject[Province] { 
    def geoLoc: Province = ... 
} 
相關問題