2009-11-13 68 views
0

方法結果我現在有重構VAL在編譯時錯誤

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

回答

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,序列[節點],文本和節點

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

貌似列表[NodeSeq]不是一個有效的選項。

考慮到這一點,您可能想從列表中取出單個NodeSeq以將其綁定到表單。你確定你真的想從助手方法返回一個列表嗎?

1

我沒有看到NodeSeq擴展序列[節點],所以我對提取出的方法錯誤的返回類型。更改爲

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

工程。

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 
1

作爲一個側面說明,有一個在你的代碼一兩件事,不工作:

case all: List[NodeSeq] 

因爲類型擦除的,有沒有辦法測試,在運行時,是否all列表List[NodeSeq]List[String],List[AnyRef]或什麼是你。我很確定你必須在那條線上發出警告,並且忽略它,因爲你不明白它警告你的是什麼(至少,當我得到這樣的警告時,這就是發生在我身上的事情)。正確的路線是:

case all: List[_] 

這將接受任何形式的List。如果你有興趣,請在類型擦除和Scala上查找我的問題,以查看更多關於它的信息。

+0

之前出現了編譯錯誤,所以沒有警告b/c。 – Trenton 2009-11-14 23:22:45