2011-02-15 119 views
16

我试图用一个匹配替换我的isInstanceOf检查,但它不起作用。斯卡拉匹配错误

在我的方法中,我检查一个树节点 - 如果它是一片树叶 - 我想立即将它返回到一个Vector中,如果不是,我继续使用该方法。

所以我原本:

//code here 
    if (common.isInstanceOf[LeafNode]) { 
     return Vector(common.asInstanceOf[LeafNode].data) 
    } 
    //code here 

然后我试图取代它:

//code here 
    common match { 
     case leaf: LeafNode => return Vector(leaf.data) 
    } 
    //code here 

,但我得到scala.MatchError。

回答

21

如果您的common不是LeafNode,您将收到MatchError。您的ifmatch表达式不等效。我认为,最直接的方式,使他们相当于是:

common match { 
    case leaf: LeafNode => return Vector(leaf.data) 
    case _ => 
} 

但我建议在看整个代码块,并制定出有做这个工作更多的功能的方式。也就是说,没有中间的return。还记得那场比赛是一个表达式,所以这样的事情是可能的:

def foo = { 
    //code here 
    common match { 
    case leaf: LeafNode => Vector(leaf.data) 
    case notLeaf: Branch => //code here 
    } 
} 
5

问题是您的match区块中的一组病例并非详尽无遗;如果common不是LeafNode,则会引发MatchError。您可以通过具有像这样一个包罗万象的情况下解决这个问题:

common match { 
    case leaf: LeafNode => return Vector(leaf.data) 
    ... // other cases 
    case other => ... // what to do if nothing else matches 
} 

这是类似于default情况下在Java switch语句。 other案件被称为“无可辩驳的模式”,因为它没有特征;它不需要特定的类型或构造函数,因此它总是能够匹配任何符合它的东西。变量的名称不一定是other,它可以是任何你想要的,甚至是_ ......实际上你不需要在这里绑定一个新的变量,因为它将与common相同。

从样式上来看,在match块中放置返回语句通常是不好的形式;整个块是一个表达式,它的计算结果就是它的一种情况,所以只需返回整个表达式即可。此外,根本不需要使用return关键字,因为函数定义中的最后一个表达式将用作结果。

+0

约回报好一点,谢谢其实 – drozzy 2011-02-15 06:31:38

+0

,如果你在你的函数返回语句,斯卡拉2.9编译器会强迫你明确说明函数的返回类型。不知道有关早期版本,虽然 – Aaron 2011-08-18 20:55:40