Scala 将val重构到方法会导致编译时错误

Scala 将val重构到方法会导致编译时错误,scala,refactoring,lift,Scala,Refactoring,Lift,我现在有 def list(node: NodeSeq): NodeSeq = { val all = Thing.findAll.flatMap({ thing => bind("thing", chooseTemplate("thing", "entry", node), "desc" -> Text(thing.desc.is), "creator" -> thing.creatorName.getOrElse("U

我现在有

  def list(node: NodeSeq): NodeSeq = {
    val all = Thing.findAll.flatMap({
      thing => bind("thing", chooseTemplate("thing", "entry", node),
        "desc" -> Text(thing.desc.is),
        "creator" -> thing.creatorName.getOrElse("UNKNOWN"),
        "delete" -> SHtml.link("/test", () => delete(thing), Text("delete"))
        )
    })

    all match {
      case Nil => <span>No things</span>
      case _ => <ol>{bind("thing", node, "entry" -> all)}</ol>
    }
  }
def列表(节点:NodeSeq):NodeSeq={
val all=Thing.findAll.flatMap({
thing=>bind(“thing”,选择模板(“thing”,“entry”,node),
“desc”->文本(thing.desc.is),
“creator”->thing.creatorName.getOrElse(“未知”),
“delete”->SHtml.link(“/test”,()=>delete(thing),Text(“delete”))
)
})
全部匹配{
案例Nil=>无任何问题
案例{bind(“thing”,node,“entry”->all)}
}
}
我试着把它重构成

  def listItemHelper(node: NodeSeq): List[NodeSeq] = {
    Thing.findAll.flatMap({
      thing => bind("thing", chooseTemplate("thing", "entry", node),
        "desc" -> Text(thing.desc.is),
        "creator" -> thing.creatorName.getOrElse("UNKNOWN"),
        "delete" -> SHtml.link("/test", () => delete(thing), Text("delete"))
        )
    })
  }

  def list(node: NodeSeq): NodeSeq = {
    val all = listItemHelper(node)

    all match {
      case Nil => <span>No things</span>
      case all: List[NodeSeq] => <ol>{bind("thing", node, "entry" -> all)}</ol>
      case _ => <span>wtf</span>
    }
  }
def listItemHelper(节点:NodeSeq):列表[NodeSeq]={
Thing.findAll.flatMap({
thing=>bind(“thing”,选择模板(“thing”,“entry”,node),
“desc”->文本(thing.desc.is),
“creator”->thing.creatorName.getOrElse(“未知”),
“delete”->SHtml.link(“/test”,()=>delete(thing),Text(“delete”))
)
})
}
def列表(节点:NodeSeq):NodeSeq={
val all=listItemHelper(节点)
全部匹配{
案例Nil=>无任何问题
case all:List[NodeSeq]=>{bind(“thing”,node,“entry”->all)}
案例=>wtf
}
}
但我得到了以下信息。我已经跟踪了所有的返回类型,我不认为我的重构与内部发生的重构有什么不同。我甚至尝试添加更多匹配案例(如重构代码中所示),以确保选择了正确的类型

/Users/trenton/projects/sc2/supperclub/src/main/scala/com/runbam/snippet/Whyme.scala:37: error: overloaded method value -> with alternatives [T <: net.liftweb.util.Bindable](T with net.liftweb.util.Bindable)net.liftweb.util.Helpers.TheBindableBindParam[T] <and> (Boolean)net.liftweb.util.Helpers.BooleanBindParam <and> (Long)net.liftweb.util.Helpers.LongBindParam <and> (Int)net.liftweb.util.Helpers.IntBindParam <and> (Symbol)net.liftweb.util.Helpers.SymbolBindParam <and> (Option[scala.xml.NodeSeq])net.liftweb.util.Helpers.OptionBindParam <and> (net.liftweb.util.Box[scala.xml.NodeSeq])net.liftweb.util.Helpers.BoxBindParam <and> ((scala.xml.NodeSeq) => scala.xml.NodeSeq)net.liftweb.util.Helpers.FuncBindParam <and> (Seq[scala.xml.Node])net.liftweb.util.Helpers.TheBindParam <and> (scala.xml.Node)net.liftweb.util.Helpers.TheBindParam <and> (scala.xml.Text)net.liftweb.util.Helpers.TheBindParam <and> (scala.xml.NodeSeq)net.liftweb.util.Helpers.TheBindParam <and> (String)net.liftweb.util.Helpers.TheStrBindParam cannot be applied to (List[scala.xml.NodeSeq])
      case all: List[NodeSeq] => <ol>{bind("thing", node, "entry" -> all)}</ol>
                                                                  ^
/Users/trenton/projects/sc2/supperclub/src/main/scala/com/runbam/snippet/Whyme.scala:37:错误:重载方法值->带替代项[T scala.xml.NodeSeq)net.liftweb.util.Helpers.FuncBindParam(Seq[scala.xml.Node])net.liftweb.util.Helpers.TheBindParam(scala.xml.Node)net.liftweb.util.Helpers.TheBindParam(scala.xml.Text)net.liftweb.util.Helpers.TheBindParam(scala.xml.NodeSeq)net.liftweb.util.Helpers.TheBindParam(字符串)net.liftweb.util.Helpers.TheStrBindParam不能应用于(列表[scala.xml.NodeSeq])
case all:List[NodeSeq]=>{bind(“thing”,node,“entry”->all)}
^

我没有看到NodeSeq扩展了Seq[Node],因此我在提取的方法上使用了错误的返回类型。将其更改为

  def listItemHelper(node: NodeSeq): NodeSeq = {
    Thing.findAll.flatMap({
      thing => bind("thing", chooseTemplate("thing", "entry", node),
        "desc" -> Text(thing.desc.is),
        "creator" -> thing.creatorName.getOrElse("UNKNOWN"),
        "delete" -> SHtml.link("/test", () => delete(thing), Text("delete"))
        )
    })
  }

  def list(node: NodeSeq): NodeSeq = {
    val all = listItemHelper(node)

    all.length match {
      case 0 => <span>No things</span>
      case _ => <ol>{bind("thing", node, "entry" -> all)}</ol>
    }
  }
def listItemHelper(节点:NodeSeq):NodeSeq={
Thing.findAll.flatMap({
thing=>bind(“thing”,选择模板(“thing”,“entry”,node),
“desc”->文本(thing.desc.is),
“creator”->thing.creatorName.getOrElse(“未知”),
“delete”->SHtml.link(“/test”,()=>delete(thing),Text(“delete”))
)
})
}
def列表(节点:NodeSeq):NodeSeq={
val all=listItemHelper(节点)
长跑比赛{
案例0=>什么都没有
案例{bind(“thing”,node,“entry”->all)}
}
}

有效。

我看不到NodeSeq扩展了Seq[Node],因此我在提取的方法上使用了错误的返回类型。将其更改为

  def listItemHelper(node: NodeSeq): NodeSeq = {
    Thing.findAll.flatMap({
      thing => bind("thing", chooseTemplate("thing", "entry", node),
        "desc" -> Text(thing.desc.is),
        "creator" -> thing.creatorName.getOrElse("UNKNOWN"),
        "delete" -> SHtml.link("/test", () => delete(thing), Text("delete"))
        )
    })
  }

  def list(node: NodeSeq): NodeSeq = {
    val all = listItemHelper(node)

    all.length match {
      case 0 => <span>No things</span>
      case _ => <ol>{bind("thing", node, "entry" -> all)}</ol>
    }
  }
def listItemHelper(节点:NodeSeq):NodeSeq={
Thing.findAll.flatMap({
thing=>bind(“thing”,选择模板(“thing”,“entry”,node),
“desc”->文本(thing.desc.is),
“creator”->thing.creatorName.getOrElse(“未知”),
“delete”->SHtml.link(“/test”,()=>delete(thing),Text(“delete”))
)
})
}
def列表(节点:NodeSeq):NodeSeq={
val all=listItemHelper(节点)
长跑比赛{
案例0=>什么都没有
案例{bind(“thing”,node,“entry”->all)}
}
}

有效。

一个问题是,您的匹配实际上没有任何意义:基本上,您是针对空列表或非空列表进行匹配。没有其他可能性:

all match {
  case Nil          =>  //if list is empty
  case nonEmptyList =>  //if list is not empty
}
当然,你也可以这样做:

case Nil       =>
case x :: Nil  => //list with only a head
case x :: xs   => //head :: tail

一个问题是,您的匹配实际上没有任何意义:基本上,您是针对空列表或非空列表进行匹配。没有其他可能性:

all match {
  case Nil          =>  //if list is empty
  case nonEmptyList =>  //if list is not empty
}
当然,你也可以这样做:

case Nil       =>
case x :: Nil  => //list with only a head
case x :: xs   => //head :: tail

下面是我的大脑如何解析错误信息

error: overloaded method value ->
这是方法的名称,它是'->'

with alternatives 
下面是bind()函数中->的可能参数列表

[T <: net.liftweb.util.Bindable](T with net.liftweb.util.Bindable)net.liftweb.util.Helpers.TheBindableBindParam[T] 
看起来列表[NodeSeq]不是有效的选项


考虑到这一点,您可能想从列表中取出一个单独的NodeSeq,以便将其绑定到表单。您确定要从helper方法返回列表吗?

下面是我的大脑如何解析错误消息的

error: overloaded method value ->
这是方法的名称,它是'->'

with alternatives 
下面是bind()函数中->的可能参数列表

[T <: net.liftweb.util.Bindable](T with net.liftweb.util.Bindable)net.liftweb.util.Helpers.TheBindableBindParam[T] 
看起来列表[NodeSeq]不是有效的选项


考虑到这一点,您可能希望将单个NodeSeq从列表中取出,以便将其绑定到表单。是否确实要从helper方法返回列表?

请注意,代码中有一点不起作用:

case all: List[NodeSeq]
由于类型擦除,无法在运行时测试
all
list a
list[NodeSeq]
list[String]
list[AnyRef]
或您有什么。我很确定您一定在那一行上收到了警告,并忽略了它,因为您不明白它警告了您什么(至少,当我收到这样的警告时,我就是这样的:)。正确的答案应该是:

case all: List[_]

它可以接受任何类型的
列表。
。如果您感兴趣,请查阅我关于类型擦除和Scala的问题,了解更多信息。

作为旁注,您的代码中有一点不起作用:

case all: List[NodeSeq]
由于类型擦除,无法在运行时测试
all
list a
list[NodeSeq]
list[String]
list[AnyRef]
或您有什么。我很确定您一定在那一行上收到了警告,并忽略了它,因为您不明白它警告了您什么(至少,当我收到这样的警告时,我就是这样的:)。正确的答案应该是:

case all: List[_]
哪个wo