2010-12-22 102 views
11

我正在学习一些斯卡拉代码,发现这种方法让我感到困惑。在比赛声明中,什么是[email protected]构造?它包含什么样的价值?当我打印它的差异不是tail,但如果我用尾部替换它,该函数返回差异结果。有人可以解释它是什么,并指出我是一个正确的资源来理解它吗? (我知道我可以在谷歌搜索,但不知道要寻找什么。)斯卡拉“匹配”帮助

def flatMapSublists[A, B](ls: List[A])(f: (List[A]) => List[B]): List[B] = 
    ls match { 
     case Nil => Nil 
     case [email protected](_ :: tail) => f(sublist) ::: flatMapSublists(tail)(f) 
    } 
+0

`@`通常用于注释中,但我在这里没有看到类似的东西...... – 2010-12-22 20:32:06

回答

28

我会称之为“吃你的蛋糕,让它太操作”。在模式匹配的任何级别,您可以给一个零件一个名称(在@之前)并将其进一步解构(在@之后)。例如想象你要匹配3个元素的列表,你需要的第二个元素,而是要记录整个列表:

something match { 
    case [email protected](_,elem,_) => log("matching:" + list); elem  
    case _ => error("not found") 
} 

没有此功能,你必须写类似

something match { 
    case List(a,elem,b) => log("matching:" + List(a,elem,b)); elem  
    case _ => error("not found") 
} 

正如您所看到的,我们需要命名第一个和第三个元素,仅仅是因为我们需要它们在右侧获取具有相同结构的列表,这是样板。如果您可以在整个结构中指定一个名称(list),并且结构中还有更深的零件(elem),并且您在右侧需要这两个零件时更容易和清楚。

8

在这种情况下,子列表成为整个列表(_ :: tail)命名变量。尾巴是列表的尾部。我不确定这里是否有'@'的专用名称。

我没有真正看到子列表的目的,因为你可以直接引用ls

声明:我是scala新手。我希望我有这个权利。

+1

Haskell(也可以是ML)也是如此。 – delnan 2010-12-22 20:37:02

+0

嘿,谢谢你的回答。这两个答案帮助我理解了它。 – 2010-12-22 21:12:30