﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-ghost-随笔分类-scala</title><link>http://www.blogjava.net/ghost/category/43247.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 12 Jan 2010 09:55:34 GMT</lastBuildDate><pubDate>Tue, 12 Jan 2010 09:55:34 GMT</pubDate><ttl>60</ttl><item><title>scala中的协变与逆变</title><link>http://www.blogjava.net/ghost/archive/2010/01/12/309043.html</link><dc:creator>冯雪松</dc:creator><author>冯雪松</author><pubDate>Tue, 12 Jan 2010 09:20:00 GMT</pubDate><guid>http://www.blogjava.net/ghost/archive/2010/01/12/309043.html</guid><wfw:comment>http://www.blogjava.net/ghost/comments/309043.html</wfw:comment><comments>http://www.blogjava.net/ghost/archive/2010/01/12/309043.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ghost/comments/commentRss/309043.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ghost/services/trackbacks/309043.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;java中的泛型：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">List</span><span style="color: #000000">&lt;</span><span style="color: #000000">String</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;s1</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ArrayList</span><span style="color: #000000">&lt;</span><span style="color: #000000">String</span><span style="color: #000000">&gt;</span><span style="color: #000000">();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s1.add(</span><span style="color: #000000">"</span><span style="color: #000000">hello</span><span style="color: #000000">"</span><span style="color: #000000">);</span></div>
当在s1中添加 String 类型以外的对象时，编译器会报错。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">s1.add(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Date());</span></div>
scala 中是用 [] 代替 java 中的&lt;&gt; 表达泛型。scala 在new ArrayList时，不需要指定String类型，得益与scala 的类型推断。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">val&nbsp;strs&nbsp;:&nbsp;List[String]</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ArrayList()</span></div>
scala 中定义泛型列表，和java中类似<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Link[T](val&nbsp;head:&nbsp;T,&nbsp;val&nbsp;tail:&nbsp;Link[T])&nbsp;</span></div>
协变的定义:&nbsp;&nbsp;&nbsp;&nbsp;假设有类G(或者接口和特征) 和类型T1,T2&nbsp; 。 在T1是T2的子类的情况下， 如果G&lt;T1&gt; 也是G2&lt;T2&gt;的子类，则类G是协变的。<br />
<br />
当我定义一个列表对象li，并定义一个ln为li 的别名<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">&nbsp;List</span><span style="color: #000000">&lt;</span><span style="color: #000000">Integer</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;li</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ArrayList</span><span style="color: #000000">&lt;</span><span style="color: #000000">Integer</span><span style="color: #000000">&gt;</span><span style="color: #000000">();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;li.add(</span><span style="color: #000000">1</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: #000000">&lt;</span><span style="color: #000000">Number</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;ln</span><span style="color: #000000">=</span><span style="color: #000000">li;</span></div>
<br />
这样的方式，编译器不能通过。<br />
通过协变，可以实现上诉功能<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_48_49_Open_Image" onclick="this.style.display='none'; Codehighlighter1_48_49_Open_Text.style.display='none'; Codehighlighter1_48_49_Closed_Image.style.display='inline'; Codehighlighter1_48_49_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_48_49_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_48_49_Closed_Text.style.display='none'; Codehighlighter1_48_49_Open_Image.style.display='inline'; Codehighlighter1_48_49_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Link[</span><span style="color: #000000">+</span><span style="color: #000000">T](val&nbsp;head&nbsp;:&nbsp;T,&nbsp;val&nbsp;tail:&nbsp;Link[T])&nbsp;</span><span id="Codehighlighter1_48_49_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_48_49_Open_Text"><span style="color: #000000">{}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img id="Codehighlighter1_82_188_Open_Image" onclick="this.style.display='none'; Codehighlighter1_82_188_Open_Text.style.display='none'; Codehighlighter1_82_188_Closed_Image.style.display='inline'; Codehighlighter1_82_188_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_82_188_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_82_188_Closed_Text.style.display='none'; Codehighlighter1_82_188_Open_Image.style.display='inline'; Codehighlighter1_82_188_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />def&nbsp;main(args&nbsp;:&nbsp;Array[String])</span><span id="Codehighlighter1_82_188_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_82_188_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val&nbsp;ln&nbsp;:&nbsp;Link[Integer]</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Link[Integer](</span><span style="color: #000000">1</span><span style="color: #000000">,</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val&nbsp;lnn&nbsp;:&nbsp;Link[Number]</span><span style="color: #000000">=</span><span style="color: #000000">ln<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; println(lnn.head)<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
<br />
但是如果试图加入一个方法，追加一个参数，并返回Link， 则会产生编译错误<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_48_111_Open_Image" onclick="this.style.display='none'; Codehighlighter1_48_111_Open_Text.style.display='none'; Codehighlighter1_48_111_Closed_Image.style.display='inline'; Codehighlighter1_48_111_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_48_111_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_48_111_Closed_Text.style.display='none'; Codehighlighter1_48_111_Open_Image.style.display='inline'; Codehighlighter1_48_111_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Link[</span><span style="color: #000000">+</span><span style="color: #000000">T](val&nbsp;head&nbsp;:&nbsp;T,&nbsp;val&nbsp;tail:&nbsp;Link[T])&nbsp;</span><span id="Codehighlighter1_48_111_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_48_111_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;def&nbsp;prepend(newHead:&nbsp;T):&nbsp;Link[T]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Link(newHead,&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">)<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
<p class="alt"><span>&nbsp;</span> <br />
实际上，范型变为协变之后就不能把类型参数不加修改的放在成员方法的参数上（这里是newHead）了。但是，通过将成员方法定义为范型，并按照如下所示描述后就可以避免该问题了</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_47_124_Open_Image" onclick="this.style.display='none'; Codehighlighter1_47_124_Open_Text.style.display='none'; Codehighlighter1_47_124_Closed_Image.style.display='inline'; Codehighlighter1_47_124_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_47_124_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_47_124_Closed_Text.style.display='none'; Codehighlighter1_47_124_Open_Image.style.display='inline'; Codehighlighter1_47_124_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Link[</span><span style="color: #000000">+</span><span style="color: #000000">T](val&nbsp;head:&nbsp;T,&nbsp;val&nbsp;tail:&nbsp;Link[T])&nbsp;</span><span id="Codehighlighter1_47_124_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_47_124_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;prepend[U&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">:&nbsp;T](newHead:&nbsp;U):&nbsp;Link[U]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Link(newHead,&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">)&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000">&nbsp;</span></div>
scala 逆变，类似协变<br />
假设有类 G 和类型T1,T2, 在T1&nbsp;是T2的子类的情况，如果G[T2]是G[T1]的子类， 则G为逆变。<br />
假设含有 apply的类 LessThan(apply 的逻辑 当a&lt;b 时，返回true 否则返回false)<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_28_63_Open_Image" onclick="this.style.display='none'; Codehighlighter1_28_63_Open_Text.style.display='none'; Codehighlighter1_28_63_Closed_Image.style.display='inline'; Codehighlighter1_28_63_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_28_63_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_28_63_Closed_Text.style.display='none'; Codehighlighter1_28_63_Open_Image.style.display='inline'; Codehighlighter1_28_63_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /><span style="color: #0000ff">abstract</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;LessThan[</span><span style="color: #000000">T]&nbsp;</span><span id="Codehighlighter1_28_63_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_28_63_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;def&nbsp;apply(a:&nbsp;T,&nbsp;b:&nbsp;T):&nbsp;Boolean<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_50_123_Open_Image" onclick="this.style.display='none'; Codehighlighter1_50_123_Open_Text.style.display='none'; Codehighlighter1_50_123_Closed_Image.style.display='inline'; Codehighlighter1_50_123_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_50_123_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_50_123_Closed_Text.style.display='none'; Codehighlighter1_50_123_Open_Image.style.display='inline'; Codehighlighter1_50_123_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /><span style="color: #000000">val&nbsp;hashCodeLt:&nbsp;LessThan[Any]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;LessThan[Any]&nbsp;</span><span id="Codehighlighter1_50_123_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_50_123_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;apply(a:&nbsp;Any,&nbsp;b:&nbsp;Any):&nbsp;Boolean&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;a.hashCode&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;b.hashCode<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;strLt:&nbsp;LessThan[String]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;hashCodeLt<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">assert</span><span style="color: #000000">(</span><span style="color: #0000ff">true</span><span style="color: #000000">&nbsp;,strLt(</span><span style="color: #000000">"</span><span style="color: #000000">a</span><span style="color: #000000">"</span><span style="color: #000000">,</span><span style="color: #000000">"</span><span style="color: #000000">b</span><span style="color: #000000">"</span><span style="color: #000000">))</span></div>
在非变的情况&nbsp;编译器会报错：<font style="background-color: #cce8cf">Error:Error:line (18)error: type mismatch;<br />
found&nbsp;&nbsp; : xxx.LessThan[Any]<br />
required: xxx.LessThan[String]<br />
val strLt: LessThan[String] = hashCodeLt<br />
在需要LessThan[Any]的地方使用了LessThan[String]，由此看来LessThan不是逆变的，也不是协变，可以成为非变。<br />
但是在类的定义前加一个 - 符号，使用逆变， 代码则可编译过去了。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_28_63_Open_Image" onclick="this.style.display='none'; Codehighlighter1_28_63_Open_Text.style.display='none'; Codehighlighter1_28_63_Closed_Image.style.display='inline'; Codehighlighter1_28_63_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_28_63_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_28_63_Closed_Text.style.display='none'; Codehighlighter1_28_63_Open_Image.style.display='inline'; Codehighlighter1_28_63_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /><span style="color: #0000ff">abstract</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;LessThan[</span><span style="color: #000000">-</span><span style="color: #000000">T]&nbsp;</span><span id="Codehighlighter1_28_63_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_28_63_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;def&nbsp;apply(a:&nbsp;T,&nbsp;b:&nbsp;T):&nbsp;Boolean<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
</font><br />
<font style="background-color: #cce8cf"><br />
</font><br />
<img src ="http://www.blogjava.net/ghost/aggbug/309043.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ghost/" target="_blank">冯雪松</a> 2010-01-12 17:20 <a href="http://www.blogjava.net/ghost/archive/2010/01/12/309043.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Scala的implicit隐式转换</title><link>http://www.blogjava.net/ghost/archive/2009/12/23/307049.html</link><dc:creator>冯雪松</dc:creator><author>冯雪松</author><pubDate>Wed, 23 Dec 2009 09:17:00 GMT</pubDate><guid>http://www.blogjava.net/ghost/archive/2009/12/23/307049.html</guid><wfw:comment>http://www.blogjava.net/ghost/comments/307049.html</wfw:comment><comments>http://www.blogjava.net/ghost/archive/2009/12/23/307049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ghost/comments/commentRss/307049.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ghost/services/trackbacks/307049.html</trackback:ping><description><![CDATA[<p>java 有很庞大的类库资源，但是 被声明成 final 的类不允许继承 例如 String ， 怎样扩展java及第三方类库 scala提供了很灵活的方式</p>
<p>当 scala 使用 implicit 隐式转化时 ，&nbsp; scala 编辑器发现对象的类型不匹配时，不会直接报错，而会在代码中尝试匹配implicit声明的object, 当然，相同方法签名的类必须唯一。<br />
举个小例子，实现在字符串前后 添加 "**" 的操作。</p>
当然 例子本事无实际意义， 只是说明implicit的用法而已&nbsp;<br />
<div style="padding-right: 5px; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left-color: #cccccc; width: 98%; word-break: break-all; padding-top: 4px; background-color: #eeeeee; "><span style="color: #008080">&nbsp;1</span><img id="Codehighlighter1_17_201_Open_Image" onclick="this.style.display='none'; Codehighlighter1_17_201_Open_Text.style.display='none'; Codehighlighter1_17_201_Closed_Image.style.display='inline'; Codehighlighter1_17_201_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_17_201_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_17_201_Closed_Text.style.display='none'; Codehighlighter1_17_201_Open_Image.style.display='inline'; Codehighlighter1_17_201_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" alt="" /><span style="color: #000000">object&nbsp;implicits&nbsp;</span><span id="Codehighlighter1_17_201_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_17_201_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img id="Codehighlighter1_59_107_Open_Image" onclick="this.style.display='none'; Codehighlighter1_59_107_Open_Text.style.display='none'; Codehighlighter1_59_107_Closed_Image.style.display='inline'; Codehighlighter1_59_107_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_59_107_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_59_107_Closed_Text.style.display='none'; Codehighlighter1_59_107_Open_Image.style.display='inline'; Codehighlighter1_59_107_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" />&nbsp;&nbsp;implicit&nbsp;&nbsp;def&nbsp;strWrapper(s&nbsp;:&nbsp;String)</span><span style="color: #000000">=</span><span id="Codehighlighter1_59_107_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_59_107_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img id="Codehighlighter1_69_103_Open_Image" onclick="this.style.display='none'; Codehighlighter1_69_103_Open_Text.style.display='none'; Codehighlighter1_69_103_Closed_Image.style.display='inline'; Codehighlighter1_69_103_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_69_103_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_69_103_Closed_Text.style.display='none'; Codehighlighter1_69_103_Open_Image.style.display='inline'; Codehighlighter1_69_103_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_69_103_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_69_103_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;wrap</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">**</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">s</span><span style="color: #000000">+</span><span style="color: #000000">"</span><span style="color: #000000">**</span><span style="color: #000000">"</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img id="Codehighlighter1_141_199_Open_Image" onclick="this.style.display='none'; Codehighlighter1_141_199_Open_Text.style.display='none'; Codehighlighter1_141_199_Closed_Image.style.display='inline'; Codehighlighter1_141_199_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_141_199_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_141_199_Closed_Text.style.display='none'; Codehighlighter1_141_199_Open_Image.style.display='inline'; Codehighlighter1_141_199_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" />&nbsp;&nbsp;def&nbsp;main(args:&nbsp;Array[String])&nbsp;</span><span id="Codehighlighter1_141_199_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_141_199_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">hello</span><span style="color: #000000">"</span><span style="color: #000000"><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;println(s.wrap)&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;**hello**</span><span style="color: #008000"><br />
</span><span style="color: #008080">11</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" alt="" />}</span></span></div>
<br />
当scala的编译器 编译 s.wrap 时，因为 String 类中没有 wrap方法，编译器会寻找代码中方法签名相同的 strWrapper(s :String),<br />
输出&nbsp; **hello**<br />
<br />
另外一种写法&nbsp;：<br />
<br />
<div style="padding-right: 5px; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left-color: #cccccc; width: 98%; word-break: break-all; padding-top: 4px; background-color: #eeeeee; "><span style="color: #008080">&nbsp;1</span><img id="Codehighlighter1_17_233_Open_Image" onclick="this.style.display='none'; Codehighlighter1_17_233_Open_Text.style.display='none'; Codehighlighter1_17_233_Closed_Image.style.display='inline'; Codehighlighter1_17_233_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_17_233_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_17_233_Closed_Text.style.display='none'; Codehighlighter1_17_233_Open_Image.style.display='inline'; Codehighlighter1_17_233_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" alt="" /><span style="color: #000000">object&nbsp;implicits&nbsp;</span><span id="Codehighlighter1_17_233_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_17_233_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img id="Codehighlighter1_50_79_Open_Image" onclick="this.style.display='none'; Codehighlighter1_50_79_Open_Text.style.display='none'; Codehighlighter1_50_79_Closed_Image.style.display='inline'; Codehighlighter1_50_79_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_50_79_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_50_79_Closed_Text.style.display='none'; Codehighlighter1_50_79_Open_Image.style.display='inline'; Codehighlighter1_50_79_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;StrWrapper(s&nbsp;:&nbsp;String)</span><span id="Codehighlighter1_50_79_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_50_79_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;wrap</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">**</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">s</span><span style="color: #000000">+</span><span style="color: #000000">"</span><span style="color: #000000">**</span><span style="color: #000000">"</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img id="Codehighlighter1_113_231_Open_Image" onclick="this.style.display='none'; Codehighlighter1_113_231_Open_Text.style.display='none'; Codehighlighter1_113_231_Closed_Image.style.display='inline'; Codehighlighter1_113_231_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_113_231_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_113_231_Closed_Text.style.display='none'; Codehighlighter1_113_231_Open_Image.style.display='inline'; Codehighlighter1_113_231_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" />&nbsp;&nbsp;def&nbsp;main(args:&nbsp;Array[String])&nbsp;</span><span id="Codehighlighter1_113_231_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_113_231_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;implicit&nbsp;def&nbsp;wrapper(s&nbsp;:String)</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;StrWrapper(s)<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">hello</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;println(s.wrap)&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;print&nbsp;**hello**</span><span style="color: #008000"><br />
</span><span style="color: #008080">10</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" alt="" />}</span></span></div>
<img src ="http://www.blogjava.net/ghost/aggbug/307049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ghost/" target="_blank">冯雪松</a> 2009-12-23 17:17 <a href="http://www.blogjava.net/ghost/archive/2009/12/23/307049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>