在随后的scala 2.10.0-M7会话中:
scala> trait A
defined trait A
scala> class B extends A
defined class B
scala> class C extends A
defined class C
scala> Some(0).fold(new B){_=>new C}
<console>:11: error: type mismatch;
found : C
required: B
Some(0).fold(new B){_=>new C}
Run Code Online (Sandbox Code Playgroud)
我希望编译器找到常见的超类型(即A)而不是抱怨.是一般的类型推理限制,还是Option.fold定义方式的结果?
谢谢.
kir*_*uku 10
Scalas类型推理算法与Option.fold定义方式相结合的问题结果.
Scalas类型推断从左到右工作,这意味着它从最左边的符号开始,以搜索表达式的可能类型.此外,对于方法参数列表,这意味着泛型类型绑定到最左边的参数列表填充的类型:
scala> def meth[A](a1: A, a2: A) = (a1, a2)
meth: [A](a1: A, a2: A)(A, A)
scala> meth(1, "")
res7: (Any, Any) = (1,"")
scala> def meth[A](a1: A)(a2: A) = (a1, a2)
meth: [A](a1: A)(a2: A)(A, A)
scala> meth(1)("")
<console>:10: error: type mismatch;
found : String("")
required: Int
meth(1)("")
^
Run Code Online (Sandbox Code Playgroud)
可以看出,在第一种情况下Any是推断的,而在第二种情况下,抛出编译器错误,因为类型A由第一个参数列表绑定而第二个不能再改变它.
但是为了使问题中的方法调用起作用,在Option达到第二个参数列表之前,可能不会定义结果的类型.因为这需要从右到左类型推断因此错误.这有点相同List.fold:
scala> List(1).foldLeft(Nil)((xs,x) => x::xs)
<console>:8: error: type mismatch;
found : List[Int]
required: scala.collection.immutable.Nil.type
List(1).foldLeft(Nil)((xs,x) => x::xs)
^
Run Code Online (Sandbox Code Playgroud)
要使代码生效,必须明确指定生成的集合的类型,有关示例,请参阅@rks answer.
请参阅此处的讨论,以获得完整解释为何定义它的定义.简而言之:Option在许多方面遵循集合的设计 - 因此,当它的行为与集合的行为相同时更加清晰.
| 归档时间: |
|
| 查看次数: |
2056 次 |
| 最近记录: |