Что делает так, что scala.collection.mutable.Map.apply может быть LHS присваиваемого?

#scala

#scala

Вопрос:

Я не понимаю, почему это разрешено:

 scala> val mutableMap = new scala.collection.mutable.HashMap[String,Int]()
mutableMap: scala.collection.mutable.HashMap[String,Int] = Map()

scala> mutableMap("foo") = 1

scala> mutableMap("foo")
res1: Int = 1

scala> mutableMap("foo")  = 10

scala> mutableMap("foo")
res3: Int = 11
  

Я полагаю, что последнее ( = ) является расширением первого ( = ) — но я не понимаю, что делает это допустимым LHS в присваивании. Это особый случай в компиляторе, или есть какая-то черта или класс, который предоставляет эту функциональность?

Комментарии:

1. Посмотрите на update метод 😉

2. Я думаю, что это будет переведено компилятором во что-то вроде: mutableMap.update("foo", mutableMap.apply("foo") 10) .

Ответ №1:

Это особый случай, обрабатываемый компилятором. Это синтаксический сахар.

Языковая спецификация охватывает все это, хотя найти что-либо в этом документе может быть довольно сложно.


x(i) = e означает x.update(i, e)

Из раздела 6.15 («Присвоения»):

Присваивание f(args) = e функции application слева от = оператора интерпретируется как f.update(args, e) , то есть вызов update функции, определенной f .

Вот некоторые выражения присваивания и их эквивалентные расширения.

 x.f = e                x.f_=(e)
x.f() = e              x.f.update(e)
x.f(i) = e             x.f.update(i, e)
x.f(i, j) = e          x.f.update(i, j e)
  

Таким образом, mutableMap("foo") = 1 расширяется до mutableMap.update("foo", 1) .


l = r означает l = l r

Раздел 6.12.4 описывает, как = работает. Выражение l = r переосмысливается как l = l r (если l не имеет = метода, и в этом случае это типичная инфиксная запись для l. =(r) ).


Применяя оба правила, мы получаем эту последовательность расширений:

  • mutableMap("foo") = 10
  • mutableMap("foo") = mutableMap("foo") 10
  • mutableMap.update("foo", mutableMap("foo") 10)

Комментарии:

1. Есть ли также какая-либо информация о = и ее переводе с update ?

2. Раздел 6.12.4 описывает, как = работает. Если у вас есть l = r , либо l есть = метод, либо выражение переосмысливается как l = l r .

3. Ах, я не заметил, что это = было частью вопроса. Я расширю свой ответ.

4. Должно x.f_=e быть x.f_=(e) ?