首页 > 其他分享 >推荐使用 Kotlin 关键字 Reified

推荐使用 Kotlin 关键字 Reified

时间:2023-04-21 10:56:56浏览次数:42  
标签:getDataOrNull val Int Kotlin bundle reified 关键字 Bundle Reified

原文地址 zhuanlan.zhihu.com

推荐使用 Kotlin 关键字 Reified

残枫cps残枫cps

​目录收起1. 不再需要传参数 clazzreified 方式2. 不安全的转换reified 方式3. 不同的返回类型函数重载reified 方式

原文地址 www.jianshu.com

reified:使抽象的东西更加具体或真实,非常推荐 Android 开发使用这个关键字。本文介绍 3 点特别的使用方式如下:

1. 不再需要传参数 clazz

大部分的文章讲解 reified 的使用,都有提到这个点,比如我们定义实现一个扩展函数启动 Activity,一般都需要传 Class<T> 参数:

// Function
private fun <T : Activity> Activity.startActivity(context: Context, clazz: Class<T>) {
    startActivity(Intent(context, clazz))
}

// Caller
startActivity(context, NewActivity::class.java)

reified 方式

使用 reified,通过添加类型传递简化泛型参数

// Function
inline fun <reified T : Activity> Activity.startActivity(context: Context) {
    startActivity(Intent(context, T::class.java))
}

// Caller
startActivity<NewActivity>(context)

2. 不安全的转换

Kotlin 中, 使用安全转换操作符 as?,它可以在失败时返回 null。实现如下函数,我们认为会安全地获取数据或返回 null

// Function
fun <T> Bundle.getDataOrNull(): T? {
    return getSerializable(DATA_KEY) as? T
}

// Caller
val bundle: Bundle? = Bundle()
bundle?.putSerializable(DATA_KEY, "Testing")
val strData: String? = bundle?.getDataOrNull()
val intData: Int? = bundle?.getDataOrNull() // Crash

然而,如果获得的数据不是它期望的类型,这个函数会出现 crash。 因此为了安全获取数据,修改之前的函数如下:

// Function
fun <T> Bundle.getDataOrNull(clazz: Class<T>): T? {
    val data = getSerializable(DATA_KEY)
    return if (clazz.isInstance(data)) {
        data as T
    } else {
        null
    }
}

// Caller
val bundle: Bundle? = Bundle()
bundle?.putSerializable(DATA_KEY, "Testing")
val strData: String? = bundle?.getDataOrNull(String::class.java)
val intData: Int? = bundle?.getDataOrNull(String::class.java) // Null

这种写法不太友好,不仅在实现函数的方式上,而且还需要传递额外的 clazz 参数。

reified 方式

使用 reified,简化泛型参数和保证 as? 类型转换安全性

// Function
private inline fun <reified T> Bundle.getDataOrNull(): T? {
    return getSerializable(DATA_KEY) as? T
}

// Caller
val bundle: Bundle? = Bundle()
bundle?.putSerializable(DATA_KEY, "Testing")
val strData: String? = bundle?.getDataOrNull()
val intData: Int? = bundle?.getDataOrNull() // Null

3. 不同的返回类型函数重载

实现一个函数计算 DP 到像素,并返回一个 Int 或 Float。这种情况就会想到函数重载,如下所示:

fun Resources.dpToPx(value: Int): Float {
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        value.toFloat(), displayMetrics)
}

fun Resources.dpToPx(value: Int): Int {
    val floatValue: Float = dpToPx(value)
    return floatValue.toInt()
}

但是,这将导致编译时出错。原因是,函数重载方式只能根据参数计数和类型不同,而不能根据返回类型。

reified 方式

使用 reified,可以实现不同的返回类型函数重载

inline fun <reified T> Resources.dpToPx(value: Int): T {
    val result = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        value.toFloat(), displayMetrics)

    return when (T::class) {
        Float::class -> result as T
        Int::class -> result.toInt() as T
        else -> throw IllegalStateException("Type not supported")
    }
}

// Caller
val intValue: Int = resource.dpToPx(64)
val floatValue: Float = resource.dpToPx(64)

从上面的3个例子中,很明显 reified 使 Kotlin 用起来更加友好。如果还有其他场景使用 reified 的方法,欢迎分享。

编辑于 2023-04-21 10:46・IP 属地山东KotlinScalaJava​赞同​添加评论​分享​喜欢​收藏​设置

标签:getDataOrNull,val,Int,Kotlin,bundle,reified,关键字,Bundle,Reified
From: https://www.cnblogs.com/cps666/p/17339556.html

相关文章

  • JAVA访问修饰符与关键字
    访问修饰符定义:Java中,可以使用访问修饰符来保护对类、变量、方法和构造方法的访问。Java支持4种不同的访问权限。分类:private:在同一类内可见。使用对象:变量、方法。注意:不能修饰类(外部类)default(即缺省,什么也不写):在同一包内可见,不使用任何修饰符。使用对象:类......
  • SpringBoot Kotlin 集成和使用 Protobuf
    环境版本不同的环境配置参数可能区别较大,请酌情参考。插件或依赖版本号SpringBoot2.7.10Gradle7.5.1ProtobufGradlePlugin0.9.2ProtobufJava3.21.9Protoc3.21.9Grpc1.53.0项目是使用IDEA创建的SpringWeb项目,语言Kotlin,构建GradlePr......
  • volatile关键字
    volatile(不稳定的)如何保证变量的可见性:在Java中,volatile关键字可以保证变量的可见性,如果我们将变量声明为volatile,这就指示JVM,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。volatile关键字能保证数据的可见性,但不能保证数据的原子性。publicvo......
  • 亚马逊平台使用API接口通过关键字搜索商品
    亚马逊公司(Amazon,简称亚马逊;NASDAQ:AMZN),2022年营收为5140亿美元,是美国最大的一家网络电子商务公司,位于华盛顿州的西雅图。是网络上最早开始经营电子商务的公司之一,亚马逊成立于1994年,一开始只经营网络的书籍销售业务,现在则扩及了范围相当广的其他产品,已成为全球商品品种最多的网......
  • super关键字和方法重写
    1.super关键字介绍super代表父类的引用,用于访问父类的属性、方法、构造器2.基本语法297代码在com.stulzl.super_.包中父类Apackagecom.stulzl.super_;publicclassA{//4个属性publicintn1=100;protectedintn2=200;intn3=300;private......
  • vi 查找关键字
    https://blog.csdn.net/weixin_40959890/article/details/128004090vi打开一个文件后命令模式下敲斜杆(/),这时在状态栏(也就是屏幕左下脚)就出现了“/”然后输入你要查找的关键字敲回车就可以了。如果你要继续查找此关键字,敲字符n就可以继续查找了。敲字符N(大写N)就会向前......
  • Java-Day-12( 类变量 + 类方法 + main 方法 + 代码块 + 单例设计模式 + final 关键字 )
    Java-Day-12类变量定义一个变量count,是一个类变量(静态变量)staticclassPerson{privateStringname;// 该静态变量static最大的特点就是会被Person所有的对象实例共享publicstaticintcount=0;publicPerson(Stringname){this.na......
  • C++ const关键字
    参考资料:【C++const的各种用法详解】【const用法深入浅出】-COS-博客园(cnblogs.com)const的基本概念:const名叫常量限定符,用来限定特定变量,以通知编译器该变量是不可修改的。习惯性的使用const,可以避免在函数中对某些不应修改的变量造成可能的改动。下面我就const的用法......
  • break和continue关键字的使用
    break和continue关键字的使用使用范围循环中使用的作用break:switch-case、循环结构中结束当前循环continue:循环结构中结束当次循环......
  • #yyds干货盘点#python关键字参数
    关键字参数kwarg=value 形式的 关键字参数 也可以用于调用函数。函数示例如下:defparrot(voltage,state='astiff',action='voom',type='NorwegianBlue'):print("--Thisparrotwouldn't",action,end='')print("ifyouput......