【问题标题】:Methods versus Function and implicits in ScalaScala 中的方法与函数和隐式
【发布时间】:2012-04-03 09:48:58
【问题描述】:

让我们将 def 和等效函数声明为 val:

scala> def optional(x:Int):Option[String] = None
optional: (x: Int)Option[String]

scala> val optional2:(Int)=>Option[String] = (i:Int) => None
optional2: Int => Option[String] = <function1>

现在为什么这不起作用?

scala> List(1).flatMap(optional2)
<console>:9: error: type mismatch;
 found   : Int => Option[String]
 required: Int => scala.collection.GenTraversableOnce[?]
              List(1).flatMap(optional2)
                              ^

虽然这两个都可以?

scala> List(1).flatMap(optional)
res4: List[String] = List()

scala> List(1).flatMap(optional2(_))
res5: List[String] = List()

由于 Option 不是 GenTraversableOnce 的子类型,我认为这一定与隐式有关,但我无法弄清楚它到底是什么。我正在使用 Scala 2.9.1。

【问题讨论】:

    标签: scala option implicits


    【解决方案1】:

    隐式转换 Option.option2IterableList(1).flatMap(optional)List(1).flatMap(optional2(_)) 工作的原因。

    您的问题可以归结为隐式转换未被拾取:

    scala> val optional2:(Int)=>Option[String] = (i:Int) => None
    optional2: Int => Option[String] = <function1>
    
    scala> (optional2(_)): Function[Int, Iterable[String]]
    res0: Int => Iterable[String] = <function1>
    
    scala> (optional2): Function[Int, Iterable[String]]
    <console>:9: error: type mismatch;
     found   : Int => Option[String]
     required: Int => Iterable[String]
    

    当您使用下划线时,编译器会尝试键入函数并提供必要的隐式转换。当您只提供 optional2 时,没有适用的隐式转换。

    【讨论】:

    • 是的,但是为什么不能应用于第一种情况呢?
    • @KimStebel,optional2 没有隐式转换。在第二种情况optional2(_) 中,编译器会为您构建一个函数并尝试匹配返回类型,这时它会选择option2Iterable
    • 换句话说,没有从Function[T,R1] =&gt; Function[T,R2] 的隐式转换,其中存在隐式R1 =&gt; R2。您需要使用optional2(_) 构建一个新的函数对象,以便可以进行隐式转换,在本例中为i =&gt; optional2(i: Iterable[String])optional2 是一个对象,optional2(_) 是一个新对象。
    猜你喜欢
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    相关资源
    最近更新 更多