Превосходный в Котлине - PullRequest
       2

Превосходный в Котлине

0 голосов
/ 15 октября 2018

CS реализует kotlin.CharSequence.Суть здесь в следующем:

class CS  (val sequence: CharSequence = "") : CharSequence {
... override get/length in interface CharSequence 
    override fun equals(other: Any?): Boolean =
            (this === other) || ((other is String) && this.sequence.equals(other))
}

Объект компилятора для CS("hello") == "hello" как: Оператор '==' не может быть применен к 'CS' и 'String' .У него нет проблем с CS("hello") == "hello" as Any или CS("hello").equals("hello"), которые оба работают.

Что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

Я не уверен в причине этой ошибки, но она может быть связана с более глубокой проблемой с вашим подходом…

В Kotlin (и Java) метод equals() имеет довольно узкуюСпецификация.Одно условие состоит в том, что он должен быть симметричным: всякий раз, когда a и b не равны нулю, a.equals(b) всегда должен давать тот же результат, что и b.equals(a).

Но ваша реализация не проходит этот тест, потому что CS("abc").equals("abc") возвращает true, а "abc".equals(CS("ABC")) равно false.Это потому, что ваш класс знает о CharSequence s, таких как String, но String не знает о вашем классе.

Нет простого способа обойти это.В целом, гораздо безопаснее разрешить экземплярам класса соответствовать только экземплярам этого класса.Если вы контролируете оба класса, то есть способы обойти это, но они довольно тонкие и запутанные.(Возможно, лучшим объяснением является Martin Odersky et al. .)

Так что большинство реализаций equals() имеют тенденцию работать по следующим направлениям:

override fun equals(other: Any?)
    = (other is ThisClass)
    && field1 == other.field1
    && field2 == other.field2
    // ...

Как ясказал, я не знаю, почему компилятор Kotlin жалуется в вашем случае.Может быть, он обнаружил что-то из этой проблемы, или это может быть что-то не связанное.Но я не думаю, что вы сможете исправить свою программу таким образом, чтобы проверки на равенство делали то, что вы хотите, поэтому, возможно, лучше принять это как подсказку, чтобы попробовать немного другой подход!

0 голосов
/ 15 октября 2018

Оператор == в Kotlin не работает, если типы с обеих сторон операции известны и отличаются друг от друга.
Например:

3 == "Hello"
true == 5.0
// and so on

Даст компиляциюошибка, потому что компилятор делает вывод, что операнды являются экземплярами разных классов и поэтому не могут быть равными.

Единственное исключение, если одна сторона оператора является подклассом другой:

open class A
class B: A()
class C: A()

val c = C()
val b = B()
val a = A()

c == b
c == a // good
a == b // also good

В этом случае c == b выдаст ошибку компиляции, а две другие операции - нет.

Именно поэтому, когда вы приводите одну сторону операции к Any, она больше не выдает ошибку, так как всеэто подтип Any.

0 голосов
/ 15 октября 2018

@ Майкл упомянул в комментарии, что этот оператор действителен, поэтому вы можете перейти к ответу ниже:

Я думаю, ошибка, которую вы получаете, может быть связана с тем, что у Kotlin есть проблемы с выводом вашеготип данных.Вы предоставляете тип Any в качестве параметра для метода equals(...) и сравниваете его с вашим классом (this).Возможно, попытайтесь привести тип так:

this == (other as String)

или

this == (other as CharSequence)

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

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