我正在尝试定义一个实例具有String
和函数的类。在函数中使用String
参数。
class Tenant(val name: String, exclusion: Map[String, Int] => Boolean)
val rule1 = new Tenant(name = "Baker3",
(suggestedFloor: Map[String, Int]) => suggestedFloor(name) != topFloor)
val rule1 = new Tenant(name = "Cooper2",
(suggestedFloor: Map[String, Int]) => suggestedFloor(name) != groundFloor)
在最后一次使用名称时出现错误:not found: value name
。
我该怎么做?
答案 0 :(得分:2)
<强>问题:强>
您正试图在词汇上下文中引用名称name
,但它根本不可用:
val rule1 = new Tenant(name = "Cooper2",
(suggestedFloor: Map[String, Int]) => suggestedFloor(name) != groundFloor)
- name
在此上下文中未引用name
中定义的Tenant
,而是引用name
范围内的名称rule1
定义,当然它显然不存在。使用此代码,错误将消失,但当然这不是您想要的:
val name = ??? // this is the `name` that gets referenced by the lambda
val rule1 = new Tenant(name = "Cooper2",
(suggestedFloor: Map[String, Int]) => suggestedFloor(name) != groundFloor)
<强>解决方案:强>
要解决这个问题,不要在实例化时传入函数,而是使用方法覆盖:
abstract class Tenant(val name: String) {
def exclusion(suggestedFloor: Map[String, Int]): Boolean
}
val rule1 = new Tenant(name = "Baker3") {
def exclusion(suggestedFloor: Map[String, Int]) =
suggestedFloor(name) != topFloor
}
这将创建一个Tenant
的匿名子类,其中包含exclusion
的“自定义”定义;我想说,这也是Scala中惯用的风格。
或者,您可以使用稍微不同的语义并覆盖不是方法,而是覆盖包含函数的属性;当使用_
:
abstract class Tenant(val name: String) {
val exclusion: Map[String, Int] => Boolean
}
val rule1 = new Tenant(name = "Baker3") {
val exclusion = (_: Map[String, Int])(name) != topFloor
}
不幸的是,类型推理器并没有消除对Map[String, Int]
重新声明的需要,因为只有比我聪明的人才能详细说明。
答案 1 :(得分:0)
你需要讨论函数或类声明:
class Tenant(name: String)(exclusion: Map[String, Int] => Boolean = _(name) != topFloor)
现在创建一个实例:
scala> new Tenant("hello")()
res8: Tenant = Tenant@13c3c24f