zoukankan      html  css  js  c++  java
  • [Kotlin参考]一、总览-(8)1.1新增功能

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(let_us_code)
    ➤博主域名:https://www.zengqiang.org
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/12152307.html
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    Kotlin 1.1的新功能

    目录

    的JavaScript

    从Kotlin 1.1开始,JavaScript目标不再被视为实验性的。支持所有语言功能,并且有许多新工具可与前端开发环境集成。请参阅下面的更详细的更改列表。

    协程(实验性)

    在科特林1.1的主要新功能是协同程序,使支持的asyncawaityield和类似的编程模式。Kotlin设计的关键特征是协程执行的实现是库的一部分,而不是语言的一部分,因此您不必受限于任何特定的编程范例或并发库。

    协程实际上是一种轻量级的线程,可以将其挂起并在以后恢复。协程可以通过挂起函数来支持:调用该函数可以潜在地挂起协程,而要启动新的协程,我们通常使用匿名的挂起函数(即,挂起lambda)。

    让我们看一下asyncawait,它是在外部库kotlinx.coroutines中实现的

     
     
     
     
     
    //在后台线程池中运行代码
    有趣的 asyncOverlay()=  异步CommonPool){
        //启动两个异步操作
        val  original  =  asyncLoadImage“ original”
        val  overlay  =  asyncLoadImage“ overlay”
        //然后将叠加层应用于两个结果
        applyOverlay的await(),覆盖的await())
    }
    //在UI上下文中启动新的协程
    启动UI){
        //等待异步叠加完成
        val  image  =  asyncOverlay()。等待()
        //然后在用户界面中显示
        showImageimage
    }
     
     
     

    在这里,async { ... }启动一个协程,并且当我们使用时await(),协程的执行会在执行正在等待的操作的同时暂停执行,并在等待操作完成后继续执行(可能在其他线程上)。

    标准库使用协程来支持带有函数的延迟生成的序列在这样的序列中,返回序列元素的代码块在检索每个元素之后将被挂起,并在请求下一个元素时恢复。这是一个例子:yieldyieldAll

     
     
     
     
     
     
     
    val  seq  =  buildSequence {
        i  in  1 .. 5){
            //产生i的平方
            屈服i  *  i
        }
        //产生一个范围
        yieldAll26 .. 28
    }
    //打印序列
    的printlnSEQtoList())
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    运行上面的代码以查看结果。随时对其进行编辑,然后再次运行!

    有关更多信息,请参阅协程文档教程

    请注意,协程目前被视为实验性功能,这意味着Kotlin团队在最终的1.1版本之后不再致力于支持该功能的向后兼容性。

    其他语言功能

    类型别名

    类型别名使您可以为现有类型定义备用名称。这对于诸如集合之类的通用类型以及函数类型最有用。这是一个例子:

     
     
     
     
     
     
     
    typealias  OscarWinners  =  地图< StringString >
    有趣的 countLaLaLandoscarWinnersOscarWinners=
            oscarWinners { 价值包含“ La La Land”)}
    //请注意,类型名称(初始名称和类型别名)可以互换:
    有趣的 checkLaLaLandIsTheBestMovieoscarWinnersMap < StringString >=
            oscarWinners [ “最佳图片” ] ==  “ La La Land”
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    有关更多详细信息,请参见文档KEEP

    绑定可调用参考

    现在,您可以使用::运算符获取指向特定对象实例的方法或属性的成员引用以前只能用lambda表示。这是一个例子:

     
     
     
     
     
     
     
    val  numberRegex  =  “ \ d +”toRegex()
    val  number  =  listOf“ abc”“ 123”“ 456”)。过滤器numberRegex :: 匹配项
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    阅读文档KEEP以获取更多详细信息。

    密封和数据类

    Kotlin 1.1消除了Kotlin 1.0中对密封和数据类的某些限制。现在,您可以在同一文件中的顶级上定义顶级密封类的子类,而不仅仅是密封类的嵌套类。数据类现在可以扩展其他类。这可以用来清晰地定义表达式类的层次结构:

     
     
     
     
     
     
     
    密封  Expr
    数据  Constval  numberDouble):Expr()
    数据  Sumval  e1Exprval  e2Expr):Expr()
    对象 NotANumberExpr()
    fun  evalexprExpr):Double  =  whenexpr){
         Const-  >  expr
         萨姆 - >  的evalexpr中E1+  的evalexpr中E2
        NotANumber-  >  DoubleN
    }
    val  e  =  evalSumConst1.0),Const2.0)))
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    阅读文档或 密封类和 数据类 KEEP以获取更多详细信息。

    在lambdas中进行销毁

    现在,您可以使用解构声明语法来解压缩传递给lambda的参数。这是一个例子:

     
     
     
     
     
     
     
    val  map  =  mapOf1  表示 “ 1”2  表示 “ 2”
    //之前
    的println地图mapValues { 条目 - >
      valkeyvalue=  条目
      “ $ key-> $ value!”
    })
    //现在
    的println地图mapValues {(- >  “$键- > $值!” })
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    阅读文档KEEP以获取更多详细信息。

    下划线表示未使用的参数

    对于具有多个参数的lambda,您可以使用_字符替换不使用的参数名称:

     
     
     
     
     
     
     
    地图forEach { _ ->  println“ $ value!”)}
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    这也适用于销毁声明

     
     
     
     
     
     
     
    val_status=  getResult()
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    阅读KEEP了解更多详细信息。

    数字文字下划线

    与Java 8一样,Kotlin现在允许在数字文字中使用下划线来分隔数字组:

     
     
     
     
     
     
     
    VAL  oneMillion  =  1_000_000
    val  hexBytes  =  0xFF_EC_DE_5E
    val  字节 =  0b11010010_01101001_10010100_10010010
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    阅读KEEP了解更多详细信息。

    属性的较短语法

    对于将getter定义为表达式主体的属性,现在可以省略属性类型:

     
     
     
     
     
     
     
        数据  VAL  字符串VAL  年龄诠释){
        val  isAdult  get()=  age  > =  20  //属性类型推断为“布尔”
    }
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    内联属性访问器

    现在,inline如果属性没有后备字段,则可以使用修饰符标记属性访问器。此类访问器的编译方式与内联函数相同

     
     
     
     
     
     
     
    public  val  < T >  列表< T >lastIndexInt
        内联 get()=  this大小 -  1
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    您也可以将整个属性标记为inline-,然后将修饰符应用于两个访问器。

    阅读文档KEEP以获取更多详细信息。

    本地委托属性

    现在,您可以将委托属性语法与局部变量一起使用。一种可能的用途是定义一个惰性计算的局部变量:

     
     
     
     
     
     
     
    val  answer  by  lazy {
        println“正在计算答案...”
        42
    }
    ifneedAnswer()){                      //返回随机值
        println“答案是$ answer。”//答案是在此时计算的
    }
    其他 {
        println“有时没有答案就是答案...”
    }
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    阅读KEEP了解更多详细信息。

    拦截委派的属性绑定

    对于委托的属性,现在可以使用provideDelegate运算符截取委托到属性的绑定 例如,如果我们想在绑定之前检查属性名称,我们可以这样写:

     
     
     
     
     
     
     ResourceLoader < T >idResourceID < T >){
        操作者 的乐趣 provideDelegatethisRefMyUIKProperty <*> ):ReadOnlyProperty < MyUIŤ > {
            checkPropertythisRef道具
            ... //属性创建
        }
        私人 乐趣 checkPropertythisRefMyUI名称String){...}
    }
    fun  < T >  bindResourceidResourceID < T >):ResourceLoader < T > {...}
     MyUI {
        VAL  图像 通过 bindResource的ResourceIDimage_id
        VAL  文本  bindResource资源IDtext_id
    }
     
     
     

    provideDelegate在创建MyUI实例期间,将为每个属性调用方法,并且可以立即执行必要的验证。

    阅读文档以获取更多详细信息。

    通用枚举值访问

    现在可以以通用方式枚举枚举类的值。

     
     
     
     
     
     
     
    枚举  RGB { 绿 }
    直列 乐趣 < 物化 Ť枚举< Ť >>  printAllValues(){
        打印enumValues < Ť >()。joinToString { 名称 })
    }
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    DSL中隐式接收器的范围控制

    @DslMarker注释允许限制在DSL背景下使用的接收器从外部范围。考虑规范的HTML构建器示例

     
     
     
     
     
     {
        tr {
            td { +  “文字” }
        }
    }
     
     
     

    在Kotlin 1.0中,传递给lambda的代码可以td访问三个隐式接收器:一个传递给table,to tr 和to td这使您可以调用在上下文中没有意义的方法,例如在tr内部调用td,从而将<tr>标记放入<td>

    在Kotlin 1.1中,您可以对此进行限制,以便td 在传递给的lambda内只有在隐式接收器上定义的方法才可用td为此,您可以定义带有@DslMarker元注释的注释并将其应用于标签类的基类。

    阅读文档KEEP以获取更多详细信息。

    rem 算子

    mod现在不推荐使用运算符,rem而是使用它。看到这个问题的动机。

    标准库

    字符串到数字的转换

    String类上有很多新扩展,可以将其转换为数字,而不会在无效数字上抛出异常: String.toIntOrNull(): Int?String.toDoubleOrNull(): Double?等等。

     
     
     
     
     
    val  port  =  系统getenv“ PORT”toIntOrNull()80
     
     
     

    也整数转换功能,如Int.toString()String.toInt()String.toIntOrNull(),各得到了与过载radix参数,该参数允许指定转换的(2到36)的基极。

    在各个()

    onEach是用于集合和序列的小型但有用的扩展函数,它允许在一系列操作中对集合/序列的每个元素执行某些操作,可能会有副作用。在可迭代对象上,它的行为类似于,forEach但还会进一步返回可迭代实例。然后在序列上返回一个包装序列,该序列在元素被迭代时会延迟应用给定的动作。

     
     
     
     
     
    inputDir步行()
    过滤 { isFile  &&  名字结尾于“ .txt”)}
    onEach { println“将$ it移至$ outputDir”)}
    的forEach { moveFile文件outputDirtoRelativeStringinputDir)))}
     
     
     

    Also(),takeIf()和takeUnless()

    这是三个适用于任何接收器的通用扩展功能。

    also就像apply:它接收接收者,对其执行一些操作,然后返回该接收者。区别在于,在apply接收器内部的块中可以将其用作this,而在接收器内部块中可以将其also用作it(并且如果需要,可以给它起另一个名字)。当您不想this从外部范围阴影时,这很方便

     
     
     
     
     
     
     
    好玩的 复制()=  ()。 {
        内容 =  这个内容
    }
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    takeIf就像filter单个值一样。它检查接收方是否满足谓词,并返回接收方(如果满足)或null不满足。与Elvis运算符和早期返回结合使用,可以编写以下结构:

     
     
     
     
     
    VAL  outDirFile  =  文件outputDir路径)。takeIf { 存在()} 吗?返回 
    //使用现有的outDirFile做一些事情
     
     
     
     
     
     
     
     
     
     
    val  index  =  输入indexOf关键字)。takeIf { it  > =  0 } 吗?错误“未找到关键字”
    //在找到输入关键词的情况下对关键词进行索引
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    takeUnless与相同takeIf,但它采用倒置谓词。如果不符合谓词,null返回接收者否则返回。因此,可以使用takeUnless以下示例重写以上示例之一

     
     
     
     
     
    val  index  =  输入indexOf关键字)。takeUnless { it  <  0 } 吗?错误“未找到关键字”
     
     
     

    当您有一个可调用的引用而不是lambda时,使用起来也很方便:

     
     
     
     
     
     
     
    val  结果 =  字符串takeUnless字符串 :: isEmpty
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    groupingBy()

    该API可用于按键对集合进行分组,并同时折叠每个组。例如,它可以用于计算以每个字母开头的单词数:

     
     
     
     
     
     
     
    val  频率 =  单词通过 { it第一()}。eachCount()
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    Map.toMap()和Map.toMutableMap()

    这些功能可用于轻松复制地图:

     
     
     
     
     
    class  ImmutablePropertyBagmapMap < StringAny >){
        私有 val  mapCopy  =  maptoMap()
    }
     
     
     

    Map.minus(key)

    运算符plus提供了一种将键值对添加到生成新图的只读图的方法,但是没有相反的简单方法:从图中删除键,您必须减少使用喜欢Map.filter()喜欢的直截了当的方式Map.filterKeys()现在,操作员minus填补了这一空白。有4种重载可用:用于删除单个键,键集合,键序列和键数组。

     
     
     
     
     
     
     
    val  map  =  mapOf“ key”  to  42
    val  emptyMap  =  地图 -  “键”
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    minOf()和maxOf()

    这些函数可用于查找两个或三个给定值中的最小和最大值,其中值是原始数字或Comparable对象。Comparator如果您要比较本身不具有可比性的对象,则每个函数还有一个额外的实例需要重载

     
     
     
     
     
     
     
    val  list1  =  listOf“ a”“ b”
    val  list2  =  listOf“ x”“ y”“ z”
    VAL  minSize属性 =  minOflist1的大小列表2大小
    VAL  longestList  =  maxOflist1的list2中compareBy { 大小 })
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    类数组列表实例化函数

    Array构造函数类似,现在有一些函数可以通过调用lambda 来创建ListMutableList实例并初始化每个元素:

     
     
     
     
     
     
     
    val  squares  =  List10){ 索引 ->  索引 *  索引 }
    val  mutable  =  MutableList10){ 0 }
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    Map.getValue()

    该扩展名on Map返回与给定键相对应的现有值,或引发异常,并提及未找到哪个键。如果使用生成地图withDefault,则此函数将返回默认值,而不是引发异常。

     
     
     
     
     
     
     
    val  map  =  mapOf“ key”  to  42
    //返回不可为空的Int值42
    val  Int  =  mapgetValue“ key”
    val  mapWithDefault  =  mapwithDefault { k-  >  k长度 }
    //返回4
    val  value2  =  mapWithDefaultgetValue“ key2”
    // map.getValue(“ anotherKey”)// <-这将引发NoSuchElementException
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    抽象收藏

    在实现Kotlin集合类时,可以将这些抽象类用作基类。为了实现只读集合有AbstractCollectionAbstractListAbstractSetAbstractMap,以及可变集合有AbstractMutableCollectionAbstractMutableListAbstractMutableSetAbstractMutableMap在JVM上,这些抽象可变集合从JDK的抽象集合继承了大多数功能。

    数组操作功能

    现在,标准库为数组的逐个元素操作提供了一组函数:比较(contentEqualscontentDeepEquals),哈希码计算(contentHashCodecontentDeepHashCode)以及转换为字符串(contentToStringcontentDeepToString)。JVM(在其中用作相应功能的别名java.util.Arrays)和JS(在Kotlin标准库中提供实现)都支持它们。

     
     
     
     
     
     
     
    val  array  =  arrayOf“ a”“ b”“ c”
    的println阵列的toString())   // JVM实现:类型和散列乱码
    的println阵列contentToString())   //很好地格式化为列表
     
     
     
    目标平台:JVM 。运行在科特林v 61年3月1日

    JVM后端

    Java 8字节码支持

    Kotlin现在可以选择生成Java 8字节码(-jvm-target 1.8命令行选项或Ant / Maven / Gradle中的相应选项)。目前,这不会改变字节码的语义(特别是,接口和lambda中的默认方法的生成与Kotlin 1.0中的完全相同),但是我们计划稍后再使用它。

    Java 8标准库支持

    现在,标准库有单独的版本,支持Java 7和8中添加的新JDK API。如果需要访问新API,请使用kotlin-stdlib-jre7kotlin-stdlib-jre8Maven构件,而不是standard kotlin-stdlib这些工件是kotlin-stdlib它们之上的微小扩展,它们作为传递依赖项将其带入您的项目。

    字节码中的参数名称

    Kotlin现在支持在字节码中存储参数名称。可以使用-java-parameters命令行选项启用

    恒定内联

    现在,编译器将const val属性值内联到使用它们的位置。

    可变的关闭变量

    用于捕获lambda中的可变闭包变量的box类不再具有volatile字段。此更改可以提高性能,但在某些罕见的使用情况下可能导致新的竞争状况。如果您受此影响,则需要提供自己的同步来访问变量。

    javax.script支持

    Kotlin现在与javax.script API(JSR-223)集成该API允许在运行时评估代码段:

     
     
     
     
     
    val  engine  =  ScriptEngineManager()。getEngineByExtension“ kts”
    引擎评估“ val x = 3”
    的println发动机EVAL“X + 2” ))   //打印出5
     
     
     

    有关 使用API​​的大型示例项目,请参见此处

    全反射

    为了准备对Java 9的支持kotlin-reflect.jar库中的扩展功能和属性已移至程序包kotlin.reflect.full旧软件包(kotlin.reflect)中的名称已弃用,并将在Kotlin 1.2中删除。请注意,核心反射接口(例如KClass)是Kotlin标准库的一部分,不是kotlin-reflect,并且不受此举动的影响。

    JavaScript后端

    统一标准库

    现在,可以将Kotlin标准库的很大一部分用于编译为JavaScript的代码。具体地,键类,如集合(ArrayListHashMap等),异常(IllegalArgumentException等)和其他一些(StringBuilderComparator)现在将在限定的kotlin包。在JVM上,名称是相应JDK类的类型别名,在JS上,这些类在Kotlin标准库中实现。

    更好的代码生成

    现在,JavaScript后端可以生成更多可静态检查的代码,这比缩小器,优化器,棉绒等JS代码处理工具更友好。

    external修改

    如果您需要以类型安全的方式从Kotlin访问用JavaScript实现的类,则可以使用external修饰符编写Kotlin声明(在Kotlin 1.0中,使用了@native注释。)与JVM目标不同,JS允许使用带有类和属性的外部修饰符。例如,以下是声明DOM Node类的方法:

     
     
     
     
     
    外部  Node {
        val  firstChild节点
        fun  appendChildchildNode):节点
        fun  removeChildchildNode):节点
        //等
    }
     
     
     

    改进的进口处理

    现在,您可以描述应从JavaScript模块更精确地导入的声明。如果@JsModule("<module-name>")在外部声明上添加注释,则在编译期间会将其正确导入到模块系统(CommonJS或AMD)。例如,对于CommonJS,声明将通过require(...)函数导入此外,如果要将声明作为模块或全局JavaScript对象导入,则可以使用@JsNonModule注释。

    例如,以下是将JQuery导入Kotlin模块的方法:

     
     
     
     
     
    外部 接口 JQuery {
        有趣的 切换durationInt  =  defineExternally):jQuery
        有趣的 点击handler:(Event->  Unit):JQuery
    }
    @JsModule“ jquery”
    @JsNonModule
    @JsName“ $”
    外部 有趣的 jQuery选择器字符串):JQuery
     
     
     

    在这种情况下,JQuery将作为名为的模块导入jquery另外,它可以用作$对象,具体取决于Kotlin编译器配置使用的模块系统。

    您可以像下面这样在应用程序中使用这些声明:

     
     
     
     
     
    fun  mainargsArray < String >){
        jQuery“ .toggle-button”)。点击 {
            jQuery“ .toggle-panel”)。拨动300
        }
    }
     
     
  • 相关阅读:
    #研发解决方案#研发协作平台CloudEngine
    人生做出的选择越多,友谊的小船翻得越快?
    告诉别人你是谁:边界的那些事儿
    如何从零开始搭建一个技术平台?
    Windows10 自动配置切换IP地址
    Human disease database
    R语言install.packages("jpeg")报错
    RStudio中,出现中文乱码问题的解决方案(修改文件编码)
    How do I run Adobe Flash on Chrome?
    RGB颜色查询对照表
  • 原文地址:https://www.cnblogs.com/strengthen/p/12152307.html
Copyright © 2011-2022 走看看