object Thing {
def apply[T](s: String, f: T => Option[Boolean]) = ThingBuilder(s, f)
def apply[T](s: String, f: T => Option[Long]) = ThingBuilder(s, f)
}
sealed trait Thing[T, U] {
def name: String
def get(t: T): Option[U]
}
trait BooleanThing[T] extends Thing[T, Boolean]
trait LongThing[T] extends Thing[T, Long]
object ThingBuilder {
def apply[T](s: String, f: T => Option[Boolean]) = new BooleanThing[T] {
override final val name: String = s
override final def get(t: T): Option[Boolean] = f(t)
}
def apply[T](s: String, f: T => Option[Long]) = new LongThing[T] {
override final val name: String = s
override final def get(t: T): Option[Long] = f(t)
}
}
正如您所看到的,b / w BooleanThing[T]
和LongThing[T]
(类型U
)之间只有一个区别。构建器应用方法基本上是复制/粘贴,并切换出类型U
。有什么更好的方法可以做到这一点,以避免这种复制/粘贴的性质?
(顺便说一句,请不要建议我将一个特质改为一个类,我需要它们是这样的特征。)
答案 0 :(得分:0)
我倾向于认为您可能需要根据您的要求将 function loadXMLDoc(filename) {
if (window.ActiveXObject || "ActiveXObject" in window) {
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
} else {
xhttp = new XMLHttpRequest();
}
xhttp.open("GET", filename, false);
xhttp.send("");
return xhttp.responseXML;
}
if (window.ActiveXObject || "ActiveXObject" in window) {
ie();
} else {
xml = loadXMLDoc("input.xml");
xsl = loadXMLDoc("mmlctop2_0.xsl");
if (document.implementation && document.implementation.createDocument) {
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToDocument(xml, document);
var serializer = new XMLSerializer();
var transformed = serializer.serializeToString(resultDocument.documentElement);
alert(transformed);
}
}
// https://msdn.microsoft.com/en-us/library/ms753809(v=vs.85).aspx
function ie() {
var xslt = new ActiveXObject("Msxml2.XSLTemplate.3.0");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");
var xslProc;
xslDoc.async = false;
xslDoc.load("mmlctop2_0.xsl");
if (xslDoc.parseError.errorCode != 0) {
var myErr = xslDoc.parseError;
alert("You have error " + myErr.reason);
} else {
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
xmlDoc.async = false;
xmlDoc.load("input.xml");
if (xmlDoc.parseError.errorCode != 0) {
var myErr = xmlDoc.parseError;
alert("You have error " + myErr.reason);
} else {
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.addParameter("param1", "Hello");
xslProc.transform();
alert(xslProc.output);
}
}
}
的{{1}}实例明确定义为Thing[T]
或BooleanThing[T]
。
否则,如果您需要操作的只是LongThing[T]
,隐藏第二个参数类型的具体类型,那么您可以在Thing[T]
方法中添加另一个参数类型:
apply
以下使用Scala 2.12编译:
object Thing {
def apply[S, T](s: String, f: T => Option[S]) = ThingBuilder(s, f)
}
...
object ThingBuilder {
def apply[S, T](s: String, f: T => Option[S]) = new Thing[T, S] {
override final val name: String = s
override final def get(t: T): Option[S] = f(t)
}
}
这样做的缺点是我们失去了特征val a1: Thing[Int, Boolean] = Thing("Hello, Boolean", (x: Int) => Some(true))
val a2: Thing[_, Boolean] = a1
val b1: Thing[String, String] = Thing("Hello, String", Some(_: String))
val b2: Thing[_, String] = b1
和BooleanThing
的特化。