在Kotlin中没有方法这个概念,转而存在的是函数的概念。
函数的声明
我们声明一个函数,使用fun关键字来修饰函数。
fun print(){
print("this is message");
}
fun print(str:String){
print("this is message $str");
}
fun print1(str:String = "hello"){
print("this is message $str");
}
fun printMessage() = print("this is kotlin");
fun printMsg():String = "this is kotlin";
我们可以看到这里我写了五种函数的书写方式。
第一种,是我们常用的方式,小括号里面没有参数,我们可以直接输出print信息。
第二种,里面是有一个参数str,我们在使用的时候可以传入一个参数,之后用print打印出这个参数值。
第三种,kotlin可以在参数中设置一个默认值,例如这里我将str设置了一个默认值"hello",当在使用这个函数print1的时候没有传入str这个参数,那么输出的时候将采用默认值来输出。结果打印this is message hello。这是kotlin中特有的语法。
第四种,如果函数中只有一条语句,那么我们可以直接使用"="来将这一条语句直接赋值给这个printMessage()函数。
第五种,同理第四种情况,如果函数有返回值并且也只有一条语句,那么我们也同样可以直接赋值操作。
函数的嵌套
我们来看下面这段代码
fun function(){
var str:String = "hello";
fun getFunction(){
var msg:String = "world";
var account:Int = 100;
print("$str $msg");
if (account >= 100){
account--;
}
getFunction();
}
}
可以看到在function这个函数中嵌套了另外一个函数getFunction(),并且在getFunction()中使用到了外部函数Function的变量str。这个有点像Java中内部类的概念。在Kotlin中允许函数内再嵌套另外一个函数,并且内部的函数可以调用外部函数声明的变量,并且函数自身还可以调用自身。这种写法一般用于某些情况下触发递归的方法,或者是不希望被外部函数访问到的情况。因为作为内部函数是不会被外部函数所访问到的。
扩展函数
扩展函数数是指在一个类上增加一种新的行为,甚至我们没有这个类代码的访问权限。这是一个在缺少有用函数的类上扩展的方法,Kotlin能够为我们做到那些令人关注的事情,而这些Java做不到。简单来说,Kotlin扩展函数允许我们在不改变已有类的情况下,为类添加新的函数。
fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){
Toast.makeText(this, message, duration).show()
}
看到在这里我们写了一个扩展函数toast;这个函数基于Activity这个类中进行的扩展,参数有两个,一个为需要显示的内容文字,另一个为显示的时长。
当我们在调用这个函数的时候可以直接调用
override fun onCreate(savedInstanceState: Bundle?) {
super<BaseActivity>.onCreate(savedInstanceState)
toast("This is onCreate!!")
toast("Hello world!", Toast.LENGTH_LONG)
}
我们可以在任何地方(例如在一个工具类文件中)声明这个函数,然后在我们的Activity中将它作为普通方法来直接使用。
有一点值得注意:扩展函数并不是真正地修改了原来的类,它的这些作用效果是以静态导入的方式来实现的。扩展函数可以被声明在任何文件中,因此有个通用的方式是把一系列有关的函数放在一个新建的文件里,就像我们刚才所说的工具类当中。
例如我们在使用图片的时候也可以用扩展函数来处理
fun ImageView.loadImage(context: Context, path: String, placeholder: Int = R.mipmap.ic_launcher, useCache: Boolean =false) {
var options = getOptions(placeholder, useCache)
Glide.with(context).load(path).apply(options).into(this)
}
看到我们在常用的Glide图片库时候,可以通过扩展库来处理,并且指定默认的控件id、图片地址、是否使用缓存等等一系列操作。这么用起来是不是特别舒服呢?
高阶函数
高阶函数是指,函数的参数又是一个函数,所以称之为高阶函数。比如 lock() 就是一个很好的例子,它接收一个 lock 对象和一个函数,运行函数并释放 lock;
fun <T> lock(lock: Lock, body: () -> T ) : T {
lock.lock()
try {
return body()
}
finally {
lock.unlock()
}
}
现在解释一下上面的代码吧:body 有一个函数类型 () -> T,把它设想为没有参数并返回 T 类型的函数。它引发了内部的 try 函数块,并被 lock 保护,结果是通过 lock() 函数返回的。 如果我们想调用 lock() ,函数,我们可以传给它另一个函数做参数
fun toBeSynchroized() = sharedResource.operation()
val result = lock(lock, ::toBeSynchroized)
其实最方便的办法是传递一个字面函数(通常是 lambda 表达式):
val result = lock(lock, {
sharedResource.operation() })
如果觉得我的文章能够帮助到你,也欢迎关注我的微信公众号「晨雨细曲」,有新技术和知识会推送在这上面。
网友评论