Iterable#all&的行为是什么为什么Kotlin Char :: class.java!= char.javaClass [英] What's the behavior of Iterable#all & Why did Kotlin Char::class.java != char.javaClass

查看:108
本文介绍了Iterable#all&的行为是什么为什么Kotlin Char :: class.java!= char.javaClass的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用kotlin为例,例如:

I'm trying an example in kotlin, like:

fun test(){    
    val harfler = listOf("a","b",'c','d')
    println(harfler.all { 
           it.javaClass == String::class.java || it.javaClass == Char::class.java 
    })
}

列表包含CharString,但是此表达式中的 all 函数返回false,为什么返回false?

List contains Char or String but all function in this expression returns false,Why return false?

有人可以解释吗?

修改 为@JBNizet

Edit for @JBNizet

推荐答案

正如@JB Nizet已经告诉您如何分析问题.

As @JB Nizet has already told you how to analyze the problem.

根据映射类型,科特林Char将映射到Java Type上决定其声明.

According to the Mapped Types, The Kotlin Char will be mapped to Java Type decide on its declaration.

  • 当声明为不可空类型Char时,它是原始Java类型char.
  • 当声明为可空类型Char?时,它是Java包装器类型Character.
  • 当声明为 type自变量 List<Char>时,它是Java包装器类型Character.

  • when declare as a non-nullable type Char it is a primitive Java type char.
  • when declare as a nullable type Char? it is a Java wrapper type Character.
  • when declare as a type argument List<Char> it is a Java wrapper type Character.

val it = 'a'
//                v--- it should be `Any`
val array: Array<Any> = arrayOf('a')

//          v--- char
println(it.javaClass)

//             v--- print [java.lang.Character]  
println(array.map { it.javaClass })

但是我想说的是,用法声明之间是有区别的. 例如,参数类型itjava.lang.Character,但其javaClasschar.

But I want to say that there is a different between the usage and the declaration. For example, the parameter type it is a java.lang.Character, but its javaClass is char.

fun typeOf(it: Char?) = it?.javaClass

fun test() {
    //                                          v--- java.lang.Character
    println(::typeOf.javaMethod!!.parameterTypes[0])
    //       v--- but it return `char` rather than `java.lang.Character`
    println(typeOf('a'))
}

下面的示例进一步说明了不同之处,这就是为什么我在前面的示例中将数组类型声明为Array<Any>而不是Array<Char>的原因:

And the example below show the different as further, this is why I declare the array type to Array<Any> rather than Array<Char> in preceding example:

//                v--- uses `java.lang.Character` instead
val array: Array<Char> = arrayOf('a')

//                       v--- java.lang.Character
println(array.javaClass.componentType)
//             v--- [char]
println(array.map { it.javaClass })


为什么在Koltin中发生奇怪的行为?


Why did the strange behavior occurs in Koltin?

这是因为Kotlin Char和其他包装器类代表2个角色.一个是Java 原始类型 char,另一个是Java 包装器java.lang.Character.但是,Kotlin Char静态的,这意味着您无法在运行时更改其类型.并且在Kotlin中默认将Char映射到char.

This is because Kotlin Char and other wrapper classes represent 2 roles. one is a Java primitive type char, another is a Java wrapper class java.lang.Character. However, Kotlin Char is statically which means you can't change its type in runtime. and a Char should be mapped to a char by default in Kotlin.

如果您想每次获取包装器类型,则应改用KClass.javaObjectType,例如:

IF you want get the wrapper type every time, you should use KClass.javaObjectType instead, for example:

//                  v--- char 
println(Char::class.java)
//                  v--- java.lang.Character
println(Char::class.javaObjectType)


Iterable#all操作是短路操作,这意味着如果不满足任何第一个元素的要求,则会立即返回false.


The Iterable#all operation is a short-circuiting operation, which means if any first element didn't satisfied will return false immediately.

inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean {
    //   return `false` immediately the condition didn't satisfied
    //                        v                                            
    for (element in this) if (!predicate(element)) return false
    return true
}


在检查Kotlin类(如Char等)时.您应该使用Kotlin 类型检查机制,而不是使用传统的比较方法,它可以帮助您避免这种混乱.例如:


When checking a Kotlin class like as Char and others. you should use the Kotlin type checking mechanism rather than traditional comparing approach, it helps you avoid such a confusion. for example:

val anything: Array<Any> = arrayOf('a')
val chars: Array<Char> = arrayOf('a')

println(chars.all { it is Char }) // print true
println(anything.all { it is Char }) // print true

因此您的代码可以替换为类型检查如下:

So your code can replace with type checking as below:

fun test() {
    val harfler = listOf("a", "b", 'c', 'd')

    //                       v---------------v--- use type checking here 
    println(harfler.all { it is String || it is Char }) // print true
}

这篇关于Iterable#all&amp;的行为是什么为什么Kotlin Char :: class.java!= char.javaClass的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆