例如,我怎样才能(或为什么我可以)使用URL
方法自动将所有implicit
个对象转换为相关的超链接:
implicit def urlToXML(url: URL): xml.Node =
<a href={ url.toString }>{ url.getHost + url.getPath }</a>
然后我可能(隐含地)使用它:
val myURL = new URL("https://example.com")
<p>Hey, come check out my cool new website at { myURL }.</p>
Scala(2.11.5)似乎忽略了implicit
方法并将URL
对象直接转换为字符串。
答案 0 :(得分:0)
那是因为当使用大括号来转义XML文字时,需要String
。如果找到对象,则调用toString
。你可以在这里看到:
<p>{ new {} }</p> //returns <p>$anon$1@17aaa54f</p>
您可能以前只是在大括号中插入其他XML节点,因为toString
在Node
上运行良好,允许您执行以下操作:
<p>{ <div/> }</p> //returns <p><div/></p>
但这只是真的有效,因为<div/>.toString == "<div/>"
。所以在你的情况下,编译器无法知道你想要将myUrl
转换为Node
,然后然后调用toString
- 它认为它只需拨打toString
上的URL
。
有很多方法可以解决这个问题。您可以使用类型归属来触发隐式转换:
<p>Hey, come check out my cool new website at { myURL:Node }.</p>
您可以明确调用该方法(在此版本中,您不需要隐式转换):
<p>Hey, come check out my cool new website at { urlToXml(myURL) }.</p>
或者制作一个需要Node
:
def insertUrl(urlNode: Node) = <p>Hey, come check out my cool new website at { urlNode }.</p>
insertUrl(myUrl) //The implicit comes in to play here
答案 1 :(得分:0)
转化必须由预期类型或成员选择触发。在这种情况下,嵌入式Scala表达式的预期类型为Any
。
这是它的编译方式:
scala> <tag>{ 42 }{ new java.net.URI("http://acme.com") }</tag>
[[syntax trees at end of typer]] // <console>
package $line3 {
object $read extends scala.AnyRef {
def <init>(): $line3.$read.type = {
$read.super.<init>();
()
};
object $iw extends scala.AnyRef {
def <init>(): type = {
$iw.super.<init>();
()
};
object $iw extends scala.AnyRef {
def <init>(): type = {
$iw.super.<init>();
()
};
private[this] val res0: scala.xml.Elem = {
{
new scala.xml.Elem(null, "tag", scala.xml.Null, scala.this.xml.TopScope, false, ({
val $buf: scala.xml.NodeBuffer = new scala.xml.NodeBuffer();
$buf.&+(42);
$buf.&+(new java.net.URI("http://acme.com"));
$buf
}: _*))
}
};
<stable> <accessor> def res0: scala.xml.Elem = $iw.this.res0
}
}
}
}
另外,
scala> implicit class `uri anchor`(val u: java.net.URI) { def a = <a href={ u.toString }>{ u.getHost }</a> }
defined class uri$u0020anchor
scala> <tag>{ new java.net.URI("http://acme.com").a }</tag>
res1: scala.xml.Elem = <tag><a href="http://acme.com">acme.com</a></tag>
scala>
另一种方法是提供一个自定义xml库,该库在该位置采用有用的类型,例如Embeddable
,您可以为其提供所需的类型类。
另一种选择是预测Scala的未来并使用插值器。