在模型类中,我有一个简单的getter
函数,如下所示:
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)
}
}
想法是获取对象的GeoLocation - 可以是四种类型中的任何一种。从我看到的,函数geoLoc
有一个返回类型,它是所有的超类:Country
,Province
,City
& Street
- 扩展Model
类。
相反,函数的返回类型为Model with GeoEntity
,其中GeoEntity
是每个类与Model
一起的特征。
为什么会这样?如何使函数返回具有模式匹配的特定类型?
答案 0 :(得分:2)
Scala推断出最具体的类型。四个实例中的每一个都是Model
和GeoEntity
,因此这是推断类型:Model with GeoEntity
。如果您希望函数返回不太具体的Model
类型(所有Model with GeoEntity
都是Model
s,但并非所有Models
都是Model with GeoEntity
s),只需使用该类型注释函数:def geoLoc: Model = ...
。
该函数只能有一种返回类型,并且无法在编译时知道它将遇到的四种情况中的哪一种。如果你想为每种情况返回一个更具体的类型,那么关于这个对象需要哪种类型的信息需要成为对象类型的一部分(或者你可以使用依赖类型,但类型信息仍然必须来自某个地方) 。例如。你可以使你的对象成为一个抽象的泛型类型,具有特定实例的子类:
class MyObject[LocationType <: Model] {
def geoLoc: LocationType
}
class MyObjectCountry extends MyObject[Country] {
def geoLoc: Country = ...
}
class MyObjectProvice extends MyObject[Province] {
def geoLoc: Province = ...
}