自动为类参数创建getter(以避免大小写类)?

Jus*_*s12 12 scala

在Scala,如果我们有

class Foo(bar:String)
Run Code Online (Sandbox Code Playgroud)

我们可以创建一个新对象但无法访问 bar

val foo = new Foo("Hello")
foo.bar // gives error
Run Code Online (Sandbox Code Playgroud)

但是,如果我们宣布Foo成为case class这个工程:

case class Foo(bar:String) 
val foo = Foo("hello")
foo.bar // works
Run Code Online (Sandbox Code Playgroud)

因为这个原因,我被迫将我的许多课程作为案例课程.否则,我必须编写样板代码来访问bar:

class Foo(bar:String) {
  val getbar = bar
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:

  1. 有没有办法在不使用案例类或样板代码的情况下"修复"这个问题?
  2. 在这种情况下使用案例类是一个好主意吗?(或者案例类的缺点是什么?)

我想第二个值得一个单独的问题.

om-*_*nom 18

只需在构造函数中使用val关键字即可公开访问:

class Foo(val bar:String) {

}
Run Code Online (Sandbox Code Playgroud)

至于你的问题:如果这是你需要的唯一功能,不要使用case类,只需写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
Run Code Online (Sandbox Code Playgroud)

即便如此:

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

对于案例类(感谢@JamesIry):

case class Bar(`public`: String, private val `private`: String)  
Run Code Online (Sandbox Code Playgroud)

  • 实际上,您可以编写案例类Foo(private val bar:String)来获取案例类中的私有字段 (2认同)

Rég*_*les 6

您可以使用BeanProperty批注自动生成类似Java的getter

import scala.reflect.BeanProperty
case class Foo(@BeanProperty bar:String) 
Run Code Online (Sandbox Code Playgroud)

现在Foo有一个返回bar值的getBar方法.

请注意,这只有在你有充分的理由使用类似java的getter时才有用(典型的原因是你需要你的类成为一个合适的java bean,以便使用期望java bean的java库并使用反射来访问bean的属性).

否则,只是bar直接访问该值,这是"scala方式".

http://www.scala-lang.org/api/current/index.html#scala.reflect.BeanProperty

  • 注意 - 它是 Scala 2.12 中的“import scala.beans.BeanProperty” (2认同)