- Kotlin编程实战:创建优雅、富于表现力和高性能的JVM与Android应用程序
- (美)文卡特·苏布拉马尼亚姆
- 1062字
- 2025-02-27 12:54:51
6.4 显式类型转换
仅在不可能进行智能转换的情况下使用显式转换——即编译器不能确定类型时。例如,如果一个var变量在检查和使用之间发生变化,那么Kotlin不能保证它的类型。在这种情况下,它不会应用智能转换,而我们必须为转换承担起责任。
Kotlin提供了两个运算符来执行显式转换:as和as?。让我们创建一个示例来说明如何使用这两种方法。
假设我们有一个函数,它返回不同类型的消息,比如下面这个:

现在假设我们想通过调用上面的函数来接收消息,并打印关于它的一些详细信息,但前提是结果是String类型。编写这类代码的一种方法是将调用fetchMessage()的结果存储在一个临时变量中。然后我们可以使用is来检查类型,如果它是String类型,那么我们可以使用智能转换来从该临时变量中获取我们需要的详细信息。
这可以正常工作。这是防御性编码,因此这是一个谨慎的解决方案。但有时,我们都试图将代码行数减少到不健康的程度,并且在此过程中可能会在代码中引入意外的行为。如果我们屈服于这种冲动,我们可能会想用as来编写这样的代码:

使用as进行转换就像把你所有的钱都投到彩票中——结果不会是令人愉快的。如果对象的类型与预期的不同,那么结果会是一个运行时异常。不好玩。

为了避免这种可能性,我们可以后退一步,使用is运算符,但更安全的替代方法as?也可以在这个特定的例子中工作。
as运算符会导致一个与运算符右侧指定的引用类型相同的引用,如下例所示:

另一方面,as?会导致一个可空的引用类型,如下所示:

然而,如果转换失败,as运算符就会失灵,而安全转换运算符as?将在失败时将引用赋值为null。
我们不使用as运算符,而是切换到使用更安全的方法as?。下面是从前面的例子变化而来的一行代码:

由于安全转换运算符在转换失败时将引用赋值为null,因此我们在必要时使用Elvis运算符来提供length的替代方法。
这是修改后的输出:

安全转换运算符as?总比不安全的as好。以下是一些好的建议:
□尽可能多地使用智能转换。
□只有在智能转换不是一个选项时才使用安全转换。
□如果你想看到应用程序崩溃,那么使用不安全的转换。
Kotlin对使代码类型安全的支持并不仅限于简单类型。为了使使用泛型类型的代码也变得安全,该语言做了一些额外的工作。我们经常在代码中使用泛型类型,了解到Kotlin 提供的泛型参数类型的灵活性不仅有助于我们创建更好的代码,更重要的是,理解使用这些特性的代码。
一般来说,处理泛型并不容易,而且当我们混合使用协变和逆变等术语时,它会令人沮丧。下面是该语言的一些高级功能,值得努力学习,但要慢慢理解这些概念。先散个步,再喝一杯含咖啡因的饮料,回来后,准备好边阅读边练习代码——这将帮助你更容易地理解这个高级主题。