kotlin学习之函数(二)

目录


这一节主要介绍顶层函数和属性,扩展函数和属性的原理,理解它们与Java的区别,并提出局部函数的概念

顶层函数不属于任何类,可以理解成Java的静态函数

//在Join.kt文件中
package strings

fun joinToString(...): String { ... }

const val UNIX_LINE_SEPARATOR = "\n"

相当于Java代码中的

package strings;
public class JoinKt {

    public static String joinToString(...) { ... }
    
    public static final String  UNIX_LINE_SEPARATOR = "\n";
}
//ExtendsionTextView.kt文件中
//扩展函数定义
fun TextView.isBold() = this.apply { 
	paint.isFakeBoldText = true
}

//扩展函数调用
activity.find<TextView>(R.id.course_comment_tv_score).isBold()

等同于下面的 Java 代码:

public final class ExtendsionTextViewKt {//这个类名就是顶层文件名+“Kt”后缀,这个知识上篇博客有详细介绍
   public static final TextView isBold(@NotNull TextView $receiver) {//扩展函数isBold对应实际上是Java中的静态函数,并且传入一个接收者类型对象作为参数
      Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
      $receiver.getPaint().setFakeBoldText(true);//设置加粗
      return $receiver;//最后返回这个接收者对象自身,以致于我们在Kotlin中完全可以使用this替代接收者对象或者直接不写。
   }
}

实际上就是一个静态函数,静态函数参数是接受者类型的对象,利用这个对象就可以访问这个对象里面的所有东西,所以相当于扩展了,扩展属性是怎么实现的呢?各位可以先思考一下,再看下面。

//ExtendsionTextView.kt文件中
//扩展属性定义
var TextView.isBolder: Boolean
	get() {//必须定义get()方法,因为不能在现有对象添加字段,也自然就没有了默认的get()实现
		return this.paint.isFakeBoldText
	}
	set(value) {
		this.paint.isFakeBoldText = true
	}
//扩展属性调用
activity.find<TextView>(R.id.course_comment_tv_score).isBolder = true

等同于下面的 Java 代码:

public final class ExtendsionTextViewKt {
   //get()方法所对应生成静态函数,并且传入一个接收者类型对象作为参数
   public static final boolean isBolder(@NotNull TextView $receiver) {
      Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
      return $receiver.getPaint().isFakeBoldText();
   }
   //set()方法所对应生成静态函数,并且传入一个接收者类型对象作为参数和一个需要set的参数
   public static final void setBolder(@NotNull TextView $receiver, boolean value) {
      Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
      $receiver.getPaint().setFakeBoldText(true);
   }
}

其实就是在get和set方法中加入了接受者类型的对象,利用这个对象就可以访问这个对象里面的所有东西

但是以为扩展函数和属性是静态的,所以是不能够重写的

class User(val id: Int, val name: String, val address: String)
 fun saveUser(user: User) {
        if (user.name.isEmpty()) {
            throw IllegalArgumentException("用户名为空不能保存")
        }
        if (user.address.isEmpty()) {
            throw IllegalArgumentException("用户地址为空不能保存")
        }
        //保存user
}

把其中检验字段的代码整个成一个验证的局部函数

fun saveUser(user: User) {
        fun validate(value: String, fieldName: String) {
            if (value.isEmpty()) {
                throw IllegalArgumentException("用户${user.fieldName} 为空不能保存") //局部函数能访问外部函数的user对象
            }
        }
        validate(user.name, "名")
        validate( user.address, "地址")
        //保存user
    }

当然,你也可以用将这段局部函数直接放进扩展函数中

fun User.validateBeforeSave() {
        fun validate(value: String, fieldName: String) {
            if (value.isEmpty()) {
                throw IllegalArgumentException("用户$fieldName 为空不能保存")
            }
        }
        validate(name, "名")
        validate(address, "地址")
    }

fun saveUser(user: User) {
        user.validateBeforeSave()
        //保存user
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值