Помітка інфіксації Scala


12

Чи можна викликати метод, використовуючи позначення infix?

Наприклад, у Haskell я міг написати таку функцію:

x `isAFactorOf` y = x % y == 0

а потім використовувати його так:

if 2 `isAFactorOf` 10 ...

Що в деяких випадках дозволяє дуже читати код. Чи можливо щось подібне до цього в Scala? Я шукав "Scala infix notation", але цей термін, схоже, означає щось інше у Scala.

Відповіді:


15

Починаючи з версії 2.10, Scala представила неявні класи для вирішення саме цієї проблеми.

Це дозволить виконати неявну конверсію заданого типу в обгорнутий клас, який може містити власні методи та значення.

У вашому конкретному випадку ви використовуєте щось подібне:

implicit class RichInt(x: Int) {
  def isAFactorOf(y: Int) = x % y == 0
}

2.isAFactorOf(10)
// or, without dot-syntax
2 isAFactorOf 10

Зауважте, що при компіляції це в остаточному підсумку перетворить на наше неочищене значення в a RichInt(2). Ви можете обійти це, оголосивши ваш RichInt як підклас AnyVal:

implicit class RichInt(val x: Int) extends AnyVal { ... }

Це не спричинить бокс, але він є більш обмежувальним, ніж типовий неявний клас. Він може містити лише методи, а не значення або стан.


2
Вам, мабуть, слід згадати, що неявні класи не можуть бути верхнього рівня, тому неявний клас потрібно буде визначати локально.
Carcigenicate

3

По суті, у Scala ви не можете викликати функцію інфіксуючим способом, але ви можете визначити метод на тип, який лівий аргумент можна перетворити неявно. Отже, для вашого прикладу ви можете визначити клас, у якого є метод isAFactorOf (прийняття Int), і вказати, що Int можна неявно перетворити на екземпляр цього класу.

Якщо ви подивитесь на цю відповідь https://stackoverflow.com/a/3119671 на інше запитання, ви побачите синтаксис у Scala, який працює в рівній мірі.


Варто відзначити, що нові версії Scala мають конструкцію , явно для цього, що відповідь пов'язаний не адреса: implicit class RichInt(i: Int) { def square() = i * i }.
KChaloux
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.