13

Scalaでは、

class Foo(bar:String)

新しいオブジェクトを作成できますが、アクセスできませんbar

val foo = new Foo("Hello")
foo.bar // gives error

ただし、これが機能すると宣言Fooした場合case class

case class Foo(bar:String) 
val foo = Foo("hello")
foo.bar // works

このため、私は自分のクラスの多くをケースクラスとして作成することを余儀なくされています。それ以外の場合は、アクセスするための定型コードを作成する必要がありますbar

class Foo(bar:String) {
  val getbar = bar
}

だから私の質問は:

  1. ケースクラスや定型コードを使用せずにこれを「修正」する方法はありますか?
  2. このコンテキストでケースクラスを使用するのは良い考えですか?(またはケースクラスの欠点は何ですか?)

2番目のものは別の質問に値すると思います。

4

2 に答える 2

18

コンストラクターでvalキーワードを使用するだけで、パブリックにアクセスできるようになります。

class Foo(val bar:String) {

}

あなたの質問に関して:これがあなたが必要とする唯一の機能であるならば、ケースクラスを使わずに、ただ。で書いてvalください。

ただし、ケースクラスが適切でない理由を知っておくと便利です。

クラスの場合、デフォルトではすべての引数がパブリックですが、プレーンクラスの場合はすべてプライベートです。ただし、この動作を調整することはできます。

scala> class Foo(val bar:String, baz: String)
defined class Foo

scala> new Foo("public","private")
res0: Foo = Foo@31d5e2

scala> res0.bar
res1: String = public

scala> res0.baz
<console>:10: error: value baz is not a member of Foo
              res0.baz

そしてそのようにさえ:

class Foo(private[mypackage] val bar:String) {
  // will be visible only to things in `mypackage`
}

ケースクラスの場合(@JamesIryに感謝):

case class Bar(`public`: String, private val `private`: String)  
于 2012-09-10T15:32:48.740 に答える
9

BeanPropertyアノテーションを使用して、Javaのようなゲッターを自動的に生成できます

import scala.reflect.BeanProperty
case class Foo(@BeanProperty bar:String) 

これで、Fooには値を返すgetBarメソッドがありbarます。

ただし、これは、Javaのようなゲッターを使用する正当な理由がある場合にのみ役立つことに注意してください(一般的な理由は、Java Beanを期待するJavaライブラリを操作し、リフレクションを使用するために、クラスが適切なJavaBeanである必要があることです。 Beanのプロパティにアクセスします)。

それ以外の場合は、値に直接アクセスするだけですbar。これが「スカラウェイ」です。

http://www.scala-lang.org/api/current/index.html#scala.reflect.BeanPropertyを参照してください

于 2012-09-10T15:31:58.483 に答える