Для полноты следует сказать, что ваше «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 (например, присвоение элементов массива и выборка).Это также удобно для заводских методов на объектах-компаньонах.Помимо этого, следует соблюдать осторожность, так как это одна из тех вещей, которая может легко сделать ваш код слишком компактным, чтобы его можно было действительно прочитать.