Scala:无法使用超类型声明对函数的引用
很抱歉我问了noob这个问题,但我对Scala很陌生 我有以下Scala类:Scala:无法使用超类型声明对函数的引用,scala,compiler-errors,Scala,Compiler Errors,很抱歉我问了noob这个问题,但我对Scala很陌生 我有以下Scala类: class Test { class Request {def getValue(): String = {"request"}} class Response {def getValue(): String = {"response"}} case class MyRequest(message: String) extends Request case class MyRespons
class Test {
class Request {def getValue(): String = {"request"}}
class Response {def getValue(): String = {"response"}}
case class MyRequest(message: String) extends Request
case class MyResponse(message: String) extends Response
val myFunction: (Request) => Response = doSomething
private val functions = scala.collection.mutable.Map[String, (Request) => Response](
"myFunction" -> myFunction
)
def doSomething(request: MyRequest): MyResponse = {
null
}
}
无法编译,出现以下错误:
type mismatch;
found : Test.this.MyRequest => Test.this.MyResponse
required: Test.this.Request => Test.this.Response
val myFunction: (Request) => Response = doSomething
如果我将myFunction和functions的声明更改为:
val myFunction: (MyRequest) => MyResponse = doSomething
private val functions = scala.collection.mutable.Map[String, (MyRequest) => MyResponse](
"myFunction" -> myFunction
)
但这不是我想要的——我希望能够向映射中添加其他具有不同具体类型(都扩展了请求或响应)的函数。因此,我想声明map接受请求或响应的任何子类
你知道我做错了什么吗?你可以将
doSomething
的参数类型改为Request
,而不是MyRequest
,它会工作:
def doSomething(request: Request): MyResponse = {
null
}
为什么会这样?您不能将参数类型更具体的函数赋给参数类型不太具体的变量。如果doSomething
的参数类型为MyRequest
,并且在doSomething
的主体中,我们调用了一个只在MyRequest
上可用而在Request
上不可用的方法,如果有人使用不同的Request
实现调用myFunction,在下面的示例中会发生什么?我们会破坏安全装置的
val myFunction: (Request) => Response = doSomething
我们可以在Function1
trait上的参数化类型中看到这一点:
trait Function1[-T1, +R]
-T1
表示函数的参数是反变的,这意味着参数类型不太具体的函数被视为子类型(即Request=>Response
函数可以分配给类型为MyRequest=>Response
的变量)。+R
表示函数返回类型是协变的,这意味着具有更具体返回类型的函数
s可作为子类型(即请求=>MyResponse
可分配给类型为请求=>Response
的变量)