1

我想知道具有其中一个属性的数据类是否是函数,例如:

data class Holder(val x: Data, val f: () -> Unit)

完全可以工作,因为以下测试失败。

val a = {}
val b = {}
Assert.assertEquals(a, b)

更新:用例可能是有一个

data class ButtonDescriptor(val text: String, val onClick: () -> Unit)

然后在做的时候把它流到 UIdistinctUntilChanged()

4

2 回答 2

1

创建数据类时,如果通过引用传递函数,它将与 DiffUtils 和 distinctUntilChanged() 一起使用。函数引用不会isEquals()像 lambda 那样破坏数据类的方法。

例如,您为 onClick 创建一个函数:

private fun onClick() { // handle click }

并创建您的数据类

BottomDescriptor("some text", ::onClick)
于 2021-09-13T10:49:08.220 回答
1

我不认为这是可能的,我害怕。

您当然可以检查引用相等性(===或者==在这种情况下,因为函数通常不会覆盖equals())。这会给你一个明确的答案,你可以引用相同的函数实例。但这并不能检查结构相等性,因此将问题中的两个 lambda 报告为不同。

您可以通过检查它们的.javaClass属性来检查这两个函数是否是同一类的实例。如果相同,则意味着它们执行相同的处理——尽管我认为它们仍然可以具有不同的变量/捕获。但是,如果不同,那不会告诉您任何事情。即使是问题中的简单示例也是不同的类……</p>

当然,您不能将它们作为“黑匣子”进行检查——尝试所有可能的输入并检查它们的输出是不可行的。(即使假设它们是没有副作用的纯函数,这通常不是真的!)

也许可以从类加载器中获取它们的字节码,然后进行比较,但我真的不推荐它——这将是很多不必要的工作,你必须考虑到类名等方面的差异,它可能会有很多误报,而且我再次认为它可以为两个由于参数/捕获不同而表现不同的函数返回相同的代码。

所以不,我认为这在 JVM 语言中是不可能的。

你想用这个实现什么,还有其他方法吗?(例如,如果这些函数在您的控制之下,您可以安排引用相等来做您需要的事情吗?或者您可以使用带有额外属性的函数对象来提供 ID 或其他您可以比较的东西吗?)

于 2021-06-11T10:51:25.343 回答