我有类型的问题,我不明白.在下面的代码中,我有两个方法half1和half2完全相同,除了half1的返回类型是明确指定的.然而,当我在foldLeft中使用这两个方法时,会导致编译器错误.这是代码.设置val c的行有问题.
package org.bodhi.reactive.`try` import scala.util.{Try,Success,Failure} object Hello { def main(args: Array[String]): Unit = { val list = List(1,2,3) Try(1024).flatMap(half1) Try(1024).flatMap(half2) half1(1024).flatMap(half1) half2(1024).flatMap(half2) val a = list.foldLeft(Try(1024))((accum,n) => accum.flatMap(half1)) val b = list.foldLeft(half1(1024))((accum,n) => accum.flatMap(half1)) val c = list.foldLeft(half2(1024))((accum,n) => accum.flatMap(half2)) // Compiler error } def half1(n: Int): Try[Int] = if (n % 2 == 0) Success(n / 2) else Failure(new Exception(s"WRONG $n")) def half2(n: Int) = if (n % 2 == 0) Success(n / 2) else Failure(new Exception(s"WRONG $n")) }
我得到的错误是:
[error] /home/chris/projects/reactive/example/src/main/scala/org/bodhi/reactive/try/Hello.scala:18: type mismatch; [error] found : scala.util.Try[Int] [error] required: Product with Serializable with scala.util.Try[Int] [error] val c = list.foldLeft(half2(1024))((accum,n) => accum.flatMap(half2))
我的问题是:为什么half1 comile在foldLeft,但是half2没有?
我正在使用scala 2.11.5
解决方法
成功和失败都将Try [T]扩展到带有Serializable的产品,(具有Serializable的产品,因为它们是案例类).因此,当您将返回类型保留为half2时,返回的类型将被推断为Try [T] with Product with Serializable.
通常这没关系,flatMap(half2)仍将返回Try [T]
scala> Try(1024).flatMap(half2) res2: scala.util.Try[Int] = Success(512)
但foldLeft是一个不同的故事.问题是当你传递half(2)作为第一个参数时.我们来看看foldLeft的签名:
def foldLeft[B](z: B)(op: (A,B) => B): B
B是从参数z推断出来的,这意味着
B = Try[T] with Product with Serializable
这意味着op应该具有以下类型:
(A,Try[T] with Product with Serializable) => Try[T] with Product with Serializable
但相反,它是(A,Try [T])=>尝试[T],因此您会遇到类型不匹配.使用类型推断可能很好,但大多数时候显式键入返回类型将为您节省很多麻烦.