Scala模式匹配'@'/在绑定运算符时无法保持类型缩小

时间:2015-07-12 17:11:16

标签: scala pattern-matching

我希望在模式匹配时缩小类型,以便特殊情况下,但是当尝试绑定元组我将模式匹配到变量时,Scala编译器似乎失去了在比赛。这使我无法转发匹配,而是必须重新创建元组,以便保留类型。

缩小示例:

    type mismatch;  found   : (Fruit, Int)  required: (Apple, Int)

是否有某种原因或只是一个特殊的角落案件?

我可能追踪存在的问题吗?我试着搜索,但空手而归。

编译器错误消息:

Apple

从本质上讲,我原本期望将case tup : (Apple, Int) @ (apple: Apple, index) => 案例转换为类似伪scala的内容:

tup

(Apple, Int)的类型为<body>

斯卡拉小提琴示例:http://scalafiddle.net/console/f182c4c2e7b4bd91debd2d0d636becac

Scala版本是2.11.6。

2 个答案:

答案 0 :(得分:2)

The spec says类型参数被实例化以符合模式的预期类型。这就是你如何知道嵌套的“组件模式”的预期类型。

所以它是从外到内,而不是从里到外。

我想知道元组优化是否适用于这种情况。

issue说,如果我创建一个元组只是为了解构它,不要费心去构造它。

如果我解构一个元组只是为了构造它,就会重新添加实例,即使它是一个不同的元组类型。

换句话说,避免重新装箱scala> :pa // Entering paste mode (ctrl-D to finish) sealed trait Fruit case class Apple(weight: Int = 200) extends Fruit case object Orange extends Fruit val fruits = Seq[Fruit](Apple(120), Orange, Orange, Apple()) // Exiting paste mode, now interpreting. defined trait Fruit defined class Apple defined object Orange fruits: Seq[Fruit] = List(Apple(120), Orange, Orange, Apple(200)) scala> fruits.zipWithIndex map { case (x: Apple, i: Int) => (x,i) case _ => (null, -1) } res0: Seq[(Apple, Int)] = List((Apple(120),0), (null,-1), (null,-1), (Apple(200),3))

的int和元组
public class MainClass {
    private UIController uIController;

    MainClass() {
        uIController = new UIController();
    }

    public void MethodIWantToCall() {
        //Do Something
    }
}

我将用例附加到故障单,因为元组是特殊生物,很快就会最终确定。

答案 1 :(得分:0)

我想,apple: Apple只是一个检查apple.isInstanceOf[Apple]并将值赋给apple变量的测试。但是,它不会更改tup Pair[Fruit, Int]的类型(或等效地,(Fruit, Int))。 (其他特征Product with Serializable来自caseOrange声明中的关键字Apple。)

(实际上,Seq(Apple(120), Orange, Orange, Apple())的类型为Seq[T],其中T是序列元素的最低超类型。超级类型T包含Fruit但是,关键字case会自动向Product with SerializableApple添加其他类型Orange,但不会向Fruit添加。这就是计算出的类型{{} 1}}有更多的类型信息。如果您愿意,您可以通过归序序列元素的类型来删除详尽的类型:T。它将具有类型Seq(Apple(120):Fruit, Orange, Orange, Apple())。)。