我们从2017年年中开始在OkCupid使用Kotli188bet金ê188博金宝电子体育频道53;搏官网n,我们整个Android团队都喜欢它。如果您一直在开发或研究Kotlin,您就会意识到它比Java更有趣。

我们知道很多好处—没有分号、可空类型、扩展方法等等。但是,我认为在语言中有一些隐藏的小秘密,当然,你可以在文档中找到,但是在介绍性的Kotlin文章中并不总是会提到。所以我们要给你介绍几个!

我们可以将隐藏的宝石分为两类,而不是将其作为一个包含Kotlin技巧和技巧的抓取包:

  1. 包含的方法
  2. 语言特点

包含的方法

本节将讨论在标准库中内置的方法,这些方法在Java中不存在,在Kotlin中您可能不知道。

我认为值得复习的一门课是字符串班级。在我们的职业生涯中,这是一门必须学习的课程,因此了解科特林的弦乐课的力量是很重要的。

首先,让我们沿着内存通道走一走,回忆一下我们作为Java开发人员的日子。在Java中,如果我们想使用字符串来完成内置Java字符串类无法完成的任务,我们应该导入阿帕奇公地StringUtils类的库。它会给我们一些有用的方法:

StringUtils.IsBlank文件(“”);//真StringUtils.SubstringBefore子字符串("亚当·麦克尼尔“,”);//“亚当StringUtils.SubstringAfter子字符串("亚当·麦克尼尔“,”);//“麦克尼尔”StringUtils.LeftPad文件("1", 2); // " 1" 猪排。剁(“abc”);/“ab”

然而,感谢JetBrains出色的开发人员,所有这些方法都内置于:

val blank=“”.isBlank()//同时:CharSequence?。isNullOrBlank val first=“亚当·麦克尼尔“.substringBefore(‘.’)//”Adam“val last=”亚当·麦克尼尔“.substringAfter('.')//”McNeilly“val with spaces=”1“.padStart(2)/”1“val endSpaces=”1“.padEnd(3,'0')/”100“val dropStart=”Adam“.drop(2)/”am“val dropEnd=”Adam“.dropLast(2)/”Ad”

在这里您会注意到,我们摆脱了Java风格的将静态方法与格式结合使用的方式帮助类.剂量测定(输入),并使用更为Kotlin惯用的方法对格式为的对象本身调用方法输入.剂量测定(). 他们实际上是一回事,科特林扩展函数基本上只是静态方法的语法糖。

Kotlin strings类提供了更多功能,只是为了突出几个:

“A\nB\nC”.lines()//[A,B,C]”一二三“.substringAfterLast('.')//”三个“”一二三“.substringBeforeLast('..')/”一。二“”zipWithNext()//[(A,B),(B,C),(C,D)]val nullableString:字符串?=空nullableString.orEmpty()//返回“”

最后两种方法,zipWithNext()空()实际上也适用于收藏!空()是我个人在Kotlin中最喜欢的方法之一-与elvis运算符等替代方法相比,能够获取可为null的字符串或可为null的集合并将其转换为空值(不是null)是一个巨大的时间节省:val nonNullString=空字符串?: "". 注意:您也可以在可为空的集合上使用它来返回空列表!

对称性

全面使用Kotlin的一大好处是方法之间的对称性。当然,我可能经常希望子字符串在字符之前,但是在字符之后呢?也许我想填充字符串的开头,但我也可以填充字符串的结尾。语言开发人员考虑到了这一点,并确保我们尽可能地对称:

substringBefore()substringAfter()isEmpty()isNotEmpty()padStart()padEnd()drop()dropLast()trimStart()trimEnd()

注:作为reddit用户Kodablah解释,并不总是完美对称的。你可能会发现一些例外。

收藏

在这一点上,在Kotlin中有很多我们以前作为Java开发人员所做不到的事情可以做。

类似于apachecommons,但是没有外部依赖,我们有一个收藏Java中的类,它有一堆静态方法来执行我们想要的操作:

集合.排序(myList);集合.max(myList);集合.min(myList);收藏.洗牌(myList);收款.反向(myList);集合.swap(myList,1,2);

与字符串一样,我们不想担心这种Java静态方法类型方法,因此您可以用漂亮的Kotlin惯用方法来完成以上所有操作:

myList.sort类型() myList.max文件() myList.min() myList.shuffle文件() myList.反向() myList.swap文件(1, 2)

迭代集合

Kotlin提供了许多非常强大的方法来迭代集合。我不仅仅指for循环,我指的是有目的的迭代。一个常见的例子是对满足某个条件的项目进行顺序搜索。在Java中,我们习惯于这样写:

public Person getAdam(Listpeople){对于(Person:people){如果(个人.getName().equals(“Adam”){return person;}}返回null;}

这是我们在Java中所能做到的最好的方法,并不可怕,但幸好在Kotlin中,我们实际上有一个单行方法来实现这一点,它只接受我们想要检查的条件:

fun getAdam(人物:List):人物?{返回第一人{ it.名称==“亚当”}}

这个firstOrNull公司方法将返回集合中满足所提供条件的第一项。如果你看看源代码,您将看到它与我们的Java for循环做了完全相同的事情。因此,我们保持了完全相同的性能,但获得了所有这些巨大的可读性。

这里的选项非常广泛,还支持我们在stdlib周围看到的对称性:

我的列表过滤器{ } myList.filterNot公司{ } myList.filterIsInstance筛选器() myList.filterNotNull{ } 我的第一个{}//同时:indexOfFirst{}myList.firstOrNull公司{ } 我的最后一个{}//同时:indexOfLast{}myList.lastOrNull公司{ } myList.单{ } myList.singleOrNull公司{ } 我的名单。有吗{ } 我的列表。无{ } 我的列表。全部{ } myList.分区{}//Pair,列表>

我把partition作为一个有趣的小宝石放进去了——它是一个接受条件的方法,返回一个满足条件的项目列表和一个不满足条件的项目列表收藏文档,你一定会找到一个独特的方法,你从来没有见过,但做一些你以前需要的。

语言特点

本节将讨论在Kotlin语言中可以做的事情,这些事情我们在Java中做不到,以及如何利用它们来提高生产率。

高阶函数

好吧,按照你的标准,这可能是或不是一块“隐藏的宝石”,但这取决于它们是如何呈现给你的。根据文档,“Lambda表达式和匿名函数都是‘函数文本’,也就是说,函数没有声明,而是作为表达式立即传递。”然而,当我从Java开发人员的角度看下面的代码时,很难理解发生了什么。我被告知lambda是一个函数进入另一个函数,但我在这里没有看到任何我要传递的偏执:

数值=myNumberList.filter公司{it%2==0}

真正发生的是这件事的好处关键点:

在Kotlin中,有一个约定,即如果函数的最后一个参数接受函数,则作为相应参数传递的lambda表达式可以放在括号外。

如果我们查看filter的源代码,我们可以看到它接受一个函数,该函数接受类型T(列表中的任何项目类型),并输出一个布尔值:

public inline fun数组.filter(谓词:(T)->布尔):List{return filterTo(ArrayList(),谓词)}val evenNumbers=myNumberList.filter公司{it%2==0}

所以,让我们看一下这个示例用例。让我们考虑编写一个方法,检查用户是否授予了对存储的写入权限,如果授予了权限,我们希望执行一些回调:

WritePermission的私人乐趣(回调:()->Unit){activity?。让{activity->rxperimissions(activity).request(Manifest.permission.WRITE\外部\存储).subscribe{granted->if(granted){callback()}}

因为我们的函数只有一个参数,这是另一个函数,我们可以用一个非常酷的lambda调用它:

withWritePermission{launchGallery()}

我也看到过一些例子,展示了如何在Android上检查API版本:188博金宝电子体育频道

支持LLIPOP{doSomething()}

不过,这里需要注意一点。在谷歌IO,杰克·沃顿解释为什么他们不在androidktx库中包含这样的方法。原因是,我们没有任何方法来包含上面的else块。如果188博金宝电子体育频道Android未来版本的功能发生了变化,那么你需要考虑三个阶段:棒棒糖之前、棒棒糖之后,以及这个新的变化之后,你将无法用上面的步骤来实现这一点。

所以在使用最后一个参数技巧时要小心,不要把自己编码到角落里。

分解声明

我们要讨论的最后一个强大的Kotlin特性是解构,这肯定是得不到足够信用的。

考虑一个用例,其中有一个表示3D坐标的整数数组。按照我们以前的Java方式,我们必须引用每个单独的索引才能得到我们想要的:

val coordinates=arrayOf(5,10,15)val x=coordinates[0]val y=coordinates[1]val z=coordinates[2]println(“x coordinate:$x”)println(“y coordinate:$y”)println(“z coordinate:$z”)

不过,由于解构,我们可以在Kotlin的一行中完成所有这些。您只需定义所需的值,并将每个变量名用括号括起来,用逗号分隔:

val坐标=数组(5,10,15)val(x,y,z)=坐标println(“x坐标:$x”)println(“y坐标:$y”)println(“z坐标:$z”)

这方面的一个很酷的用例是对数据类进行分解,以便可以从函数返回两个项:

数据类Result(val Result:Int,val status:status)fun函数(…):Result{返回结果(Result,status)}val(Result,status)=函数(…)

您还可以分解地图条目,这使得遍历地图变得更好。您不再需要访问entry.key键条目.值,您只需在循环内部进行分解:

val actionsMap:Map=hashMapOf(…)for((key,Action)in actionsMap){//。。。}

在引擎盖下工作的方式是添加一个组件n()函数的值。这对我们来说是自动发生的数据类,但如果要在自己的类中执行此操作,则需要编写自己的运算符函数:

类Person(val name:String,val age:Int){operator fun component1():String{return name}operator fun component2():Int{return age}}val Person=Person(“Adam”,25)val(name,age)=Person

你可以有很多组件n()函数,但如果您尝试分解的项多于您的组件函数,则会出现错误。

结论

这篇文章有三个要点:

  1. 在Kotlin中,string和Collections类比您想象的要强大得多。花点时间阅读他们的文档,以及其他常见的类,你一定会对你不知道存在的方法感到惊讶。
  2. 拥有函数类型真的很棒,而且你可以用它们做一些非常奇妙的事情。这里面还有更多文件. 只是要意识到一些限制,使它难以前进。
  3. 解构是科特林鲜为人知的秘密之一。你可以节省自己很多时间!

科特林充满了隐藏的秘密,甚至超越了这里所讨论的一切。你有最喜欢的宝石吗?向我伸出援手推特! 想和我一起去爱神丘比特吗?188bet金宝搏官网我们在招聘!