首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala:协变函数

Scala:协变函数
EN

Stack Overflow用户
提问于 2014-07-17 23:27:27
回答 3查看 234关注 0票数 1

假设下面有代码片段

代码语言:javascript
复制
 trait Foo

  class Bar extends Foo

  def foobar(fn: Option[Set[_ <: Foo] => Unit]) {}

  def main(args: Array[String]) {
  foobar(Option(bar)) //doesnt compile
  }

  def bar(input: Set[Bar]) {}

它执行编译,因为函数1被定义为trait Function1 [-T1, +R] extends AnyRef。我的问题是,Scala中是否有一个函数,它接受Type或它的子类型,然后做一些事情?或者我担心这是不可能的

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-18 00:32:32

可以将Setfoobar中的类型约束移出到函数本身的类型参数:

代码语言:javascript
复制
trait Foo {

  class Bar extends Foo

  def foobar[A <: Foo](fn: Option[Set[A] => Unit]) {}

  def main(args: Array[String]) {
      foobar(Option(bar _)) //compiles!
  }

  def bar(input: Set[Bar]) {}

}

Scala编译器将从传递给foobar的参数中推断类型foobar,同时仍然强制执行类型约束。此外,您还需要部分应用bar将其传递到这样的Option中。

票数 3
EN

Stack Overflow用户

发布于 2014-07-18 00:09:13

怎么样

代码语言:javascript
复制
trait Foo

class Bar extends Foo

def bar(input: Set[_ <: Foo]) {}

def foobar(fn: Option[Set[_ <: Foo] => Unit]) {}

foobar(Some(bar(_)))  // partially applied

foobar(None)

现在可以这样做,以便在某些情况下完全应用foobar()

代码语言:javascript
复制
 val x = Set(new Bar())

 foobar(Some( x => bar(x)))

注意,它必须是x => bar(x),因为类型是函数对象的一部分,而不是函数的结果。

票数 1
EN

Stack Overflow用户

发布于 2014-07-18 06:00:46

如果你想使用存在主义,而不是杰西的答案,你可以有这样的东西:

代码语言:javascript
复制
def foobar(fn: Option[(Set[X] => Unit) forSome { type X <: Foo }]) {}
foobar(Option(bar _))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24815150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档