Как избавиться от лишних приведений к реализованному интерфейсу?

2
задан User1291 14 March 2019 в 13:45
поделиться

2 ответа

Есть ли конкретная причина, по которой вам нужно использовать средство сравнения beSameInstanceAs?

Вы можете сделать что-то вроде:

val suits = CardSuit.values() as Array<out ICardSuite>

suits.forEach {
    when (it.name) {
        "HEART" -> it shouldBe CardSuit.HEART
        "SPADE" -> it shouldBe CardSuit.SPADE
   }
}

Однако, если вы действительно хотите использовать beSameInstanceAs , вы можете:

suits.forEach {
    when(it.name) {
       "HEART" -> it shouldBeSameInstanceAs CardSuit.HEART
       "SPADE" -> it shouldBeSameInstanceAs CardSuit.SPADE
    }
}

Я не получаю никаких жалоб от компилятора здесь

0
ответ дан Kerooker 14 March 2019 в 13:45
поделиться

beTheSameInstanceAs(CardSuit.HEART) возвращает Matcher<CardSuit>, поэтому оно не может совпадать с произвольным ICardSuit. Это имеет смысл (хотя Matcher может быть против -варианта, здесь вам понадобится ковариация). Но вы можете:

  1. Звонить явно beTheSameInstanceAs<ICardSuit>(CardSuit.HEART).

  2. Создайте вспомогательную функцию

    inline fun <T1, reified T2 : T1> Matcher<T2>.widen() = object : Matcher<T1>() {
        override fun test(value: T1) = 
            if (value is T2) 
                this.test(value) 
            else 
                Result(false, "$value is not a ${T2::class.name}", "$value is a ${T2::class.name}")
    }
    

    и вызовите

    it should beTheSameInstanceAs(CardSuit.HEART).widen()
    

    (я думаю, здесь должен работать вывод типов).

  3. Поскольку beTheSameInstanceAs(x) действительно может соответствовать чему угодно, объявите эквивалентную функцию, которая возвращает Matcher<Any>:

    fun beTheSameInstanceAsAny(x: Any) = beTheSameInstanceAs(x)
    
    // usage
    "HEART" -> it should beTheSameInstanceAsAny(CardSuit.HEART)
    
0
ответ дан Alexey Romanov 14 March 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: