在Scala中,_ :: _是什么意思?

7

我正在阅读一本名为《Lift in action》的书,遇到了一个我不太理解的东西:_ ::


object permanent_link extends MappedString(this, 150){
    override def validations =
    valMinLen(3, "Link URL must be at least 5 characters") _ ::
    super.validations
}

我找不到任何线索,如果有人能帮助我,我将不胜感激。

3个回答

18

我不了解Lift,但这是一个普遍的问题。首先,:: 是Scala的cons运算符:

scala> 1 :: 2 :: List(3, 4)
res0: List[Int] = List(1, 2, 3, 4)
这意味着super.validations是某种序列,而valMinLen(3, "Link URL must be at least 5 characters") _是该列表中的单个值。
从上下文来看,在重写的validations方法中,他们调用了super版本,并在开头添加一些额外的验证。
这个额外的验证是通过调用valMinLen()创建的。但是,这个额外的调用并没有返回与validations列表类型相匹配的元素,而是一个函数。我们不是将函数值前置,而是明确地说(通过添加_后缀)我们想要前置函数本身,而不是该函数的返回值。
代码片段胜过千言万语:
scala> def f = 3
f: Int

scala> def g = 4
g: Int

scala> val listOfInts = List(f, g)
listOfInts: List[Int] = List(3, 4)

scala> val listOfFunctions = List(f _, g _)
listOfFunctions: List[() => Int] = List(<function0>, <function0>)

比较 listOfIntslistOfFunctions 的类型。我相信 Scala 世界中 f _ 语法被称为 部分应用函数


5

下划线表示valMinLen不应被调用,而应该被用作函数“指针”。

::操作符连接列表。

换句话说,代码似乎构建了一个名为validations的列表,其中包含对给定参数使用函数“指针”valMinLen的调用和其余列表为super.validations即超类的验证。

我相信有人会纠正我的术语 :)


0

通过一些适当的缩进和引入val,代码可能会更易读:

object permanent_link extends MappedString(this, 150) {

  override def validations = minimumValidation :: super.validations

  val minimumValidation = valMinLen(3,"Link URL must be at least 5 characters") _
}

所以如前所述,:: 运算符只是将一个新元素添加到列表中,_ 与此无关,用于获取函数对象,例如:
(1 :: 2 :: Nil) map (println _)

创建一个列表 [1, 2] 并将函数 println 应用于每个元素 (这里可以省略下划线)。对象 println _ 构造一个函数对象,该函数从方法 println 中获取,并使用 _ 表示函数的单个参数。


你可以在声明之前引用 minimumValidation 吗? - ziggystar
在Scala中,声明顺序并不重要,大多数现代语言也是如此。 - Ozymandias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接