Рефакторинг val к ​​методу приводит к ошибке времени компиляции - PullRequest
0 голосов
/ 13 ноября 2009

У меня сейчас

  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 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>
    }
  }

но я получаю следующее. Я проследил все типы возвращаемых данных и не вижу, как мой рефакторинг отличается от того, что происходит внутри. Я даже пытался добавить больше вариантов совпадения (как вы можете видеть в переработанном коде), чтобы убедиться, что я выбрал правильный тип.

/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>
                                                                  ^

Ответы [ 4 ]

3 голосов
/ 13 ноября 2009

Вот как мой мозг анализировал сообщение об ошибке ...

error: overloaded method value ->

Это имя метода, которое '->'.

with alternatives 

Ниже приведен список возможных параметров для -> в функции bind ().

[T <: net.liftweb.util.Bindable](T with net.liftweb.util.Bindable)net.liftweb.util.Helpers.TheBindableBindParam[T] 

Это говорит о том, что все, что реализует или включает черту Bindable, является честной игрой.

<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 

Ах! Узловые вещи. Наши допустимые параметры: NodeSeq, Seq [Node], Text и Node

cannot be applied to (List[scala.xml.NodeSeq])

Похоже, List [NodeSeq] не является допустимым параметром.

Имея это в виду, вы, вероятно, захотите вывести отдельный NodeSeq из списка, чтобы связать его с формой. Вы действительно хотите вернуть список из вспомогательного метода?

1 голос
/ 13 ноября 2009

Как примечание, в вашем коде есть одна вещь, которая не работает:

case all: List[NodeSeq]

Из-за стирания типа невозможно во время выполнения проверить, есть ли у all список List[NodeSeq], List[String], List[AnyRef] или что у вас есть. Я почти уверен, что вы должны получать предупреждение в этой строке и игнорировать его, потому что вы не понимаете, о чем оно вас предупреждает (по крайней мере, именно это случилось со мной, когда я получил такое предупреждение :). Правильная строка будет:

case all: List[_]

Что бы принять любой вид List. Посмотрите мой вопрос о стирании типов и Scala, чтобы узнать о нем побольше, если вам интересно.

1 голос
/ 13 ноября 2009

Одна проблема заключается в том, что ваше совпадение на самом деле не имеет никакого смысла: в основном вы сравниваете либо с пустым списком, либо с непустым списком. Других возможностей нет:

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
1 голос
/ 13 ноября 2009

Мне не удалось увидеть, что 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>
    }
  }

работает.

...