Рефакторинг val в метод приводит к ошибке времени компиляции

StackOverflow https://stackoverflow.com/questions/1726277

  •  19-09-2019
  •  | 
  •  

Вопрос

В настоящее время у меня есть

  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>
                                                                  ^
Это было полезно?

Решение

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

error: overloaded method value ->

Это название метода, которое называется '->'.

with alternatives 

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

[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 

Ах!Материал, связанный с узлом.Нашими допустимыми параметрами, по-видимому, являются NodeSeq, Seq [Node], Text и Node

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

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

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

Другие советы

Я не смог увидеть, что 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>
    }
  }

работает.

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

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

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

case all: List[NodeSeq]

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

case all: List[_]

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top