Может ли неявный класс также быть Dynami c? - PullRequest
4 голосов
/ 21 января 2020

Я попытался неявным образом добавить функциональность Dynami c в класс, выполнив следующее:

case class C(map: Map[String, String])

implicit class Enhancer(c: C) extends Dynamic {
    def selectDynamic(str: String) = c.map.getOrElse(str, "")
}

val c = C(Map("a" -> "A"))

И это не скомпилирует

val up = c.a

Но явный вызов будет:

val up = Enhancer(c).a

Почему это?

Ответы [ 2 ]

2 голосов
/ 21 января 2020

Правило в спецификации :

Выбор на Dynami c

Если не применяется ни одно из предыдущих преобразований, а e является Префикс выбора e.x, а тип e соответствует классу scala.Dynamic, затем выбор перезаписывается в соответствии с правилами для выбора элемента dynamici c.

Соответствие не включает «может быть неявно преобразовано»; так что нет, вы не можете добавить Dynamic неявно. Вы можете предложить его для будущей версии Scala, но я был бы удивлен, если бы она была принята.

2 голосов
/ 21 января 2020

Да, это скомпилируется ...

val up = Enhancer(c).a  //up: String = A

... но тогда, то же самое будет ...

val up = Enhancer(c).wxyz  //up: String = ""

Если класс C не имеет член a, а класс Enhancer не имеет члена a, компилятор не будет проверять, поддерживается ли a динамически, потому что все поддерживается динамически.

Если я проектировал язык / компилятор, и мне приходилось выбирать между разрешением a.anything (потому что Enhancer означает Dynamic) или разрешением только членов с естественной поддержкой (игнорируя динамику), я думаю, что ' д go с последним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...