0

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)

name: の最後の使用でエラーが発生しますnot found: value name

どうやってやるの?

4

2 に答える 2

2

問題:

name単に利用できない字句コンテキストで名前を参照しようとしています:

val rule1 = new Tenant(name = "Cooper2",
  (suggestedFloor: Map[String, Int]) => suggestedFloor(name) != groundFloor)

nameこのコンテキストでは、 は 内で定義された を参照するのではnameなく、定義のスコープ内のTenant名前を参照します。もちろん、それは明らかに存在しません。このコードでは、エラーは消えますが、もちろんこれはあなたが望むものではありません:namerule1

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

于 2014-06-26T10:18:40.293 に答える
0

関数またはクラス宣言をカリー化する必要があります。

class Tenant(name: String)(exclusion: Map[String, Int] => Boolean = _(name) != topFloor)

インスタンスを作成します。

scala> new Tenant("hello")()
res8: Tenant = Tenant@13c3c24f
于 2014-06-26T08:40:18.513 に答える