Найти в Дзене
Kotlin King

Kotlin. Зачем нужно ключевое слово operator?

Познакомимся с ключевым словом operator в Kotlin
Познакомимся с ключевым словом operator в Kotlin

Привет!

Сегодня мы поговорим зачем нужно ключевое слово operator в Kotlin.

Если коротко, то оно служит, чтобы расширить стандартные операции языка (такие как +, - , * и другие) на ваши собственные типы данных.

По умолчанию Котлин умеет складывать, умножать, вычитать, делить, инкрементировать (да много чего еще) со числовыми типами данных, умеет соединять строки, добавлять значения в массивы и тд. Это известно и понятно, но мы бы хотели научить Котлин работать так же с наши классами. Вот тут нам и поможет ключевое слово operator.

Давайте рассмотрим на примере как работать с этой фичей. Будет очень красиво, обещаю :)

👉 Допустим есть класс Point, который представляет собой точку на плоскости. Он хранит в себе x и y значения. Вот он кстати:

class Point(val x: Int, val y: Int)

Очень хочется чтобы могли взять две точки и сложить или вычесть, чтобы получить новую координату, но сделать это красиво, вот так, например:

val x1 = Point(1,1)

val x2 = Point(2,2)

val result = x1 + x2

Котлин не умеет работать с нашим классом Point по умолчанию, и знак «плюс» тут не сработает, но давайте его научим этому. Напишем функцию plus в классе Point:

class Point(val x: Int, val y: Int){

operator fun plus (p : Point) : Point {

return Point(this.x + p.x, this.y + p.y)

}

}

Теперь Котлин перестанет подчеркивать знак + красным, и легко выполнит

val result = x1 + x2

Так, стоп! что именно мы написали? Мы написали функцию перегрузки стандартного оператора +, поэтому функция называется plus. Есть целая таблица операций, которым сопоставлено название соответствующих операций. Вот небольшая её часть:

-2

👉 Пользуясь таблицей мы можем теперь перегрузить оператор «минус», например. А ключевое слово operator просто сообщает Котлину, что мы хотим перегрузить оператор +, а не просто написать какую-то свою функцию с таким именем.

Вот и пример с «минусом» подоспел:

class Point(val x: Int, val y: Int) {

operator fun plus(p: Point): Point {

return Point(this.x + p.x, this.y + p.y)

}

operator fun minus(p: Point): Point {

return Point(this.x - p.x, this.y - p.y)

}

}

fun main() {

val x1 = Point(1, 1)

val x2 = Point(2, 2)

val result = x1 + x2

val result2 = result - Point(3, 3)

println(result2.toString())

}

👉 Вот, думаю теперь всё понятно, и вопросов тут быть не должно. Мы могли бы еще x++ подобным образом сделать, но давайте лучше сделаем нечто похожее с коллекциями. Предположим у нас есть класс Shelf, это книжная полка, которая содержит Books в списке List и мы бы хотели добавлять книги туда, брать от туда, а так же смотреть что там есть. Так что, давайте сразу перегрузим 3 функции в классе Shelf:

class Book(val name : String)

class Shelf(val books : MutableList<Book> = mutableListOf()) {

operator fun get(id: Int) = books[id]

operator fun set(id: Int, product: Book) {

books.add(id, product)

}

operator fun contains(book: Book) = book in books

}

Работать с книгами на полке мы можем теперь так:

fun main() {

val shelf = Shelf()

val book = Book("Война и мир")

shelf[0] = book //set

println(shelf[0].name) //get

println(shelf.contains(book)) //contains

}

Что приятнее и короче чем писать

shelf.books[0] = book

println(shelf.books[0].name)

println(shelf.books.contains(book))

👉 Хорошо, с этим разобрались. Полную таблицу поддерживаемых операций я приведу ниже, глядя на которую, вы сможете сами выбрать куда ещё добавить немного сахарку в своем коде =) Поэкспериментируйте с другими операциями самостоятельно.

-3

-4
-5

На этом пока всё. Ждите следующих выпусков. Поставьте лайк если понравилось, а так же не забывайте подписываться на канал. Увидимся!