【问题标题】:Scala Unit to Anonymous ClassScala 单元到匿名类
【发布时间】:2012-07-06 11:27:31
【问题描述】:

是否可以将 Unit 转换为匿名类的方法?

代替:

addSelectionListener(new SelectionListener{
    def widgetSelected(SelectionEvent event): Unit = {
       //...
    }
}

到这里:

addSelectionListener toAnonymousClass(classOf[SelectionListener], { 
    /* .. */ 
})

如果没有任何库可以做到这一点,我将如何制作一个?有可能吗?

【问题讨论】:

    标签: scala closures anonymous-class


    【解决方案1】:

    我相信下面的隐式转换应该可以达到你想要的结果:

    implicit def selectionListener (f: SelectionEvent => Unit) = 
      new SelectionListener {
        def widgetSelected(event: SelectionEvent) {
          f(event)
        }
      }
    

    它会自动将SelectionEvent => Unit 类型的函数文字转换为SelectionListener,这样你就可以像这样使用addSelectionListener 方法:

    addSelectionListener { event: SelectionEvent =>
        /* .. */ 
    }
    

    【讨论】:

    • 是否可以使用单一方法和单一参数编写适用于任何接口的东西?
    • 不,不是。 1. selectionListener 隐式的当前返回类型是SelectionListener - 如果函数能够返回其他类型,您希望它是什么? 2. 即使你希望这个函数返回的所有类型都实现了一些更高的接口,比如Listener,并且你把它作为转换的返回类型,你将如何解决在转换中返回哪个实现?因此,基本上您应该为所提供的示例要使用的每个匿名类创建一个隐式。
    • 有道理:)。无论如何,您重用了许多相同的侦听器,因此它仍然比编写所有匿名类要少得多。谢谢
    【解决方案2】:

    您可以将重载添加到addSelectionListener,这样您就不需要隐式转换。从 2.10 开始,此类转换需要导入 language.implicitConversions,这是一个微妙的提示,您应该尽可能避免它们。

    def addSelectionListener(f: SelectionEvent => Unit) = 
      addSelectionListener(new SelectionListener {
        def widgetSelected(event: SelectionEvent): Unit = f(event)
      }
    })
    

    然后用作

    addSelectionListener { se => 
      /* ... */
    }
    

    这也少了样板,因为您不需要类型注释。

    如果你在其他地方使用它,你可以将重载方法放在任何addSelectionListener 定义的子类中,或者在一个特征中。

    【讨论】:

      猜你喜欢
      • 2022-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多