Инфиксная нотация

Последнее обновление: 30.05.2021

Инфиксная нотация представляет помещение оператора или функции перед операндами или аргументами. Для определения инфиксной функции вначале ее определения указывается ключевое слово infix:

infix fun название_функции(параметр: тип_параметра): тип_возвращаемого_значения{
	// действия функции
}

Инфиксная функция должна принимать только один параметр. При этом параметр не должен иметь значение по умолчанию и не должен представлять неопределенный набор значений.

Есть два способа определения инфиксной функции: либо внутри класса, либо как функции расширения.

Определим вначале внутри класса:

fun main() {

    val acc = Account(1000)
    acc put 150
	// равноценно вызову
	acc.put(150)
    acc.printSum()  // 1300
}
class Account(var sum: Int) {

    infix fun put(amount: Int){
        sum = sum + amount
    }
    fun printSum() = println(sum)
}

Здесь определен класс Account - класс банковского счета, который через конструктор принимает начальную сумму на счете. С помощью инфиксной функции put() определяем добавление на счет суммы, переданной через параметр функции.

Вызов функции выглядит следующим образом:

acc put 150

Первый параметр (здесь переменная acc) представляет объект, который вызывает функцию. А второй параметр - данные, которые непосредственно будут передаваться инфиксной функции через ее параметр. То есть данный вызов фактически аналогичен вызову:

acc.put(150)

Также инфиксная функция может определяться как функция расширения. Например, перепишем выше использованную функцию put() в виде функции расширения:

fun main() {

    val acc = Account(1000)
    acc put 150
    acc.put(150)
    acc.printSum()  // 1300
}
infix fun Account.put(amount: Int){
    this.sum = this.sum + amount
}
class Account(sum: Int) {
    fun printSum() = println(sum)
}

Стоит отметить, что функция расширения в отличие от функции внутри класса имеет доступ только тем свойствам, которые являются публичными.

Однако использование функций расширений позволяет добавить инфиксные функции к уже существующим типам. Например, определим инфиксную функцию для подсчета частоты символа в строке:

fun main() {

    val hello = "hello world"
    val lCount = hello wordCount 'l'
    val oCount = hello wordCount 'o'
    println(lCount)   // 3
    println(oCount)   // 2
}

infix fun String.wordCount(c: Char) : Int{
    var count = 0
    for(n in this){
        if(n == c) count++
    }
    return count
}

Здесь функция wordCount проходит по всем символам строки и подсчитывает, сколько раз встречается символ, передаваемый через параметр функции. Результат возвращается функцией. Затем мы можем применить инфиксную нотацию:

val lCount = hello wordCount 'l'

Поскольку функция возвращает результат типа Int, то мы можем получить этот результат в переменную.

Помощь сайту
WebMoney
  • P378451176208
  • Z280152397659
ЮMoney/Яндекс-Деньги
  • 410011174743222
PayPal
  • metanit22@mail.ru
Перевод на карту
  • Номер карты: 4048415020898850