val var1: Any = "Carmelo Anthony"

I'm under the impression ::class.simpleName returns the variable type of an object
when I do the following:

val var1Type = var1::class.simpleName
print(var1Type)

我得到String分,而不是Any

但当我这么做的时候

val var2: String = var1

我得了Type mismatch: inferred type is Any but String was expected

推荐答案

  • In Kotlin, the ::class operator exists in 2 forms:
  • 在您的例子中,var1的运行时tytpe为String,但静态类型为Any.
  • 但是,与大多数静态类型语言一样,Kotlin的类型系统不允许隐式缩小转换(即,给定一个类型为String的变量var2,您不能从另一个静态类型为Any的变量(var3)分配给var2,因为var3 could的运行时类型与String完全不兼容,例如InputStream对象.

In context:

fun main() {

    val var1: Any = "Carmelo Anthony"
    val var1Type = var1::class.simpleName
    println("var1's type: " + var1Type) // <-- This will print the *runtime type* of `var1` (String), not its static type (which is `Any`, *not* `String`).

    /*
    val var2: String = var1 // <-- Fails beause `var1` is `Any`, and `Any` is "wider" than `String`, and narrowing conversions always considered unsafe in languages like Kotlin, Java, etc.
    */
    val var2Unsafe: String  = var1 as  String; // <-- Doing this is unsafe because it will throw if `var1` is not a String.
    val var2Safe  : String? = var1 as? String; // <-- Doing this is safe because it `var2Safe` will be null if `var1` is not a String.
    
    println(var2Unsafe)
    println(var2Safe)
}

如果您熟悉其他语言,那么下面是一个不完整的等效操作及其语法表:

Kotlin Java JavaScript C# C++
Get static type TypeName::class TypeName.class ConstructorName typeof(TypeName) typeid(TypeName)
Get runtime type variableName::class variableName.getClass() typeof variableName (intrinsics) variableName.constructor (objects) variableName.GetType() typeid(variableName)
Get type from name (string) Class.forName( typeName ).kotlin Class.forName( typeName ) eval( typeName ) (never do this)
Statically-defined runtime type check variableName is TypeName variableName instanceof TypeName typeof variableName === 'typeName' (intrinsics) or variableName instanceof ConstructorName (objects) variableName is TypeName
Runtime dynamic type check otherKClass.isInstance( variableName ) or otherKType.isSubtypeOf() otherClass.isAssignableFrom( variableName.getClass() ) otherType.IsAssignableFrom( variableName.GetType() )
Unsafe narrowing (aka downcast) val n: NarrowType = widerVar as NarrowType; NarrowType n = (NarrowType)widerVar; variableName as TypeName (TypeScript only) NarrowType n = (NarrowType)widerVar;
Safe narrowing (downcast or null) val n: NarrowType? = widerVar as? NarrowType; NarrowType n? = widerVar as NarrowType; dynamic_cast<NarrowType>( widerVar )
Conditional narrowing in scope variableName is TypeName func(x: unknown): x is TypeName guard functions (TypeScript only) widerVar is TypeName n

Kotlin相关问答推荐

外键是主键的一部分,但不是索引的一部分.房间

在Kotlin 有更好的结合方式?

Kotlin:有限的并行性并不是限制并行性

Kotlin中一个接口的实现问题

kotlin 模式匹配如何像 scala 一样工作

如何在 Jetpack Compose 中启动和停止动画

gradle 如何 Select 以-jvm结尾的库?

Jetpack Compose - 单击 LazyColumn 的项目时应用程序崩溃

is return inside function definition 也是 kotlin 中的表达式

有没有办法重用 Job 实例?

为什么 android studio 不为所有安全参数生成代码?

将 Kotlin 类属性设置器作为函数引用

Kotlin 静态函数:伴生对象,@JvmStatic @JvmField

将 Firebase 数据快照反序列化为 Kotlin 数据类

如何解决:将Java类转换为Kotlin后出现error: cannot find symbol class ...?

如何在Android Studio 4.1中默认启用Kotlin Android扩展

Kotlin-将UTC转换为当地时间

在android java类中使用Kotlin扩展

lateinit 的 isInitialized 属性在伴随对象中不起作用

Kotlin中的嵌套let块