問題:
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]
再宣言の必要性は、私よりも賢い人だけが詳しく説明できる理由から、型推論によって排除されません。