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

很抱歉我问了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 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
的变量)