Автоматически создавать геттеры для параметров класса (чтобы избежать классов классов)?
В 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
}
Итак, мои вопросы:
- Есть ли способ "исправить" это без использования классов классов или шаблонов?
- Использует ли классы case в этом контексте хорошую идею? (или каковы недостатки классов case?)
Я предполагаю, что второй заслуживает отдельного вопроса.
Ответы
Ответ 1
Просто используйте ключевое слово val в конструкторе, чтобы сделать его общедоступным:
class Foo(val bar:String) {
}
Что касается вашего вопроса: если это единственная функция, которая вам нужна, не используйте классы case, просто пишите с помощью 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)
Ответ 2
Вы можете использовать аннотацию BeanProperty для автоматического создания java-подобных геттеров
import scala.reflect.BeanProperty
case class Foo(@BeanProperty bar:String)
Теперь Foo имеет метод getBar, который возвращает значение bar
.
Обратите внимание, что это полезно только в том случае, если у вас есть веская причина использовать java-подобные геттеры (типичные причины, по которым вам нужен ваш класс, чтобы быть надлежащим java bean, чтобы работать с java-библиотеками, которые ожидают java beans и использовать отражение для доступа к свойствам bean).
В противном случае просто войдите в значение bar
напрямую, это "путь scala".
См. http://www.scala-lang.org/api/current/index.html#scala.reflect.BeanProperty