2012-09-10 84 views
10

在Scala中,如果我們有爲類參數自動生成getter(以避免case類)?

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. 在這種情況下使用大小寫類是一個好主意嗎? (或案例類別的缺點是什麼?)

我想第二個值得一個單獨的問題。

回答

17

只需使用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 = [email protected] 

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` 
} 

對於case類(感謝@JamesIry):

case class Bar(`public`: String, private val `private`: String) 
+0

true'val'確實保存了1個字符。然而,知道案例班爲什麼不好,這將是一件好事。 – Jus12

+0

@ Jus12我根據你的問題做了一個編輯,總之 - 更靈活 –

+2

實際上,你可以編寫案例類Foo(private val bar:String)來獲得案例類中的私有字段 –

4

您可以使用註釋的BeanProperty自動生成的Java類的getter

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

現在美孚擁有getBar方法返回bar值。

請注意,如果您有充足的理由使用類java的getter(典型的原因是您需要您的類是一個正確的java bean,以便使用期望java bean的java庫並使用反射來訪問bean的屬性)。

否則,直接訪問bar值,這是「scala方式」。

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

+0

另外在你還可以這樣精確的情況下,首先命名「getBar」的值,但這違背了Scala慣例。 –

+0

請注意 - 這是 'import scala.beans.BeanProperty' in Scala 2.12 – Alex