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. 解决RecyclerView无法onItemClick问题

    供RecyclerView采用.会员可以查看将替代ListView的RecyclerView 的使用(一),单单从代码结构来说RecyclerView确实比ListView优化了非常多.也简化了我们编 ...

  2. linux_ubuntu 16.04 更新wifi驱动_无法链接wifi问题

    ubuntu kylin ubuntu kylin ubuntu kylin wifi 这个很好解决的,16.04 默认 没有使用wifi驱动设备,默认选择的是:不使用设备1.进入到,软件和更新 -- ...

  3. 百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法

    原文:百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法 公司的网站改版要求在一个页面显示百度地图.上面要同时显示很多标注点,标注点当然要有提示信息嘛,提 ...

  4. 在面对变化,撇开NO

    参观后转到供应商,看到自己的生产线流水线半自己的钣金生产线举措.这就是我一直想厂提高生产现场的想法,因为通常当我看到工作人员努力工作和繁忙的生产,只见废现场,线解决方式时,有点莫名的兴奋. 幸亏是一家 ...

  5. Android Intent 其中一个分析

    Intent该架构由三个区域组成: Client.正在发送此Intent的activity. Server,那是,activityManagerService.java,它是主要负责这些分布Inten ...

  6. Forms身份验证和基于Role的权限验证

    Forms身份验证和基于Role的权限验证 从Membership到SimpleMembership再到ASP.NET Identity,ASP.NET每一次更换身份验证的组件,都让我更失望.Memb ...

  7. 【SSH三大框架】Hibernate基础第六篇:多对一关联关系的映射、分析及加入、查询

    这里举样例用的是:部门与员工的关系. 一个部门能够相应多个员工,这就是非常明显的多对一关联关系. 我们须要建立两个实体类:员工(Employee).部门(Department) 员工类:Employe ...

  8. C#中四个判等函数的认识

    donet提供了四个判等函数,分别是referenceEqual,静态Equal,具体类型Equal,和==. 首先来说,object.referenceEqual和静态Equal public st ...

  9. Linux 时区变化

    1.查看当前的时区 date -R 2.改动当前时区 tzselect 之后会出来一个选项菜单,选择你想要的时区就OK了 3.替换系统时区文件 cp /usr/share/zoneinfo/XXX/Y ...

  10. Largest Rectangular Area in a Histogram

    题目地址:https://oj.leetcode.com/problems/largest-rectangle-in-histogram/ ,刚開始事实上没做这个题,而是在做https://oj.le ...