首页 > 其他分享 >Kotlin中的扩展函数和扩展属性

Kotlin中的扩展函数和扩展属性

时间:2023-05-30 20:44:31浏览次数:28  
标签:函数 Kotlin Activity 扩展 context activity dp2px 属性

扩展函数

Kotlin中可以给一个类额外添加这个类中没有的函数,即扩展函数。例如:

fun Int.dp2px(context: Context) {
	TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), context.resources.displayMetrics)
}

fun test () {
	println(16.dp2px())
}

上述代码给Int类添加了一个扩展函数dp2px用于将dp转成px,在代码中可以直接对Int类型的变量调用dp2px函数,就好像Int类的其他固有函数一样。在扩展函数中可以通过this访问调用扩展函数的变量本身。

需要注意的是,扩展函数的调用者类型是静态声明的类型,而不是实际的运行时类型,例如:

fun Context.toString() : String {
	return "context"
}
fun Activity.toString() : String {
	return "activity"
}

fun printContext(context: Context) {
	println(context.toString())
}

fun test(activity: Activity) {
	printContext(activity)
}

上述代码调用test函数输出的结果是"context"而不是"activity"

扩展属性

Kotlin中还可以给一个类额外添加这个类中没有的属性,即扩展属性。例如:

val View.activity : Activity?
	get() = this.context as? Activity

上述代码给View类添加了一个扩展属性activity,扩展属性并不是真的给该类添加了一个属性,所以只能通过gettersetter来访问和初始化

扩展函数和扩展属性的原理

class Test {

    fun Int.dp2px(context: Context) {
        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), context.resources.displayMetrics)
    }

    val View.activity : Activity?
        get() = this.context as? Activity

}

通过将上述Kotlin代码转成字节码再反编译后如下:

public final class Test {

   public final void dp2px(int $this$dp2px, @NotNull Context context) {
      Intrinsics.checkNotNullParameter(context, "context");
      float var10001 = (float)$this$dp2px;
      Resources var10002 = context.getResources();
      Intrinsics.checkNotNullExpressionValue(var10002, "context.resources");
      TypedValue.applyDimension(1, var10001, var10002.getDisplayMetrics());
   }

   @Nullable
   public final Activity getActivity(@NotNull View $this$activity) {
      Intrinsics.checkNotNullParameter($this$activity, "$this$activity");
      Context var10000 = $this$activity.getContext();
      if (!(var10000 instanceof Activity)) {
         var10000 = null;
      }

      return (Activity)var10000;
   }

}

可以发现扩展函数和扩展属性的原理是在编译后生成了特定的函数,并将扩展类型的对象作为第一个参数传递进去。
对于Int类型的扩展函数dp2px实际是在Test类中生成一个dp2px函数,并接收Int类型的参数$this$dp2px作为第一个参数。
对于View类型的扩展属性activity实际是在Test类中生成一个getActivity函数,并接收View类型的参数$this$activity作为第一个参数

标签:函数,Kotlin,Activity,扩展,context,activity,dp2px,属性
From: https://www.cnblogs.com/jqctop1/p/17443151.html

相关文章

  • 自定义方法,实现按指定属性进行去重
    实例:根据age、sex、name对user对象集合进行去重//构建user对象publicclassUser{privateintid;privateStringname;privateintage;privateStringsex;privatedoubleheight;//构造方法、getter和setter略}//创建对象集合List<User......
  • uiautomator2获取UIObject元素的属性info用法
    info是UIAutomator2中用来获取控件属性信息的方法。该方法可以获取到指定元素的一些属性信息,例如控件的文本、坐标、大小、类名、包名、是否可见等。使用该方法可以帮助我们更好的理解应用程序的UI结构,并找到需要操作的控件元素。d(text=element,instance=index).infoinfo是U......
  • C# 程序开发中如何移除List集合的某列(属性)呢?
    如题,在C#&.NET,.NETCore程序开发中如何移除List集合的某列(属性)呢?比如,有以下的MyClass类: publicclassMyClass{publicintColumn1{get;set;}publicstringColumn2{get;set;}publicintColumn3{get;set;}}现在MyClass的集合myList,如何......
  • android开发java.lang.NoClassDefFoundError: org/jetbrains/kotlin/cli/common/Prope
    问题:编译Android项目出现java.lang.NoClassDefFoundError:org/jetbrains/kotlin/cli/common/PropertiesKt原因:项目使用发JDK版本和Kotlin版本不一致或者说不对应导致gradle找不到对应的类解决方法:我的解决方法是降低JDK的版本到1.8,具体操作是OpenModulesSettings->SDKLoc......
  • vscode 自定义代码字体颜色,局部变量、全局变量、函数、宏、属性
    vscode自定义代码字体与颜色风格在setting.json中修改即可:在这里插入图片描述"editor.semanticTokenColorCustomizations":{       "enabled":true,//enableforallthemes       "rules":{           "*.static":{             ......
  • WPF属性(依赖属性&附加属性)
    本篇文章学习于:刘铁猛老师《深入浅出WPF》什么是属性?属性又称为CLR属性(CLR,CommonLanguageRuntime)。我们既可以说CLR属性是private字段的安全访问包装,也可以说一个private字段在后台支持(back)一个CLR属性。classPerson{privatestringname;publicstringNam......
  • hdu 5102(队列+节点扩展)
    TheK-thDistanceTimeLimit:8000/4000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptionGivenatree,whichhasnnodeintotal.Definethedistancebetweentwonodeuandvisthenumberofedgeontheirunique......
  • 您的监控策略是否可扩展?
    家公司都在努力更好地了解其运营效率,但他们都遇到了同样的问题:规模。那么,可扩展的监控策略是什么样的?您如何防范可观察性中最重要的问题?什么是可扩展监控策略?我们将从确定受规模影响最大的两件事开始:成本和性能。成本可以分解为存储和计算。很明显,要容纳更多数据,就需要更多存储空间......
  • mybatis查询时实体类属性名与表的字段名不一致的解决方法
    目录1、设置查询字段别名法2、在mybatis的核心配置文件中设置全局配置信息mapUnderscoreToCamelCase为true,将表中字段的下划线自动转换为驼峰3、将select语句的resultType换为resultMap,在resultMap中配置字段名和属性值的对应关系———————————————— 问题描......
  • Docker php安装扩展步骤详解
    前言此篇,主要是演示docker-php-source,docker-php-ext-install,docker-php-enable-docker-configure这四个命令到底是用来干嘛的,它们在PHP容器中都做了哪些事情。很多人很不理解在Dockerfile中安装PHP扩展的时候总是出现这几个命令,本篇就就是为你揭开这些命令的神秘面纱而准......