方法与Scala中的函数和含义

Kim*_*bel 8 scala option implicits

让我们声明一个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>
Run Code Online (Sandbox Code Playgroud)

现在为什么这不起作用?

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

虽然这两个都做到了吗?

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

scala> List(1).flatMap(optional2(_))
res5: List[String] = List()
Run Code Online (Sandbox Code Playgroud)

由于Option不是GenTraversableOnce的子类型,我认为这必须与implicits有关,但我无法弄清楚究竟是什么.我正在使用Scala 2.9.1.

huy*_*hjl 7

隐式转换Option.option2Iterable是什么使得List(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]
Run Code Online (Sandbox Code Playgroud)

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

  • 换句话说,没有来自`Function [T,R1] => Function [T,R2]`的隐式转换,其中存在隐式的"R1 => R2".您需要使用`optional2(_)`构建一个新的函数对象,以便可以进行隐式转换,在本例中为`i => optional2(i:Iterable [String])`.`optional2`是一个对象,`optional2(_)`是一个新对象. (3认同)