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. In Oracle 11g, how to change the order of the results of a sql without “order by”?(转)

    oracle 11g 当sql语句中不加order by的时候,好像是按rowid的顺序返回结果的.我也看过一些相关的文档,oracle的官方意思就是不加order by,就不保证输出的顺序. 那么, ...

  2. Codeforces 514 D R2D2 and Droid Army(RMQ+二分法)

    An army of n droids is lined up in one row. Each droid is described by m integers a1, a2, ..., am, w ...

  3. Swift_3_功能

    import Foundation println("Hello, World!") //声明函数 不带参数 无返回值 func func1(){ } //一个函数 传入两个Str ...

  4. Codeforces Round #306 (Div. 2) C

    意甲冠军 到不超过一个更100该整数字符串.采取随机从数间(不能拿). 问:是否有可能被剩下8除尽.假设能,出口YES和任选一个数字的其余病例的. 不能够,输出NO. 思路 想法题. 首先观察到.10 ...

  5. Map <STL>

    map的使用方法: #include <cstdio> #include <map> #include <string> using namespace std; ...

  6. C#精华(文章3版本)笔记

    C#精华(文章3版本) 跳转至: 导航. 搜索 文件夹 1 C#概述 2 数据类型 3 运算符和控制流 4 方法和參数 5 类 6 继承 7 接口 8 值类型(struct) 9 合式类型 10 异常 ...

  7. 栈 <stack>

    STL: pop:完成的仅仅是移除最顶端的数据.如果访问最顶端的数据,需要使用top函数(这个操作通常也被称为peek). #include <stack> #include <cs ...

  8. 网页上弹出pop窗口实例,(document).height()与$(window).height()的区别

    #dvbg{background-color:#666666; position:absolute; z-index:99; left:0; top:0; display:none; width:10 ...

  9. oracle_constraint的用处

    ql中constraint主要是增加约束 这个主要就是增加约束的 以下几种约束 .并 一一列举: 1.主键约束: 主键约束:就是对一个列进行了约束,约束为(非空.不重复)要对一个列加主键约束的话,这列 ...

  10. linux_cp_远程copy

    1:远程copy  [linux对linux 远程拷贝]   scp 文件名  root@远程ip:/路径/    将本地home目录下的test.tar的文件拷贝到远程主机192.168.1.23的 ...