Пытаюсь выяснить, как перегрузить скобки в классе.
У меня есть этот код:
class App(values: Map[String,String])
{
// do stuff
}
Я хотел бы получить доступ к значениям Map следующим образом:
var a = new App(Map("1" -> "2"))
a("1") // same as a.values("1")
Возможно ли это?
Вам необходимо определить метод apply
.
class App(values: Map[String,String]) {
def apply(x:String) = values(x)
// ...
}
Для полноты следует сказать, что ваше «apply» может принимать несколько значений, и что «update» работает как двойное значение «apply», позволяя «перегружать скобки» в левой части присваиваний
Class PairMap[A, B, C]{
val contents: mutable.Map[(A,B), C] = new mutable.Map[(A, B), C]();
def apply(a:A, b:B):C = contents.get((a, b))
def update(a:A, b:B, c:C):Unit = contents.put((a, b), c)
}
val foo = new PairMap[String, Int, Int]()
foo("bar", 42) = 6
println(foo("bar", 42)) // prints 6
Основная ценность всего этого заключается в том, что это не позволяет людям предлагать дополнительный синтаксис для вещей, которые должны были быть в специальном регистре в более ранних языках семейства C (например, назначение и выборка элементов массива). Это также удобно для фабричных методов сопутствующих объектов. Помимо этого, следует проявлять осторожность, поскольку это одна из тех вещей, которые могут легко сделать ваш код слишком компактным, чтобы его можно было прочитать.
Как уже заметили другие, вы хотите перегрузить apply
:
class App(values: Map[String,String]) {
def apply(s: String) = values(s)
}
Пока вы в этом разбираетесь, вы можете перегрузить и сопутствующий объект apply:
object App {
def apply(m: Map[String,String]) = new App(m)
}
Тогда вы сможете:
scala> App(Map("1" -> "2")) // Didn't need to call new!
res0: App = App@5c66b06b
scala> res0("1")
res1: String = 2
Хотя будет ли это преимуществом или путаницей, зависит от того, что вы пытаетесь сделать.
Я думаю, что это работает с использованием apply: Как работает магия метода apply () в Scala?