前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kotlin 1.2 有哪些新特性

Kotlin 1.2 有哪些新特性

作者头像
aqi00
发布2019-05-26 17:25:38
8540
发布2019-05-26 17:25:38
举报
文章被收录于专栏:老欧说安卓老欧说安卓

原文链接是《What's New in Kotlin 1.2》,下面的译文节选了“其它的语言特性”部分(“Other Language Features”)

通过注解声明数组变量

从Kotlin1.2开始,允许通过注解声明数组参数这种语法,从而取代了arrayOf函数的数组声明方式。比如下面这样:

代码语言:javascript
复制
@CacheConfig(cacheNames = ["books", "default"])
public class BookRepositoryImpl {
    // ...
}

可见新的数组参数声明语法依赖于注解方式。

关键字lateinit支持全局变量和局部变量

现在lateinit修饰符能够用于全局变量和局部变量了,也就是说,二者都允许延迟初始化。例如,当lambda表达式在构造一个对象时,允许将延迟初始化属性作为构造参数传过去。比如下面这样:

代码语言:javascript
复制
fun test() {
    lateinit var x: Component
    
    val injector = inject(
        ...,
        componentProvider = { x },
        ...
    )
    
    x = injector.createComponent()
}

检查一个延迟初始化属性是否初始化

通过访问属性的isInitialized字段,开发者现在可以检查一个延迟初始化属性是否已经初始化了。比如下面这样:

代码语言:javascript
复制
class Foo {
    lateinit var lateinitVar: String
    
    fun initializationLogic() {
        //sampleStart
        println("isInitialized before assignment: " + this::lateinitVar.isInitialized)
        lateinitVar = "value"
        println("isInitialized after assignment: " + this::lateinitVar.isInitialized)    
        //sampleEnd
    }
}

fun main(args: Array<String>) {
	Foo().initializationLogic()
}

内联函数支持函数的默认参数

内联函数现在允许给它们的函数参数填写默认参数了,比如下面这样:

代码语言:javascript
复制
//sampleStart,第一行的it.toString()就是默认参数值
inline fun <E> Iterable<E>.strings(transform: (E) -> String = { it.toString() }) = 
    map { transform(it) }

val defaultStrings = listOf(1, 2, 3).strings()
val customStrings = listOf(1, 2, 3).strings { "($it)" } //是外部传入的参数值
//sampleEnd

fun main(args: Array<String>) {
    println("defaultStrings = $defaultStrings")
    println("customStrings = $customStrings")
}

根据强制转换的信息,能够推断出变量类型

Kotlin编译器现在支持通过强制转换的信息,来推断出变量类型。如果你在调用一个返回“T”的泛型方法时,试图将它的返回值“T”转换为特定类型如“Foo”,编译器现在知道这个方法调用中的“T”其实是“Foo”类型。 这个对安卓开发者而言尤其重要,因为自从API26(Android7.0)开始,findViewById变成了泛型方法,然后编译器也会正确分析该方法的调用返回值。比如下面这样:

代码语言:javascript
复制
val button = findViewById(R.id.button) as Button

智能转换的改进

当一个变量为某个安全表达式(如校验非空)所赋值时,智能转换也同样运用于这个安全调用的接收者。比如下面这样:

代码语言:javascript
复制
fun countFirst(s: Any): Int {
    //sampleStart
    val firstChar = (s as? CharSequence)?.firstOrNull()
    if (firstChar != null)
       return s.count { it == firstChar } // 输入参数s被智能转换为CharSequence类型
    
    val firstItem = (s as? Iterable<*>)?.firstOrNull()
    if (firstItem != null)
       return s.count { it == firstItem } // 输入参数s被智能转换为Iterable<*>类型
    //sampleEnd
    
    return -1
}

fun main(args: Array<String>) {
    val string = "abacaba"
    val countInString = countFirst(string)
    println("called on \"$string\": $countInString")
    
    val list = listOf(1, 2, 3, 1, 2)
    val countInList = countFirst(list)
    println("called on $list: $countInList")
}

另外,Lamba表达式同样支持对局部变量进行智能转换,前提是该局部变量只在Lamba表达式之前修改过。比如下面这样:

代码语言:javascript
复制
fun main(args: Array<String>) {
    val flag = args.size == 0
    
    //sampleStart
    var x: String? = null
    if (flag) x = "Yahoo!"

    run {
        if (x != null) {
            println(x.length) // x被智能转换为String类型
        }
    }
    //sampleEnd
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年12月15日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 通过注解声明数组变量
  • 关键字lateinit支持全局变量和局部变量
  • 检查一个延迟初始化属性是否初始化
  • 内联函数支持函数的默认参数
  • 根据强制转换的信息,能够推断出变量类型
  • 智能转换的改进
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档