with函数接收两个参数,第一参数可以是任何类型的对象,第二个参数是一个Lambda表达式
with函数会在Lambda表达式中提供第一个参数的上下文,并使用Lambda表达式的最后一行代码作为函数的返回值
示例代码
val res = with(obj) { //这里是obj对象的上下文 "value"//这里是with函数的返回值 }
with函数的作用.假如现在有个需求让吃完所有的水果并且将结果打印出来,代码可以这样写
fun main() { doSomething() } fun doSomething() { val list = listOf<String>("Apple", "Banana", "Pear") val sb = StringBuilder() sb.append("Start eating fruits.\n") for (fruits in list) { sb.append(fruits).append("\n") } sb.append("Ate all fruits.") val res = sb.toString() println(res) }
利用with函数可以这样写,可以看到在Lambda表达式中,都是StringBuilder的上下文,那么就不需要我们通过StringBuilder的实例调用append()方法了,而是直接使用append()方法即可.
fun withTest() { val list = listOf<String>("Apple", "Banana", "Pear") val res = with(StringBuilder()) { append("Start eating fruits.\n") for (fruits in list) { append(fruits) append("\n") } append("Ate all fruits.") toString()//最后一行就是函数的返回值 } println(res) }
fun runTest() { val list = listOf<String>("Apple", "Banana", "Pear") //将StringBuilder调出来,用来调用run函数 val res = StringBuilder().run { append("Start eating fruits.\n") for (fruits in list) { append(fruits) append("\n") } append("Ate all fruits.") toString() } println(res) }
fun applyTest() { val list = listOf<String>("Apple", "Banana", "Pear") val res = StringBuilder().apply { append("Start eating fruits.\n") for (fruits in list) { append(fruits) append("\n") } append("Ate all fruits.") } println(res.toString()) }
在kotlin当中要是想要定义一个工具类,会比较推荐单例类进行实现
object Util { fun doAction() { println("do something") } }
虽然单例类中的doAction()方法并不是静态放啊,但是我们还是可以直接使用Util.doAction()来进行调用
但是单例类的缺点是单例类中的方法都是类似静态方法这种调用方式,但是我们只需要让类中的一个方法变成静态的怎么办?
在companion object中定义的方法就可以类似于静态方法那样进行调用了
class Util { //非静态方法属性 fun doAction1() { } //拥有静态方法的属性 companion object { fun doAction2() { } } }
单例类和companion object都是在语法形式上模仿了静态方法,实际上不属于真正的静态方法
如果我们给单例类或者companion object中的方法加上@JvmStatic注解,那么kotlin编译器就会将这些方法编译成为真正的静态方法
如下
class Util { //非静态方法属性 fun doAction1() { } //拥有静态方法的属性 companion object { @JvmStatic fun doAction2() { } } }
@JvmStatic只能加在单例类或者companion object中的方法