Type Aliase

去掉Scala的糖衣(4) -- Type Aliase

我的新博客地址:http://cuipengfei.me/blog/2013/12/23/desugar-scala-4/

Scala中有一个type关键字,用来给类型或者是操作起别名,用起来很是方便。

比如这样:

1
type People = List[Person]

这样就是给List[Person](方括号是Scala的类型参数的写法)声明了一个别名,叫做People。

接下来就可以这样使用它:

1
2
3
  def teenagers(people: People): People = {
people.filter(person => person.age < 20)
}

这个代码编译之后没有什么神奇的,仅仅是把所有出现People这个字眼的地方都用List of Person替代了。

1
2
3
4
5
6
7
  public List<Person> teenagers(List<Person> people)
{
return (List)people.filter(new AbstractFunction1() { public static final long serialVersionUID = 0L;
public final boolean apply(Person person) { return person.age() < 20; }
});
}

这种给类型一个别名的特性只是一个小糖豆,不太甜,真正有趣的是给一类操作命名(联想C#中定义delegate)。

比如这样:

1
type PersonPredicate = Person => Boolean

接受一个Person,返回一个Boolean,我们把这一类用来判断一个人是否符合某个条件的操作统称为PersonPredicate。

然后我们可以定义以下predicate:

1
val teenagerPred: PersonPredicate = person => person.age < 20

然后前面写过的teenagers方法就可以这样重新定义:

1
2
3
  def teenagers(people: People): People = {
people.filter(teenagerPred)
}

按照这个思路下去,我们就可以开始composite functions了。比如说,我们跟人收税,就可以这么做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  type Tax = Person => Double
val incomeTax: Tax = person => person.income * 5 / 100
val kejuanzaTax: Tax = person => person.income * 20 / 100
def giveMeYourMoney(p: Person) = {
calculateTax(p, List(incomeTax, kejuanzaTax))
}
def calculateTax(person: Person, taxes: List[Tax]): Double = {
taxes.foldLeft(0d) {
(acc, curTax) => acc + curTax(person)
}
}

从一个人那里拿到钱,这种操作,我们称之为Tax。然后定义个税和苛捐杂税,或者也可以有任意多的税种。

然后就可以把任意的几个税种放在一个List里面,和calculateTax去composite了。

当然,没有type这个关键字,我们也可以composite functions。只不过就得写成这样:

1
2
val teenagerPred: (Person) => Boolean = person => person.age < 20
def incomeTax: (Person) => Double = person => person.income * 5 / 100

看着稍微有点眼花。

这种用type关键字给一种操作命名的代码反编译之后是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  public Function1<Person, Object> teenagerPred()
{
return new AbstractFunction1() { public static final long serialVersionUID = 0L;
public final boolean apply(Person person) { return person.age() < 20; } } ;
}
public Function1<Person, Object> incomeTax()
{
return new AbstractFunction1() { public static final long serialVersionUID = 0L;
public final double apply(Person person) { return person.income() * 5 / 100; } } ;
}
public Function1<Person, Object> kejuanzaTax()
{
return new AbstractFunction1() { public static final long serialVersionUID = 0L;
public final double apply(Person person) { return person.income() * 20 / 100; } } ;
}

可以看到所有这种接受一个参数,返回一个值的操作都是Function1<Person, Object>。

推测一下,接受两个参数,返回一个值的是不是该叫做Function2呢?

1
2
3
type TwoToOne = (String, Int) => Double
def twoToOneImpl: TwoToOne = (str, i) => 1

反编译之后,果不其然:

1
2
3
4
public Function2<String, Object, Object> twoToOneImpl()
{
return new Hello..anonfun.twoToOneImpl.1(this);
}

那不接收参数,只有返回值的呢?

1
2
3
  type NoInJustOut = () => String
def noInJustOutImpl: NoInJustOut = () => "hello world"

反编译之后,其实是变成了Function0 of String:

1
2
3
4
  public Function0<String> noInJustOutImpl()
{
return new Hello..anonfun.noInJustOutImpl.1(this);
}

到这里,我们可以总结一下type alia这个糖衣:

一个类型的type alias,类似于这样的:type t = x。编译器将在所有使用到t的地方把t替换为x。

对于一种操作的type alias,编译器将会根据参数列表和返回值类型的不同将其替换为对应的Function0,Function1,Function2 …… 一直到Function22。

如果我们真的定义一个超过二十二个参数的操作会如何呢?

1
2
3
4
5
6
7
8
  type twentyThree = (
String, String, String, String,
String, String, String, String,
String, String, String, String,
String, String, String, String,
String, String, String, String,
String, String, String
) => String

Scala编译器会直接告诉我们: type Function23 is not a member of package scala

【测试驱动 ASP.NET MVC】

http://msdn.microsoft.com/zh-cn/magazine/jj190803.aspx

【构建可测试 ASP.NET MVC 应用程序】

http://msdn.microsoft.com/zh-cn/magazine/dd942838.aspx

Pragmatic.Test.Drive.ASP.NET.MVC.Jun.2010

http://vdisk.weibo.com/s/DOlfks4ooGf 【图片可以点击】 

这本很薄的小书,今年读了至少4边,汤姆大叔翻译的js也看了几遍,受益匪浅

现在已经完成了60%的代码重构,因为垃圾站很简单,

虽然现在还没有深入到复杂模块和高难度模块单元测试,但普通的单元测试已经解决了我很多问题了

1 拖沓,以前写一个模块用老长时间,都是周末或平时有空写写,有时候记不起来几个月前定的需求,就一直放着,等想起来在写

现在先写完单元测试代码,明确的具体的规则,和目标,每次写之前先运行一次单元测试看哪里还没写,拖沓的毛病得到治疗。

个人感觉对创业团队更为重要:1防止拖沓 2防止赶工期出垃圾工程

2长函数,以前也不是有意写长函数,只不过写着写着写着就边长了,我也没办法,

现在写的时候先要想,我要怎么测试这个东西,复杂的东西不会测,写简单点,好测试

3成就感,,,,每次看着X号变绿色,心情都好了

测试驱动 ASP.NET MVC Type Aliase的更多相关文章

  1. 测试驱动 ASP.NET MVC 和构建可测试 ASP.NET MVC 应用程序

    [测试驱动 ASP.NET MVC] http://t.cn/8kdi4Wl [构建可测试 ASP.NET MVC 应用程序]http://t.cn/8kdi4Wj

  2. (转)ASP.NET MVC 第五个预览版和表单提交场景

    转自:http://ourlife.blog.51cto.com/708821/296171 上个星期四,ASP.NET MVC开发团队发布了ASP.NET MVC框架的“第五个预览版”.你可以在这里 ...

  3. ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库

    前段时间在园子里看到了小蝶惊鸿 发布的有关绿色版的Linux.NET——“Jws.Mono”.由于我对.Net程序跑在Linux上非常感兴趣,自己也看了一些有关mono的资料,但是一直没有时间抽出时间 ...

  4. 使用IdleTest进行TDD单元测试驱动开发演练(3) 之 ASP.NET MVC

    一.[前言] (1)本文将用到IOC框架Unity,可参照<Unity V3 初步使用 —— 为我的.NET项目从简单三层架构转到IOC做准备>(2)本文的解决方案是基于前述<使用I ...

  5. 视频教程--ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库

    说好的给园子里的朋友们录制与<ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库> 这篇博客相对应的视频,由于一个月一来没有时 ...

  6. ASP.NET MVC another entity of the same type already has the same primary key value

    ASP.NET MVC项目 Repository层中,Update.Delete总是失败 another entity of the same type already has the same pr ...

  7. 3.4 自动测试初步《精通ASP.NET MVC 5》

    概述 ASP.NET MVC 框架已被设计成易于建立自动测试,并易于采用诸如测试驱动开发(TDD)等的开发方法学.ASP.NET MVC 为自动化测试提供了一个理想平台. 从广义上讲,当今的 Web ...

  8. asp.net mvc项目使用spring.net发布到IIS后,在访问提示错误 Could not load type from string value 'DALMsSql.DBSessionFactory,DALMsSql'.

    asp.net mvc项目使用spring.net发布到IIS后,在访问提示错误 Could not load type from string value 'DALMsSql.DBSessionFa ...

  9. Cordova+Asp.net Mvc+GIS跨平台移动应用开发实战1-系统初步搭建(附演示,apk,全部源码)

    1.前言 身处在移动互联网的今天,移动应用开发炙手可热,身为程序猿的我们怎么能错过开发一款我们自己的APP.本人算是一个基于.net的GIS开发入门者(马上就大四啦), 暑假在学校参加GIS比赛有大把 ...

随机推荐

  1. NYOJ 904 search(stable_sort函数的应用)

    描述 游戏积分的排行榜出来了,小z想看看得某个积分的人是谁.但是由于人数很多,他自己找很浪费时间,所以他想请你帮忙写一个程序,能快速的帮他找到他想要找的人   输入 多组测试数据,第一行有一个数T,表 ...

  2. mysql_navicat-permium 在Mac下破解方法

    首先下载符合当前系统支持的navicat-permium版本,我自己下载的是11.0.16 然后我们开始破解旅程,先要安装上navicat-permium,记住千万不要打开(如果你打开了不好意思,卸了 ...

  3. linux_常用压缩,解压缩命令

    01-.tar格式解包:[*******]$ tar xvf FileName.tar打包:[*******]$ tar cvf FileName.tar DirName(注:tar是打包,不是压缩! ...

  4. 兼容安卓的javaproject1.0

    <pre class="java" name="code"> //兼容安卓的系统package cn.com.likeshow; import ja ...

  5. Hadoop之环境搭建

    初学Hadoop之环境搭建   阅读目录 1.安装CentOS7 2.安装JDK1.7.0 3.安装Hadoop2.6.0 4.SSH无密码登陆 本文仅作为学习笔记,供大家初学Hadoop时学习参考. ...

  6. 基于Jquery的多彩二维码的生成

    Demo效果图: 源代码: @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name=&quo ...

  7. 汉字转整数,比系统简单易用!a2iLxx (覆盖物 16十六进制,VC6亲测可用)请提供意见~

    #include "string.h" #define INVALID_VALUE_LXX ((1 << (8 * sizeof(int) -1)) - 1) /*有符 ...

  8. Xcode6为什么干掉pch(Precompile Prefix Header)&amp;怎样加入pch文件

    一直在用xcode6开发,但项目都是在xcode5上创建的,所以一直没注意到,xcode6居然干掉pch文件了. 为什么xcode6没有自己主动创建pch文件呢? 简单地看:我们在写项目的时候,大部分 ...

  9. Java设计模式之装饰者模式

    要实现装饰者模式,注意一下几点内容: 1.装饰者类要实现真实类同样的接口 2.装饰者类内有一个真实对象的引用(可以通过装饰者类的构造器传入) 3.装饰类对象在主类中接受请求,将请求发送给真实的对象(相 ...

  10. 下载的youtube视频

    youtube 视频下载方法[详解]   1.打开网址: http://kej.tw/flvretriever/. 2.输入要下载的youtube视频的网址. 3.点击右侧RETRIEVE NOW ! ...