我在原帖中解释我正在寻找的东西显然做得很差,所以让我们再试一次.我想要完成的是能够传递一系列项目,提取一个或多个项目,然后将序列的REMAINDER传递给另一个提取器.注意,按顺序,我的意思是序列(不一定是List).我之前的例子使用list作为序列,我给出了一些使用cons(::)提取的例子,但我也可以将一个数组作为我的序列传递.
我以为我知道模式匹配和提取是如何工作的但我可能是错的,所以为了避免任何更基本的评论和链接到如何进行模式匹配网站这里是我的理解:
如果我想从提取器返回单个项目,我将定义一个unapply方法.此方法采用我选择的任何类型作为输入(类型可以是序列...)并返回单个可选项(返回类型本身可以是序列).如果我想要匹配,则返回必须包含在Some中.如果不需要,则返回None.下面是一个示例,它将序列作为输入并返回包含在Some中的相同序列,但前提是它包含所有字符串.我很可能只是返回包含在Some中的序列而不做其他任何事情,但这似乎会给人们造成混乱.关键是如果它被包装在Some中那么它将匹配,如果它是None,它将不会.为了更清楚,除非输入也匹配我的unapply方法输入类型,否则匹配也不会发生.这是我的例子:
object Test {
// In my original post I just returned the Seq itself just to verify I
// had matched but many people commented they didn't understand what I
// was trying to do so I've made it a bit more complicated (e.g. match
// only if the sequence is a sequence of Strings). Hopefully I don't
// screw this up and introduce a bug :)
def unapply[A](xs: Seq[A]): Option[Seq[String]] =
if (xs forall { _.isInstanceOf[String] …Run Code Online (Sandbox Code Playgroud) 我出于好奇而发布这个问题,看看是否有人知道模式匹配在以下情况下是如何工作的.假设我的函数值定义如下:
val f = (s: String) => s.toInt
Run Code Online (Sandbox Code Playgroud)
它的类型当然是String => Int.现在我想创建一个基于模式匹配传递给该函数的输出的新函数.我可以定义如下:
val f2 = f(_: String) match {
case i: Int => i + 2
}
Run Code Online (Sandbox Code Playgroud)
现在我的新函数也来自String => Int,但它在此过程中增加了2.它可以如下调用:
scala> f2("3")
res0: Int = 5
Run Code Online (Sandbox Code Playgroud)
如果我在不进行部分应用的情况下执行相同的操作,那么我会根据函数本身获得匹配:
val f3 = f match {
case x => "matched: " + x
}
Run Code Online (Sandbox Code Playgroud)
现在值f3被赋值为"匹配的<function1>",因为它调用匹配'f'作为值.
所以我的问题是,Scala如何区分这两者?它们都是函数值,都是String => Int类型.实际上,如果我在运行匹配之前将部分应用的函数值分配给临时变量tmp,那么它的行为与f3相同:
val tmp = f(_: String)
val f4 = tmp match {
case x => "matched: " + x
}
Run Code Online (Sandbox Code Playgroud)
现在为f4分配了"匹配<function1>"而不是函数String => Int.
我可以看到想要做的任何价值,我只是好奇它是如何完成的.这只是一些神奇的Scala补充说,不知怎的,它确定你在匹配的上下文中部分应用了一个函数,所以它会产生不同的东西......
是否可以根据Scala中的另一个清单定义清单?
我几乎不相信这是不可能的,因为Scala Manifest信息不是动态使用的.
这是问题所在.我有一个函数可以返回多种类型的对象(String,Int,List [Int],List [List [String]]等).为了支持这些多种类型,返回类型设置为Any,但是由于要键入擦除,列表,地图等支持的类型信息将丢失.为了恢复一些细节,我返回一个Manifest以及返回类型.
但是,返回的信息可以放在另一个列表或映射中,然后从另一个函数返回.我想更新清单,以包括类型现在是清单定义的先前类型的List或Map这一事实.
这是一些示例代码
def returnWithManifest[T: Manifest](x: T) = (x, manifest[T])
// May return String, Int, List[Int], List[List[String]], ...
def contrivedExample(t: String): (Any, Manifest[_]) = t match {
case "String" => returnWithManifest("test")
case "Int" => returnWithManifest(1)
case "Boolean" => returnWithManifest(true)
case "List[Int]" => returnWithManifest(List(1,2,3))
case "List[List[String]]" =>
returnWithManifest(List(List("a","b"),List("c","d")))
case _ => returnWithManifest(None)
}
scala> val v1 = contrivedExample("List[Int]")
v1: (Any, Manifest[_]) = (List(1, 2, 3),scala.collection.immutable.List[Int])
scala> val x = v1._1
x: Any = List(1, 2, …Run Code Online (Sandbox Code Playgroud)