- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我试图理解 reified
关键字的用途,显然是 it's allowing us to do reflection on generics .
但是,当我将其省略时,它也可以正常工作。任何人愿意解释这何时会产生实际的不同?
最佳答案
reified
适合fun <T> myGenericFun(c: Class<T>)
在泛型函数的主体中,如 myGenericFun
,您无法访问类型 T
因为它仅在编译时可用,但 erased在运行时。因此,如果你想在函数体中使用泛型类型作为普通类,你需要将类作为参数显式传递,如myGenericFun
所示。 .
如果您创建 inline
具有具体化的功能T
, T
的类型即使在运行时也可以访问,因此您不需要传递 Class<T>
此外。您可以使用 T
就好像这是一个普通的类(class) - 例如你可能想检查一个变量是否是一个实例 T
,然后您可以轻松完成:myVar is T
.
这样的inline
功能与 reified
类型 T
如下所示:
inline fun <reified T> myGenericFun()
reified
作品您只能使用 reified
结合 inline
功能。通过这样做,您指示编译器将函数的字节码复制到调用函数的每个位置(编译器“内联”函数)。当您调用 inline
功能与 reified
类型,编译器必须能够知道作为类型参数传递的实际类型,以便它可以修改生成的字节码以直接使用相应的类。因此,像 myVar is T
这样的电话变成 myVar is String
在字节码中(如果类型参数是 String
)。
让我们看一个例子来说明 reified
的帮助可。我们要为 String
创建一个扩展函数调用toKotlinObject
尝试将 JSON 字符串转换为具有函数泛型类型 T
指定类型的普通 Kotlin 对象.我们可以使用 com.fasterxml.jackson.module.kotlin
为此,第一种方法如下:
a) 没有具体化类型的第一种方法
fun <T> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
//does not compile!
return mapper.readValue(this, T::class.java)
}
readValue
方法采用应该解析 JsonObject
的类型至。如果我们尝试获取 Class
类型参数T
,编译器提示:“不能使用 'T' 作为具体类型参数。请改用类。”
b) 使用显式 Class
的解决方法参数
fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, c.java)
}
作为一种解决方法,Class
的 T
可以作为方法参数,然后用作 readValue
的参数.这很有效,并且是通用 Java 代码中的常见模式。可以这样调用:
data class MyJsonType(val name: String)
val json = """{"name":"example"}"""
json.toKotlinObject(MyJsonType::class)
c) Kotlin 方式:reified
使用 inline
功能与 reified
类型参数T
使得以不同方式实现功能成为可能:
inline fun <reified T: Any> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, T::class.java)
}
无需使用Class
的 T
另外,T
可以像普通类一样使用。对于客户端,代码如下所示:
json.toKotlinObject<MyJsonType>()
带有 reified
的内联函数type 不能从 Java 代码中调用。
关于generics - Kotlin 中的 reified 关键字是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45949584/
下面的测试类,通过。 class SimpleClassTest { private inline fun anyObject(): T { return Mockito.a
我需要获取 lambda 函数实现的 AST。我被卡住了,因为 reify 对论点起作用,而不是对它的值(value)起作用。 val x = (a: Int) => println("a") val
基于 this comment关于具体化, It acts like @property, except that the function is only ever called once; aft
我有一些这样的代码: {-# LANGUAGE AllowAmbiguousTypes #-} module Foo where import Data.Proxy class Foo x y cla
当使用reify时在 Clojure 中,如何为构造函数提供表达式? 或者,如何将参数传递给基类构造函数? 最佳答案 您不能使用reify来子类化和实例化类——它仅适用于协议(protocol)和接口
我尝试阅读论文( http://www.ittc.ku.edu/csdl/fpg/sites/default/files/Gill-09-TypeSafeReification.pdf )并设法具体化
是否有可能做到 reify在 GHCi 中? 当我使用“runQ”尝试它时,它提示“无法在 IO monad 中进行具体化”。 >>> runQ (reify ''Bool) Template Has
为什么我们需要Control.Lens.Reified ?是否有某种原因导致我无法将 Lens 直接放入容器中? reify 到底是什么意思? 最佳答案 我们需要具体化的镜头,因为 Haskell 的
我正在尝试围绕如下所示的 Java API 编写 Clojure 层: public class Executor { public interface ExecutorJob { pub
我在 Pyramid tutorial for UX design 中看到了.我无法弄清楚这个装饰器到底是什么。 我看到其用法的示例代码。 def __init__(self, request):
我试图理解 reified 关键字的用途,显然是 it's allowing us to do reflection on generics . 但是,当我将其省略时,它也可以正常工作。任何人愿意解释
我一直在使用 Scala 宏,并在宏中包含以下代码: val fieldMemberType = fieldMember.typeSignatureIn(objectType) match {
为什么我应该在 clojure 中使用 Reify 而不是代理? 最佳答案 reify 的方法体是词法闭包,可以引用周围的局部作用域。 reify 与 proxy 的不同之处在于: 仅支持协议(pro
我编写了一些代码,以使用“DefineTypeGeneric”类检测类型模型数据。 主类 fun main() { val list = ArrayList() list.add("K
实际上,主要问题仍然是 Kotlin 中的类没有具体化的类型参数。但这就是为什么在这种特定情况下这困扰我的原因: 假设您有一个包装类 Wrapper接受一个字符串 content和一个类(class)
我在有关 haskell 和函数式编程的博客中读了很多这个术语(特别是 sigfpe's blog ),但我不知道它的含义。大多数时候我都不知道,但如果我知道的话,我可能会更好地理解这些文本。谷歌没有
我有一个仅发出事件的 java 接口(interface),我正在尝试在 Clojure 中实现它。 Java接口(interface)是这样的(现实中还有很多其他方法): public interf
我正在尝试编写一个断言函数来检查给定对象是否属于 T 类型: @UseExperimental(ExperimentalContracts::class) inline fun assertIsIn
我真的可以用你的帮助来解释这个功能。 我有一个包含 2 个字符串值、一个国家名称和一个货币的国家枚举。练习是使用 2 个字符串输入,检查枚举是否有国家,然后比较它们的货币,相应地返回 true 或 f
我正在寻找 -print 或 javap 的替代方案来了解编译器在 Scala 中执行的操作。有了新的反射/宏库,reify 似乎是一个很好的候选者,如 Retronym 的 macrocosm 所示
我是一名优秀的程序员,十分优秀!