kotlin, какой из них лучше, используя «есть» или «как?», - PullRequest
0 голосов
/ 24 апреля 2020

две функции test1 и test2, одна использует «is» для проверки типа, а другая использует «as?», Кажется test2 с «as?» имеет меньше кода, но действительно ли он лучше, чем тот, который использует "is" для проверки?

Есть ли сравнение для использования "is" против "as?", что является предложением для общего использования этих два?

class Message(val int: Int, val msg:String)
class Test {
    fun test1(objList: List<Any?>) {
        for (i in objList.size - 1 downTo 0) {
            val item = objList.get(i)
            if (item is Message) {
                println(item)
            }
        }
    }

    fun test2(objList: List<Any?>) {
        for (i in objList.size - 1 downTo 0) {
            (objList.get(i) as? Message)?.let {item ->
                println(item)
            }
        }
    }
}

Ответы [ 3 ]

2 голосов
/ 24 апреля 2020

Так что, если вы посмотрите на байт-код JVM обоих:

// JVM bytecode of test1
   L5
    LINENUMBER 8 L5
    ALOAD 3
    INSTANCEOF com/example/artifact/Message
    IFEQ L6

// JVM bytecode of test2
   L4
    LINENUMBER 16 L4
    ALOAD 0
    ILOAD 1
    INVOKEINTERFACE java/util/List.get (I)Ljava/lang/Object; (itf)
    DUP
    INSTANCEOF com/example/artifact/Message
    IFNE L5
    POP
    ACONST_NULL
   L5
    CHECKCAST com/example/artifact/Message
    DUP
    IFNULL L6
    ASTORE 3

Вы можете ясно увидеть, что test1 проверяет только тип и выполняет умный привод результата, тогда как test2 однако сначала проверяется, принадлежит ли экземпляр этому типу, а затем возвращает значение null или явно «сводит» его к этому типу.

Итак, в этом наблюдении я предложу вам использовать оператор is как есть. более оптимизированы для этих задач. Если вам не нравятся фигурные скобки, вы можете опустить их, например, python, или поместить println в ту же строку, что и в случае условий.

Это более оптимизированный код, если вы как:

fun test1(objList: List<Any>) {
    for (item in objList.asReversed()) {
        if (item is Message) println(item)
    }
}

fun test2(objList: List<Any>) {
    for (item in objList.asReversed()) {
        (item as? Message)?.let { println(it) }
    }
}
1 голос
/ 25 апреля 2020

is - проверка типа. as - это приведение типа.

отличается:

is возвращение логическое, true или false

as возвращение этого типа

you используйте is, если вам нужен только ответ да или нет

пример

if (user is Login) вы просто хотите получить ответ да или нет, верно? и затем вы делаете что-то еще

, которое вы используете as, когда хотите попробовать привести к этому типу

пример

(user as? Admin).let{print(it.name.toString())} 

этот, который вы хотите проверить, если этот пользователь is Admin or not, если да, вы хотите использовать это пользовательское значение, чтобы напечатать что-то вроде имени

, поэтому для условия используйте is

для приведения. Используйте as

fun test(objList: List<Any>) = objList.asReversed().forEach {
    when(it){ is Message -> println(it)}
}
1 голос
/ 25 апреля 2020

Версия as? может иметь на одну строку кода меньше, но действительно ли она действительно содержит меньше кода в целом? Возможно, вы избавились от:

val item = objList.get(i)

Но вы заменили его на:

(objList.get(i) as? Message)?.let {item ->

В этом случае я бы сказал, что для версии as? требуется чуть больше время для понимания, чем версия is, которая более проста. Я также сомневаюсь, что между двумя подходами есть существенная разница в производительности. В общем, всегда предпочитайте более читаемый код более производительному коду, если только вы не профилировали реальную проблему производительности в своем приложении. Есть ли проблема с производительностью или нет, сильно зависит от контекста вашего приложения. И помните, преждевременная оптимизация является root всего зла .

Если вы действительно хотите меньше кода, тогда подумайте об использовании следующего:

fun test(objList: List<Any>) = objList.asReversed().forEach {
    if (it is Message) println(it)
}

Используются:

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