当前位置: 首页 > 知识库问答 >
问题:

使用函数引用注册和取消注册侦听器是否安全?

韦高格
2023-03-14

我最近发现自己正在编写以下代码:

fun listener() {
    // Do some stuff
    adapter.removeLoadStateListener(::listener)
}
adapter.addLoadStateListener(::listener)

一位同事指出

val x1 = ::listener
val x2 = ::listener
x1 == x2 //true
x1 === x2 //false

然而,

var mySet = mutableSetOf<() -> Unit>()

fun a() { }

fun b() { }

mySet.add(::a)
mySet.add(::b)
mySet.remove(::a)

mySet.contains(::a) // false
mySet.contains(::b) // true

基于这一点,我得到的印象是我没有正确理解::MyFun,我开始怀疑我的原始代码是否安全。

DR

  1. 使用::listener引用要用作侦听器且需要多次引用的方法(例如,添加+删除)是否安全?
  2. 关于匿名类等的幕后实际发生了什么?

共有1个答案

燕昊东
2023-03-14

当您使用::listener时,您每次都在创建一个实现接口的匿名类。但是,正如您的测试所示,匿名类的.equals将返回它们相等,而匿名类(使用object:语法创建)通常不是这种情况。因此,使用:Listener创建的两个实例将与==等价,但与===不等价。

集合通常使用.equals等式(==)来确定实例是否重复,但可以创建一个由IdentityHashMap支持的集合,这样它就可以使用标识比较有效地表现为集合。这违反了设置的契约,但类可能会出于某种原因在内部使用它。

使用它是否安全取决于您使用的类是通过.equals还是通过identity来比较侦听器实例。如果它可能使用IdentityHashMap来存储和比较侦听器,那么这是不安全的。

 类似资料:
  • 问题内容: 我是NodeJS的新手,正在学习它如何与流一起工作。读一本书,我发现了以下示例代码: 在此代码段中,我们先调用method,然后等待回调( 第1部分 )。 在下一行,我们正在监听事件( 第2部分 )。 问题: 如果在第1部分和第2部分之间发生延迟,那么首先执行第1部分的回调(在第2部分开始侦听事件之前。那是真的会丢失第一个数据块)吗? 问题答案: 不,因为您 不是在“等待” 回调。回调

  • 我尝试将在Apache Camel处理器中处理的数据推送到侦听器类。在处理器类实例中,我尝试在Camel上下文的实例化期间注册侦听器,但不知何故失败了。也许我在这里根本错误,这是不可能的。如果是这种情况,最好你告诉我。 我有一个Apache Camel路由,从ActiveMQ服务器获取JSON消息,并将这些JSON推送到一个自定义处理器类,该类由Camel-Spring XML定义: 我的想法是,

  • 扩展内可以调用registerFunction来注册内置函数到PHP中。需要注意Zend有限制,必须在Extension对象创建时注册函数。这与类的注册不同,扩展类必须在onStart回调中注册。 PHPX_EXTENSION() { Extension *ext = new Extension("test", "0.0.1"); ext->registerFunction(PHP

  • 我想知道用JPA/Hibernate注册自定义SQL函数的最佳方法是什么。

  • void register_function(string name, mixed impl, bool cacheable, array or null cache_attrs) Use this to dynamically register template function plugins. Pass in the template function name, followed by t

  • 本文向大家介绍uwp 取消注册任务,包括了uwp 取消注册任务的使用技巧和注意事项,需要的朋友参考一下 示例