在scala中指定以下概念的最佳方法是什么?该概念表示通用提取器函数的接口,该函数指定了在编译时提取的类。
Contruct的定义
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import scala.collection.JavaConversions._
trait ExtractorBase {
type ExtractedType
type RetType = Tuple2[Option[Seq[ExtractedType]],Option[Seq[String]]]
type ExtractorFunction = (Document) => RetType
def extractor : ExtractorFunction
}
class Extractor[T] (extractor_in: Any) extends ExtractorBase {
type ExtractedType = T
val extractor : ExtractorFunction = extractor_in
}
构造实例
//type TFunc = (Document) => Tuple2[Option[Seq[Int]],Option[Seq[String]]]
val ex = new Extractor[Int]( (x: Document)=> {
(Some(Seq(1)),Some(Seq("hassan")))
})
此时,提取器功能也没有正确别名:
[error] /Users/hassan/code/scala/extractor/hon.scala:14: type mismatch;
[error] found : Any
[error] required: org.jsoup.nodes.Document => (Option[Seq[Extractor.this.ExtractedType]], Option[Seq[String]])
[error] (which expands to) org.jsoup.nodes.Document => (Option[Seq[T]], Option[Seq[String]])
[error] val extractor : ExtractorFunction = extractor_in
如何在扩展特征的类的定义之外引用通用特征数据?在编译时和运行时。例如编译时,我宁愿:
trait ExtractorBase [T] { 类型ExtractedType = T. 类型RetType = Tuple2 [Option [Seq [ExtractedType]],Option [Seq [String]]] type ExtractorFunction =(Document)=> RetType def提取器:ExtractorFunction }
然后
class Extractor[T] (extractor_in: ExtractorBase[T].ExtractorFunction) extends ExtractorBase
类似于C ++特征。
在运行时我不介意获取特征中的类型信息。
可能有一种更惯用的创建特征实例的方法,我不想要通过Extractor[T]
类。有没有办法用特质的伴侣对象做到这一点?
修改
trait ExtractorBase[T] {
type ExtractedType = T
type RetType = Tuple2[Option[Seq[ExtractedType]],Option[Seq[String]]]
type ExtractorFunction = (Document) => RetType
def extractor : ExtractorFunction
}
class Extractor[T] (extractor_in: ExtractorBase[T]#ExtractorFunction) extends ExtractorBase[T] {
def extractor : ExtractorBase[T]#ExtractorFunction = extractor_in
}
导致:
val ex = new Extractor[Int]( (x: Document)=> {
(Some(Seq(1)),Some(Seq("hassan")))
})
答案 0 :(得分:0)
使用jsoup可以检索通用url和项目(或两者,或者任何一个,或者没有)的提取函数的可能通用规范可以定义如下。它是功能性的,惯用的afaik。如果可以改进,请提供意见。
import org.jsoup.nodes.Document
object ExtractorTraits {
case class UrlPair[T](data: String, payload: Option[T])
case class ResultPair[T,U](items: Option[Seq[T]],urls: Option[Seq[UrlPair[U]]] = None)
trait ItemExtractorTrait[I,C] {
type ExtractedType = I
type RetType = Option[Seq[ExtractedType]]
type ExtractorFunction = (Document,Option[C]) => RetType
def apply : ExtractorFunction
}
class ItemExtractor[I,C](extract_item : ItemExtractorTrait[I,C]#ExtractorFunction = (doc : Document,c: Option[C]) => None)
extends ItemExtractorTrait[I,C] { val apply = (doc: Document, ctxt: Option[C]) => extract_item(doc,ctxt) }
trait UrlExtractorTrait[U,C] {
type UrlPayload = U
type RetType = Option[Seq[UrlPair[U]]]
type ExtractorFunction = (Document,Option[C]) => RetType
def apply : ExtractorFunction
}
class UrlExtractor[U,C](extract_url : UrlExtractor[U,C]#ExtractorFunction = (doc:Document,c : Option[C]) => None)
extends UrlExtractorTrait[U,C] { val apply = (doc: Document, ctxt: Option[C]) => extract_url(doc,ctxt)}
trait ExtractorTrait[I,U,C] {
type RetType = ResultPair[I,U]
type ExtractorFunction = (Document, Option[C]) => RetType
def apply : ExtractorFunction
}
class Extractor[I,U,C] (item_extractor: ItemExtractorTrait[I,C]#ExtractorFunction = new ItemExtractor[I,C]().apply,
url_extractor: UrlExtractorTrait[U,C]#ExtractorFunction = new UrlExtractor[U,C]().apply) extends ExtractorTrait[I,U,C] {
val apply = (doc: Document, ctxt: Option[C]) => ResultPair[I,U](item_extractor(doc,ctxt),url_extractor(doc,ctxt))
}
}
修改强>
将功能特性分开,以便可以单独使用它们。
<强> EDIT2 强>
提取器现在有上下文