月度归档:2013年10月

scala类型系统:18) 不稳定(volatile)类型

volatile type,中文称为不稳定类型或易变类型,指编译器不能确定其成员不会发生改变的类型(一个例子是在一个抽象类中定义了一个抽象的类型),在scala语言规范里描述有4种情况可能满足:

1 对于复合类型

`T1 with ... Tn {R} `若该复合类型满足下面情况之一,即为不稳定类型

1.1 `T2,...,Tn` 中有一个类型参数或抽象类型
1.2  T1 是一个抽象类型,并且 R 或 Tj(j>1) 提供了一个抽象成员
1.3  `T1,...,Tn` 中有一个是单例类型

2 对于type designator(类型标识符,比如用class或type关键字定义的类型)

A type designator is volatile if it is an alias of a volatile type, or if it designates a type parameter or abstract type that has a volatile type as its upper bound.

3 对于单例类型

A singleton type p.type is volatile, if the underlying type of path p is volatile.

4 对于存在类型

 如果`T`是不稳定类型,则 `T forSome { Q }` 也是不稳定类型

2012年的海南环岛,第六天

2012.1.30 第6天,詹州到海口 距离137公里。路线图如下:

早上在马路对面的KFC吃的早餐,今天是最后一段路程了,计划中午到达福山镇,在那儿吃午饭。

各自按照自己的节奏骑行,出儋州的时候,仍有一段的起伏路程,但到海口方向整体上是下坡较多,所以我骑的较快一些。毛毛雨依然继续下着,这一天上午,我没有碰到一个骑行者,路上有一些运送甘蔗的车。路上的细雨让我很舒适,思绪发散的想着各种问题,人生、近期的生活、家庭、工作、朋友。。。

昨天在快到儋州市区的时候,是一段下坡,阴天傍晚时分路上已经有些暗了,几公里外城市的轮廓越来越清晰,脑中一直想的一个问题是自己在四十岁时是一种怎样的生活状态,是否与自己期望的所相符

连续的骑行了60公里没有停歇,在一个小镇买了瓶矿泉水,等了luchang几分钟仍未看到,继续往前骑行。到福山镇的时候,我在一个小馆子前面停留下来,等了会儿luchang到后,点了几个菜,吃了午饭。要主食的时候服务员特别问了我们是要米饭还是鸡油饭,价格一样,我们要了鸡油饭,感觉还不错。

从福山继续往海口骑行,途经澄迈,在某个岔路口看到路牌上写着“宋代美榔双塔12KM”,之前对这个景区好像也有听说,瞬间闪现了想去的念头,但考虑时间上往返可能要花将近2个小时,本身也并不是在计划中的,坚定按原计划执行,回想在生活和工作中,这样“误入”岔路的事情实在不少,最终延误了主要目标。

骑到老城的时候,看到路牌上写着“海口25km“,瞬时开始松懈了,这种松懈使得骑行的速度大大减慢,在后边接近市区的过程中,路上的车越来越多,灰尘也越来越大,这种城市外围区域一向都是骑车过程中最不舒服的

在到南海大道与秀英大道交汇的路口,我与luchang分离,这次有缘与luchang共同环岛骑行,很愉快。他在路上向我介绍了很多骑行者的故事,四川的一些路线,以及川藏线有关的一些奇人奇事。他还有很多条骑行的路线,但将川藏线保留着,打算在他40岁的时候再去走这条线,因为走过了这条线,其他的路线都将失色不少。他曾在西藏参与过工程项目,在进入拉萨前的米拉山口,上面的电力铁塔都是他们架设的。我想如果有一天我经过米拉山口,会留意一下上面的铁塔,想起这个哥们。

回到市区口,天色还没有黑下来,我打算到海口北边的岛上去逛逛,之前曾考虑过预订那个岛上的青年旅馆。打算走世纪大桥,不想到大桥下面,发现并没有行人和自行车过去方式,桥下看守的老头和我聊了几句,说岛上没有什么好看的。问我环岛有没有走文昌,文昌近些年的变化较大。我很遗憾没有去看看。

后需沿着滨海大道往市中心走,准备去还车,在人民桥附近,我停留了一下查看地图,天色已黑,路灯已亮起来了。突然后边有人问我:你也是去找青旅的吧? 回头看是两个骑着折叠车,拖着包的小情侣。我们聊了几句,他们刚开始环岛,预订了北边岛上的青旅(海口巴纳纳国际青年旅舍),问我是否同去,我说我已经环岛回来,明早的飞机,就在市区住了,方便明早去机场。

继续骑车经过博爱路去海府路,博爱路是一条很有意思的老街,建筑也是一些老房子,街上安静,有个卖废旧书籍的。往前也有大排档,很多人,在桌子上摆个小的煤炉上面有个很大的锅,就是我们煮饭的锅,里面炖着一锅不知所谓的东西。这条街经过时确实蛮有趣的。

咨询了几个旅馆,最后还是回到第一天在海口住的如家,今天价格已经比较便宜了。用会员卡只需120不到,到龙昆南路租车的地方还了车后,步行回去,路上看到”伏波庙”,我出发的那天看到祠前有人在烧香,当时不知到这所祠堂,进去逛了逛,里面有些人围在几张方桌上打麻将,墙上有关于两位伏波将军的介绍。了解了一下他们的故事后便出去,在出的时候,突然看到庙门上的画像,两个门神很像关羽和张飞,双手都持有长刀和锏,昏暗的灯光下面目狰狞。

回到旅馆后,在前台预订了明天早上6点的出租车和叫醒电话。第二天早上按时起来退房,出租车已在外边等着,到美兰机场很快,大约半个小时就到了,不想6:30的美兰机场正是人多的时候,此时正是返程高峰。在机场的商店里买了两盒海南的食品带给同事,后又去免税店逛了下,买了一瓶香水给sally。当天天气较好,前两天还受大雾影响,飞机基本是按时起飞的,到达上海时已经中午11:30左右,从浦东机场做地铁到虹桥火车站,买了下午3点回杭州的高铁。

2012年的海南环岛,第五天

2012.1.29 第5天,东方到儋州 距离125公里。路线图如下:

早上在路边的米粉店吃的早餐。车带的气有些少了,打了些气。今天的路线将是一路的起伏,我们已有所准备,预期中午时到达邦溪镇,在那儿吃午饭。

一路上果然是不断上坡下坡,不过都是柏油马路,感觉上还好。节奏放慢些并不很累。不过在路上,看到了一起事故,一辆装满玉米的小货车侧翻了,透过车窗看到里面有个带着斗笠,披着头巾的女人在哭。交警在一边疏导说120一会儿就来了,没有忍心看里面是否还有其他人,为之一阵难过。

这一天全部路段都差不多是上坡下坡,中间有一段是较差的水泥路,蹬起来明显吃力不少,好在这段水泥路并不太长,大约1,2个小时的样子。感觉累的时候,我索性放慢节奏,留意路边的景色,停下来拍几张照片,这一段路有些景色还真不错

爬上一个坡后到达加油站,它的对面是个小卖部,我继续喝了瓶冰镇可乐,这段水泥路之后,又恢复了柏油马路。中午在小镇的菜市场里找到一家买米粉的,吃了两大碗,买了些水,继续上路。

经过的一片橡胶林。

途中还经过华南热带农业大学,位于快到儋州市区的地方。到达儋州市区后,我们在市区中兴大街上找的一家旅馆,好像是叫“韶山冲”,它也有个同名的餐馆。

晚上并不怎么困,看了电视里播放的澳网决赛,那是一场很精彩的对决,艰难的拉锯战。后续又看了CCTV6播放的《冷山》,冷山第一次观看时是04年时和同学一起在电影院,影院里的音箱效果很好,片子开头时陨石坑战役中的爆炸声让我印象深刻。CCTV这次播放的是中文配音,让女主角说话略显做作。

2012年的海南环岛,第四天

2012.1.28 第4天 崖城到东方 距离128公里。路线图如下:

早晨仍在昨晚去的那家四川饭馆吃的早餐,有包子,油条,馄饨等。我们预期是中午到达差不多在中点位置的“尖峰镇”,在那儿吃午饭。

出发后一个多小时,luchang在前边发现一个小路下去就是海边,我们过去,在沙滩边遇到了2个扎帐篷的

男孩是山西人,从深圳骑车过来,终点是三亚。女孩是从广州骑车过来的,他们在开口相遇然后同行的。从他们口中了解到了西线路况还不错,詹州一段的连续起伏的路况他并未特别突出,只是提到当地民风彪悍,让我们多加小心。

与他们告别后,我们开始了持续骑行,到达黄流镇的时候,我们停下来,喝了瓶冰镇可乐。西线的路上确实与东线有些差异,民风更原始一些,有些小镇的人们就在路边的茶馆喝茶,还有的人家盖的二层楼披着我不认识的漂亮的花儿。镇子与镇子间的距离似乎也更大一些,我们直到板桥镇才吃午饭,仍是在路边的米粉店,要了两大分炒粉,又喝了一瓶冰镇可乐。这段时间我对冰镇可乐的需求比以往任何时候都大。

从板桥镇出发的时候,也大概是2点左右,没有找到休息的场所,经过过一个学校,但不想回头继续往前走,在大概G225国道288.8km的路标处,我们看到一排风车,luchang建议我们过去看看,那儿应该是片海。

我们过去,绕了一些路,经过一片玉米地

后边是一片非常安静的海,完全未开放的

后续在路上luchang很想把这片风景分享给其他的骑行者,但并非每个骑行者都很热情,我们在这片海边花的时间有点多,后续路上加快了一些,希望能赶在东方(港口)时拍到日落

经过很多个小镇,但感恩城这个小镇我一定会记得。

路上还看到几个士兵,背着枪,在跑步,我以为是拉练,但并未见到更多士兵。当我们感到东方市的时候,大约6点一刻,太阳还没落下去,路边的小贩告诉我们去往海边最近的路被堵住了,正在修路,去海边的话要再多骑10多分钟,luchang有些放弃了,他认为市区内车多,不放便赶过去。我当时也已经能量耗尽,又渴又饿,急需补充,没有坚持去,这也成了我们的一个遗憾。

在路边小贩那儿买了一点零食,然后去找旅馆,找到了一家“假日阳光”旅馆,98元,有热水和网络。晚上在一家江西老表的小饭馆里吃的,点了几个菜都有点辣,喝了点啤酒。

2012年的海南环岛,第三天

2012.1.27 第3天,陵水到崖城 距离115公里。路线图如下:

在陵水住那天晚上睡眠不太好,晚上被蚊子骚扰,luchang下去要了蚊香结果烧到一小半就灭了。早上5点的时候,我干脆起来开灯,坐在床上看书,我带着《在路上》这本书,计划在这次旅程中将它看完。在骑行的前几天每天晚上睡觉前,会做两件事,一是准备好第二天路线,二是看一会儿小说。

从5点钟看到6点钟,看了一个小时,又开始困了,再躺下去睡了一个小时。《在路上》我断断续续的看了三分之一,始终没有“入戏”,这天清晨,我决定放弃。或许有机会去美国旅行的时候,我会再看看这本书。

早晨退了房之后,我们在车站边上的包子铺吃的早餐。今天中午预期目标是到达三亚,在那儿吃饭。上路后不久,骑了约20公里很破烂的路,速度较慢,到了英州之后路况好转,速度也快了起来。在路上,我们又碰到昨天遇到的几个人,他们车队中有人车出了问题正在修理,和那个领队打了个招呼我继续骑过去了,我有些纳闷,他们昨天不是到兴隆么,怎么现在又到我们前边了。

在往前骑了一会儿,碰到他们中的一个小姑娘,打了个招呼继续往前走了。大约11点的时候,路边又看到了一个西瓜摊,有几个骑车的人在吃西瓜,luchang喊道停下来吃个西瓜。我们便在那儿停留了一下,卖西瓜的老板当时没在,那几个骑车的人是一家子,老爸带着7岁大的儿子来环岛,他们计划用15天时间。

在我们吃西瓜的时候,后边团队中的那个小姑娘赶了过来,一问才知道他们昨天遇到我们后,也改了路程,本是到兴隆的,但当时天色尚早,征得她没有问题后(他们团队的速度取决于她)便也感到了陵水,今天轻松一些。后续有过了会儿,他们团队的人都赶到了,不过他们并没有准备吃西瓜,准备继续走。后来的路上与他们团队中也来自杭州的姑娘聊了几句,了解到她环岛完之后还要去香港参加2.1号的马拉松,全程的。她一年要参加4,5次马拉松,基本都全程,很让我佩服。

在下一座山坡爬坡过之后,我们超过了他们团队,就再没有相遇过了。中午我们到达三亚,路边歇息了一会儿我觉得肚子有些不舒服,就地方便了一下。结束了223国道的全程路段后,骑到三亚的解放路,切换到了225国道上。当时已经下午1点半左右,在解放路汽车站旁边的一家兰州拉面馆里吃了份炒面,喝了一罐冰镇饮料,继续上路。

从三亚去往天涯的路上,看到很多穆斯林女人,包着头巾,在路边卖一些东西。当时正是下午2点,太阳最毒的时候。骑到天涯海角景区的时候,我们在景区的门口留了个照,没有停留继续赶路,那时正是游客较多的时候,我印象中2003年夏天的时候,我们在景区买票,似乎也没有几个人。

那一年我也是独自一人来海南旅行,同样碰到一个独自旅行的人跟我搭伴(一个刚参加完高考的学生),当时我们在天涯海角的石头前,让别人用拍立得给我照了张合影。然后在景区内被卖东西的阿姨死缠着买了一只手镯,说是用乌龟壳做的,有辟邪的功能,她用一碗水演示,当手镯靠近碗里的水面时,水星会被弹开。那个时候人好像真的不多,我在那儿安静的写了封信,寄给了某人。回忆起来真是有趣。。。

可能是天气太热的缘故,脑子有些涨,在天涯镇,我停了下来,先是灌了一瓶冰镇可乐,随后仍决定歇息一下,避开这个时候的太阳,遂进到了天涯镇的一个小学校里,在树荫下休息了半个小时

再次出发时,我们隐约能够从路旁的防护林里看到海,很宁静。下午5点到达崖城,在进入崖城的一小段路正在修路,比较难走,在崖城我们还碰到一个来自深圳的小伙子,大约30多岁,和他的妈妈一起去买菜回来,我当时正在用ipad看地图,他们问我们从哪里骑过来,聊了几句。他们是在崖城买的房子,买的时候稍贵7200每平米,他说深圳的空气太差,春节他们就在这边度过。

经过崖城大桥后,河堤路上是一篇旅馆区域,我们在那儿选择了一家住家,旅馆的名字叫“琼缘”旅馆,60块钱,有热水,没网络,还算干净。老板住在5层,2-4层用来做旅馆,6层可以凉衣服,上面还有一个很大的发电机。后来在夜里,还真停了一阵子的电,发电机嗡嗡的工作起来。

在旅馆里放好东西后,准备去外边吃东西,带着相机,不想在楼上还看的到落日,等我们跑到崖城大桥上的时候却已被不远处的建筑遮挡住了

在河堤边的大排档问了一下价格,也有鸽粥,100元一锅,没有小分,我看了一眼笼子里的鸽子没有忍心。其他的炒菜询问了下也不大便宜,便继续找饭馆。在拐角处有家四川饭馆,进去服务员说今天所有的菜价要加25%,因为是市场上的价格涨了,看了菜单价格也还可以,便点了几个菜要了2瓶啤酒。饭还没有吃完的时候,饭馆里停电了,出去一看,是整个小镇都停电了,从luchang那儿了解到海南的电网是个孤立的系统。不过当地人都已习惯,并早有准备,过了一会儿饭馆里的发电机开始发电。

晚上把衣服凉在天台,点了蚊香,没有遭到蚊子的骚扰,持续几天没有很好的休息后,终于睡了一个安稳觉。

2012年的海南环岛,第二天

2012.1.26 第2天,琼海到陵水 距离130公里。路线图如下:

我们制定的计划是中午到达万宁市区吃饭,万宁大约在今天骑行路线的一半过去一点点的位置。早晨出发前吃了一些昨天买的面包,然后骑车没多就,就在路边看到了红色娘子军的雕塑。马路对面是一家麦当劳,我们在麦当劳里吃过早餐再继续上路。

上午依然下着毛毛雨,开始我外边还穿着一件冲锋衣,后觉得热,就脱掉了,只穿了一件衬衣;雨并没有把衣服完全弄湿,但眼镜需要时不时擦一下的。今天这一路开始陆续遇到其他一些骑车的人,大部分相遇的是和我们反方向的。也有在我们前边被我们追赶上的。或我们休息时被后边骑行者追上,都会打个招呼,有时也聊几句。


路上的风景,前边几天照相比较少。

在到达万宁市区的时候,经过一家肯德基,里面人太多,就换到了一家炒粉店,要了两大盘炒粉。在万宁我看到路边摆摊的有买一种外观比柠檬小,比枣大的青色植物;不知到这个是什么,卖东西的人问我:要槟榔么?我才反应过来这东西就是槟榔,我曾在湖南时吃过,不过是加工过的,味道很不习惯。

下午在路上开始遇到了一些爬坡,我前面有个人,帽沿很大,显然是为了遮挡阳光,每当上坡骑不动的时候就下车推行,我在一个小坡上超过了他。后来遇到一个较大的坡,持续1公里的上山路,在中途我也不得不下来,推着自行车走,中到中间的时候,停下来在路边的水渠里洗了把脸,此时我已经体会到这边的太阳很强烈了。将车推到山顶之后,luchang在那儿等我,还有其他几个骑车的人也在那儿休息,他跟他们聊天,然后我们开始下坡,在经历艰辛的付出之后,迎来了巨大的愉悦。

下山的过程我一路狂奔,也就是在翻越了那座山之后,我开始闻到路边一股烂西瓜的味道,但怎么也找不到西瓜地,后来我猜测这股腐烂的味道应该是路旁自然掉落的椰子,我看到了一些腐烂的椰子,味道就像腐烂的西瓜一样。后来两天在岛的南部,只要路边有椰树,都会闻到这股味道。

下午我们大约快到兴隆的时候,在路边休息喝水。后边陆续有一些骑车的人也赶上了我们,大家聊了几句。他们是一个队伍,约有5人,有几个人也是从杭州过来的。其中的一个女孩问luchang,是否你是从重庆来的,路长说不是,是从成都;女孩说他有个网友跟他们提起有个朋友也是一个人环岛,那个网友叫”tiao”;luchang说,正是正是。tiao是他当年去骑青海湖时遇到的,他先去骑的,tiao后来到的时候向他咨询的情况。

那五个人计划是当天到达兴隆,就在前边不远的地方,今天已经是他们环岛的第7天,他们是从三亚开始先走西线然后经过海口再走东线,最后回到三亚。一共计划用8天时间,不过他们经过了文昌,路线上比我们稍长一点。一听我们计划用6天时间,询问我们的计划,听完我们每天的安排,他们的领队说没问题的,你们这个比较紧凑,很合适。同时他们给了我们一些西线的信息,詹州一段路况不断的起伏,比起东线要费力。随后我们各自前行,他们在后边到一个小镇被我们超过。

我们从兴隆继续骑了30公里左右到达陵水。在到达市区前,在路边的西瓜摊上买了2个西瓜吃。到达陵水市区时,遇到了另外几波骑行者,他们也是路上相遇然后结伴一起走的,有几个是带了帐篷这几天有时候睡帐篷,有时候睡旅馆。

也许是接近三亚的缘故,陵水的旅馆价格都普遍偏高,大多是200以上,我们在汽车站附近找到了比较便宜的,明珠宾馆,120元应该是附近最便宜的旅馆了,有热水,没有网络(海南的旅馆普遍没有网络,即使200元以上的),上面的环境比较差,地板没有打扫干净,之前客人的烟头在垃圾桶里也没有倒掉。我们在这里凑合了一个晚上。

晚上我们在附近的大排档吃的,有一家“老牌鸽粥”,只做粥,有两种:鸽子粥和螃蟹粥,我们点了一份小锅的螃蟹粥,luchang又从别的地方买了些文昌鸡,点了2瓶力加啤酒。螃蟹粥感觉还不错。

2012年的海南环岛,第一天

2012年的春节,用了6天时间骑自行车绕了海南岛一圈,这些日志是当时写的(未公开),现在放在这里,希望对一些骑行爱好者有用。当时因时间有限,没有沿着海岸线,总距离约750公里。平均每天120-130公里。以国道为主,东线G223,西线G255,全程没有上高速。

2012.1.25 第一天,海口到琼海,距离将近120公里。路线图如下:

早上7点被闹铃吵醒,睡的不太好,这一层有个ktv,昨晚有人唱歌到凌晨2点,隔音效果一般,受了些影响。起来后出去到附近的麦当劳吃了早餐,外边下着毛毛细雨,影响不大。然后推车下来退房,结算时了解到海南的旅馆要额外收2块钱的税,与其他省份不同。

推车出来后外边雨似乎大了一点,披上了雨披,开始出发。走到海府立交桥的时候,自行车道与骑车道分离,我问了一下路,我原本的路线是“海府路”->”新大洲大道”->“南渡江第一大桥”->“灵山”,但清洁工阿姨热心的将我因上了琼州大桥,说去年她也在这里碰到一个女孩子一个人环岛,也问她路,就是那个方向的。我说我不走琼州大桥而走南渡江大桥,她说琼州大桥也叫南渡江大桥(实际上两个大桥相差还有几公里呢),正是这个错误的说法让我按照了她的路线去走。不过虽然她改变了我的计划路线,但也是一样可以到达灵山镇的。实际出海口时走的路线如下:

走这条路线也是某种缘分,因为在过了琼州大桥后不久,遇到了另一个独自骑车的家伙;他本来准备环半岛,用五天时间,绕着海边的大圈走,了解了我的计划后,他改变了主意决定跟我一起环全岛。这样我从第一天就多了一个搭档,一聊起来,大家是同一年毕业的,也是同龄人。他来自四川,在电力系统工作。以前也骑过一些路线,黄龙,九寨沟,乌江,青海湖等。这个哥们儿叫严路长,是一个自行车爱好者。

我们在到达灵山之前,未上223国道时,路线与我事先准备的路线没有吻合,路上询问了一些人路线,当地人大多并不清楚什么国道,后来碰到一个骑电动车的大伯,说跟我走吧,我也去那个方向。我们路上跟大伯聊了几句,他讲到他在文化大革命的时候,曾骑车去过广东,车子骑到那边就坏了。他有个侄子在北京外国语学院念书,环岛自行车赛的时候还取得过41名的成绩。

跟随这位大伯走了一段后,我们上了223国道,此时比较有数了,后续一路都是沿着国道走,不再担心走叉路的情况。这一段的国道并不理想,是水泥路而非柏油路,加上有一个多月没骑车了,开始还没有进入状态,尽管下雨脑袋上不断冒汗骑起来费力不少,至少比我们走杭州到苏州的路要吃力很多。心里有些担心,想这一路不会一直这样吧。

中午在三门坡(一个小镇)吃的饭,此时骑了约50公里,点了两大碗的米粉加个鸡蛋,10元一碗。补充过能量后再上路时,好受一些。骑到蓬莱镇时,终于进入了柏油马路,瞬时感觉轻松很多。

下午连续骑行了30多公里,才停下来休息喝水,然后又骑10多公里,到达“大路镇”的时候,心里有底了。

骑行至第一个100公里处:

快到达琼海市区时,先看到了一排平地起的高楼,知道马上就要到了,因为不会有那个小镇会盖这样的高楼。大约下午4点半时到达琼海市区。在市区中心找了一个比较便宜的旅馆,100元,有热水,没网络,房间还算干净。晚上在街边的大排档吃的,喝了当地的力加啤酒。

总体感觉,这一天感觉是最累的,即使后边在詹州的那一段路程起伏较多也没有第一天感觉累。度过第一天后,身体也进入了状态,后边越来越轻松了。

scala雾中风景(7): val x:Int = x + 1 的问题

前些天在scala中国的QQ群里,看到有人问为什么scala允许这样定义一个变量:

val x:Int = x + 1

这种在java里不允许,因为java里初始化一个变量(赋值)时不允许引用自身。java同样不允许下面的形式:

public class A {
    int x = y + 1;  //java中不行
    int y = 2;
}

必须把y定义在x前面,才可以在x初始化时使用y。而scala里可以:

scala> class A { 
            val x = y + 1 //scala里可以
            val y = 2 
       }

编译时只是给出警告,但会通过,运行也通过,只是x结果可能不符合你的预期;-)。

我们看一下为什么scala里会允许这种直觉上不合理的方式。看看scala在定义了一个val变量时,是怎样转成java字节码的

class A  {
  val x:Int =  1
  println(x) //看看访问x变量会被翻译成什么
}

对上面的代码通过 scalac -Xprint:jvm 可以看到:

class A extends Object {

    private[this] val x: Int = _;
    <stable> <accessor> def x(): Int = A.this.x;

    def <init>(): A = {
        A.super.<init>();
        A.this.x = 1;
        scala.this.Predef.println(scala.Int.box(A.this.x())); //调用的是x()方法而不是x变量
        ()
    }
}

它除了定义了一个 Int 类型的x变量,还定义了一个同名的 x() 方法,并且在其他地方访问x变量时实际都是调用的x()方法,它很像C#里的“属性”,C#里访问一个属性,都是调用的它的get方法。

所以scala里访问变量时,都是访问其同名的get方法;另参考这篇:scala中的无参方法与统一访问原则

现在清楚了,val x = y + 1 里面的y实际上是调用的 y()方法,val x:Int = x + 1 也是同理。不过这里面还有初始化的问题,scala的初始化比java的花样多一些,比如一个类在混入trait时的初始化顺序,以及引入了early definition的情况;后边再单独说。

scala类型系统:17) 结构类型的细节问题

这次聚会中分享的《scala类型系统》中,对于结构类型,有一页中有错误,纠正一下。

这页ppt中,上面一行代码中的 {val name:String} 是结构类型,但下面一行中{val name="wang"}在这种情况下并不是结构类型,而是Early definition

我们看一下scala规范里对Early definition的定义:

{   val p1:T1 =e1 
    ...
    val pn: Tn = en
} with sc with mt1 with mtn {stats}

在这种情况下,大括号这部分并不是结构类型,只是相当于把部分成员在父类初始化之前提前初始化而已。大括号后边的sc 是指父类构造器。

然后再说说对结构类型的理解,还是那页ppt里的例子:

trait T extends { val name:String } 

等价于

trait T extends AnyRef { val name:String } 

在scala语言规范描述复合类型(compound type)时,也说到:

A compound type may also consist of just a refinement {R } with no preceding component types. Such a type is equivalent to AnyRef{R }.

复合类型可以只是 {refinement} 部分,前边可以不要其他 component type,它等价于 AnyRef{refinement} ,这么看结构类型算是复合类型的一个特例。

在scala语言规范里,也没有专门定义“结构类型”的章节,只是在2.6版本修订时,提到可以声明结构类型:

Changes in Version 2.6 (27-July-2007) It is now possible to declare structural types using type refinements (§3.2.7).

结构类型中的”structural“这个词也是来自规范对compound type描述时:{refinement} 部分如果包含声明或类型定义(没有覆盖其他component type),则说这部分的声明或定义是“结构化的”。

A compound type T1 with . . . with Tn {R } represents objects with members as given in the component types T1, ..., Tn and the refinement {R }. A refinement {R } contains declarations and type definitions. If a declaration or definition overrides a declaration or definition in one of the component types T1, …, Tn, the usual rules for overriding apply; otherwise the declaration or definition is said to be “structural”.

另外对于结构类型中的类型参数,还有一个约束,看下面的例子:

scala> def f( p: {def id[T](i:T) } ) { 
            //donothing
        }
f: (p: AnyRef{def id[T](i: T): Unit})Unit

上面f函数的参数p 是一个结构类型,它内部声明了一个方法id,该方法带有类型参数。如果类型参数是在结构类型自己的上下文定义的(上面的情况),编译和运行都没有问题:

scala> f( new { def id[String](i:String)=print(i) })
//运行ok

但如果结构类型中声明的方法需要外部的类型参数,比如:

scala> def f[T]( p: {def id(i:T) } ) { 
            //donothing
        }
<console>:7: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement

编译时会有错误,提示不能使用定义在外部的抽象类型。但是对于返回值使用外部的类型参数却没有问题:

scala> def f[T]( p: {def id():T } ) { 
            //donothing
        }
        //编译ok f: [T](p: AnyRef{def id(): T})Unit

这个原因是scala在jvm上实现,受限于jvm运行时采取的类型擦拭,结构类型背后通过反射来执行的,丢失了类型信息所致。细节解释可以参考:这里

2013华东scala爱好者聚会(杭州)

上周六下午在西溪园区组织了一次华东地区scala爱好者交流,上海也来了6,7个人,总共有6个分享,议题如下。

《scala类型系统》
《类型驱动的函数式编程》
《actor与akka》
《spray初探》
《spark:基于Scala的大数据处理》
《sbt made simple》

这次参与的大约30人,杭州几家使用scala开发的都来了,就是时间上有点挤,没留足交流的时间。
所有PPT都已上传到:https://github.com/CSUG/csug/tree/master/slide/2013_10_19_scala_meetup