F#程序设计-函数式编程之Records
来源:互联网 发布:redis cluster java 编辑:程序博客网 时间:2024/05/18 03:39
当你想把数据组成一个结构化的格式,而不需要太复杂的语法时,你可以使用F#中的Record类型。Record类型与C语言的Struct类型基本一样,存储一组类型的值,通过字段的值来获取。定义一个Record类型很简单,只需要在大括号内定义系列的名称/类型就可以。要实例化一个Record,只需要提供对应的字段以及值即可,剩下的类型推断系统会根据你的输入来自动判断,比如:
> type PersonRec = {First : string; Last : string; Age : int};;
type PersonRec =
{First: string;
Last: string;
Age: int;}
> let steve = {First = "Steve"; Last="Holt"; Age=21};;
val steve : PersonRec = {First = "Steve";
Last = "Holt";
Age = 21;}
> printfn "%s is %d years old" steve.First steve.Age;;
Steve is 21 years old
val it : unit = ()
Cloning Records
利用关键字"with"可以很容易的实现记录克隆,比如上面的那个steve有一个双胞胎哥哥,可以用下面的代码来实例化他哥哥,^_^:
> let bill = {steve with First="Bill"};;
val bill : PersonRec = {First = "Bill";
Last = "Holt";
Age = 21;}
如果克隆时需要更改多个字段的值,只需要用逗号分隔开来。
Pattern Matching
Record也可用于模式匹配,使用时只需要提供Record的字段值与给定的字面值都匹配即可,不如给定一辆车,将车的型号为品牌做匹配:
> type Car = {Model : string; Color : string};;
type Car =
{Model: string;
Color: string;}
> let matchCar newCars =
- newCars
- |> List.filter
- (function
- | {Model = "Coup" } -> true
- | {Model = "BMW" } -> true
- | _ -> false);;
val matchCar : Car list -> Car list
> let cars = [{Model = "Coup" ; Color = "Red"};{Model = "Benz" ; Color = "Black"
- }];;
val cars : Car list = [{Model = "Coup";
Color = "Red";}; {Model = "Benz";
Color = "Black";}]
> matchCar cars;;
val it : Car list = [{Model = "Coup";
Color = "Red";}]
Type Inference
在F#中,类型推断系统是一个非常重要的东西,几乎所有的地方都需要用到它,现在来看看Record是在类型推断系统下工作的。在.NET中,类在使用前,必须标明它的类型,而在F#中,判断Record类型是根据Record的字段来的,就像我们上面的说,利用let绑定到一个大括号包围的数据,类型推断系统就能根据它的字段来推理出是Record。就拿下面的代码段来说,对于值pt1和pt2,没有任何地方标明它是什么类型,但是由于X和Y值被访问,并且F#编译器知道有一个Record包含有字段X和Y,自然就推断出pt1和pt2的类型了:
> type Point = {X : float; Y : float};;
type Point =
{X: float;
Y: float;}
> let distane pt1 pt2 =
- let square x = x * x
- sqrt <| square (pt1.X - pt2.X) + square (pt1.Y - pt2.Y);;
val distane : Point -> Point -> float
> distane { X = 0.0; Y = 0.0} {X = 10.0 ; Y = 10.0};;
val it : float = 14.14213562
当两个Record的具有相同的字段时,如果像上面这样写,那么类型推断系统就会发出一个错误了,因为它不知道你希望用到的是哪个类型。为了解决这个问题,你可以提供类型注释或者完整路径的字段,比如:
> type Point = {X : float; Y : float};;
type Point =
{X: float;
Y: float;}
> type Vector3 = {X : float; Y : float; Z : float};;
type Vector3 =
{X: float;
Y: float;
Z: float;}
> let distance (pt1 : Point) (pt2 : Point) =
- let square x = x * x
- sqrt <| square (pt1.X - pt2.X) + square (pt1.Y - pt2.Y);;
val distance : Point -> Point -> float
引入字段的完整路径名可以像下面这样子:
> let origin = { Point.X = 0.0; Point.Y = 0.0 };;
val origin : Point = {X = 0.0;
Y = 0.0;}
Methods and Properties
在Record中也可以增加方法和属性:
> type Vector =
- {X : float; Y : float; Z : float}
- member this.Length =
- sqrt <| this.X ** 2.0 + this.Y ** 2.0 + this.Z ** 2.0;;
type Vector =
{X: float;
Y: float;
Z: float;}
with
member Length : float
end
> let v = {X = 10.0; Y = 20.0; Z = 30.0};;
val v : Vector = {X = 10.0;
Y = 20.0;
Z = 30.0;}
> v.Length;;
val it : float = 37.41657387
- F#程序设计-函数式编程之Records
- F#程序设计-函数式编程之函数组合(Function Composition)
- F#程序设计-函数式编程之模式匹配
- F#程序设计-函数式编程之Discriminated Unions
- F#程序设计-函数式编程之惰性加载
- F#程序设计-函数式编程之值的可变性
- F#程序设计-函数式编程之用函数风格来编程(1)
- F#程序设计-函数式编程之用函数风格来编程(2)
- F#程序设计-面向对象编程之继承
- F# 函数式编程
- F#程序设计-F#语言基础之函数(1)
- F#程序设计-F#语言基础之函数(2)
- F#学习之路(1)什么是函数式编程
- 函数式编程语言F#
- F#程序设计-面向对象编程之属性和方法
- F#程序设计-面向对象编程之访问修饰符
- F#简明教程一:F#与函数式编程概述
- F#--函数式编程语言 学习过程
- 广义相对性原理的基本假设3-广义相对论的命题表述
- C# 语音识别 相关网址
- J2SE 窗体LookAndFeel 功能 更换组件的皮肤
- 理想、激情、生存——位技术管理人员的20年工作经历和感悟(1)
- 宽容别人,幸福自己
- F#程序设计-函数式编程之Records
- java Swing 程序连接SQLsever数据库方面的系列问题.
- Hibernate 笔记
- 学习...
- 记mfc父子控件通信的一般方法
- 0days最好的破解网站
- Thinkpad T43升级5K160 硬盘微码,解决2010错误的体会
- 理想、激情、生存———位技术管理人员的20年工作经历和感悟(2)
- 用commons-email-1.1.jar实现发邮件功能: