0

私は現在持っています

  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

4 に答える 4

3

これが私の脳がエラーメッセージをどのように解析したかです...

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 を取り出して、フォームにバインドすることをお勧めします。本当にヘルパー メソッドからリストを返したいですか?

于 2009-11-13T00:22:07.453 に答える
1

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

動作します。

于 2009-11-13T00:19:46.630 に答える
1

1 つの問題は、一致が実際には意味をなさないことです。基本的に、空のリストまたは空でないリストのいずれかと一致しています。他に可能性はありません:

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
于 2009-11-13T00:20:06.973 に答える
1

補足として、コードには機能しないものが 1 つあります。

case all: List[NodeSeq]

タイプが eraseであるため、実行時にallリスト a List[NodeSeq]List[String]List[AnyRef]または what-have-youかどうかをテストする方法はありません。その行で警告が表示され、それが何を警告しているのか理解していないため、それを無視していると確信しています(少なくとも、そのような警告が表示されたときに私に起こったことです:)。正しい行は次のようになります。

case all: List[_]

どんな種類のList. 興味があれば、型消去と Scala に関する私の質問を調べて、それについてもう少し調べてください。

于 2009-11-13T11:50:35.940 に答える