Iterable#all&的行为是什么为什么Kotlin Char :: class.java!= char.javaClass [英] What's the behavior of Iterable#all & Why did 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
})
}
列表包含Char
或String
,但是此表达式中的 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 typechar
. - when declare as a nullable type
Char?
it is a Java wrapper typeCharacter
. when declare as a type argument
List<Char>
it is a Java wrapper typeCharacter
.
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 })
但是我想说的是,用法和声明之间是有区别的.
例如,参数类型it
是java.lang.Character
,但其javaClass
是char
.
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&的行为是什么为什么Kotlin Char :: class.java!= char.javaClass的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!