拼吾爱程序人生

首页 » .Net编程 » F# » F#学习之路(5)元组类型
cobra - 2008-8-28 22:21:00
元组类型,表示一组有序数据类型的集合。F#通过支持元组类型,方便了我们定义临时数据结构,而不需要为了临时的数据专门定义一个数据类型。

    一、元组的定义:

Code


在F#中元组使用小括号,元素之间逗号分隔来定义。元组元素可以是任何类型。

    上面代码中,tuple_2的类型是int*int,而tuple_3的类型为string*float*string。元组类型使用元组元素类型乘号连接的方式。

 

    元组类型可以作为函数的输入参数,也可以作为函数的返回值。

Code


上面函数的类型为 int*int*int->int*int*int

 

    元组类型虽然方便我们组织一组数据类型,而无需专门定义一个数据结构。但很显然他不能很好地帮助我们理解数据结构的语义,尤其是互操作时作为函数返回值的情况下。给元组类型取一个别名,能够部分缓解这个问题。

Code


二、元组类型的比较   

    在F#中元组类型可以进行比较,前提当然是同类型的元组类型。所谓同类型,是指元组的元素长度相等,元素类型相同。F#从前至后依次比较。

Code


打印的结果 为 true   

 

    三、元组与模式匹配

      模式匹配在函数式语言中经常出现,其功能强大。比命令式语言中switch强大的多。不仅可以匹配基本类型、元组类型、列表类型、记录类型,还可以用于类型检测。在F#中还允许自定义类型的模式匹配,通过活动模式(Active Pattern)可以做到这一点。

Code


元组类型不仅可以使用常用的模式匹配方法。

Code


还可以使用隐式的模式匹配方法来分解元组

Code


这种隐式的模式匹配大大方便了我们使用元组类型的分解。上面的代码使用了列表,列表将在下一篇博客中讨论。



    四、元组类型的互操作

    在学习F#函数时,我们知道F#函数的输入参数是不需要括号的。

Code


上面的代码中f1和f2的类型是不一样的。

    f1的函数类型是int->int->int->int,而f2的函数类型是int*int*int->int。

    我把f1函数称为柯里化函数风格,而把f2函数称为元组函数风格。

    之所以称f1为柯里化的函数风格,是因为f1可以进行柯里化的函数调用,可以部分地传入参数值。而f2则必须全部传入。   

    两种函数风格的适用场景是什么了?

    柯里化的函数很显然比较适合扮演高阶函数。根据我目前所理解,在不讨论互操作的情况下,元组类型风格的函数总是可以通过柯里化的函数风格代替的。在不需要互操作的情况下,应该优先使用柯里化的函数风格,因为柯里化的函数可以更好的组合,从这个角度来说,柯里化的函数风格可以很好的组合代码,而元组类型的函数风格则用来组合数据。

    为什么说在互操作场景中优先使用元组类型的函数风格?

    回答上面的问题,则要讨论一下元组类型真正的类型是什么?什么叫元组类型真正的类型呀,元组类型不就是元组类型吗?呵呵,绕起来了。

Code


上面的tuple_3元组类型是int*int*int,这是对的。但这只是表面,实质上它的真实类型是Tuple<int,int,int>,F#编译器做了手脚。Tuple类型定义了一个泛型的记录类型,它有三个元素。

Code


在F#中,一共定义了六个泛型版的元组类型。从2个元素到七个元素的元组类型。很显然,元组类型最少两个元素,最多没有限制,理论上肯定是只要内存足够就可以了。F#如何处理超过七个元素的元组类型的了。根据我的测试,发现如果超过七个元素,超过的元素将变成一个嵌套的元组的成员,依此类推。举个例子:

Code


上面的F#函数对应的c#方法签名是:

Code


注意上面的讨论是针对函数返回值的。对于函数输入参数并不适用,我们要分别讨论。

    对于函数来说,元组类型的函数风格与柯里化的函数风格,对于c#来说,并没有区别。或者说,柯时化的函数风格和元组类型的函数风格都会转化为c#方法风格。

Code


对应的c#方法签名:

Code


一个有趣的例子:

Code


上面的tuple_7和tuple_9在F#中是完全不同的类型,但对于c#来说,却是完全等效的。



    但当我们在类型上使用这两种风格的函数时就发生了变化,这种变化还很大。下面我就定义一个记录类型:

Code


我创建了一个记录类型,叫Order,并使用静态成员方法创建类型实例。

    c#签名如下:

Code


这意味着什么,这意味着当我们在F#中使用柯里化风格的函数作为公开接口时,不是c#程序员习惯的调用方式。而采用元组风格的函数与c#程序员的习惯是一致的。

    在F#中元组的存在,使得接受多值的返回值时,F#比C#处理方式漂亮的多。

Code


五、总结:

    (1) 元组类型一般用做临时数据的容器。业务数据结构应该选用记录类型或类、结构。

    (2) 当需要与其他.net语言互操作时,元组类型用做方法或函数的输入参数,有更好的兼容性,除非你的确需要柯里化的函数风格。在互操作时,元组类型不要作为函数的返回值,如果使用元组类型作为函数返回值,互操作的语言就必须引用F#的特定函数库。

    (3) 元组类型与模式匹配语法相结合,可以很好的组合、拆分。




(文/lvxuwen  出处/博客园)

 您可能对 [F#] 的这些文章也感兴趣:

F#学习资源(不断更新)
F# 1.9.4 Available Now with Important Updates
F# 之旅(七):在F#中进行单元测试
F#学习之路(6)列表
F# 20分钟快速上手(一)
F# 学习之路 (2) 深刻理解函数(下)
理解F#中的模式匹配与活动模式
F# 之旅(四):面向对象编程(中)
从C# 3.0到F#
F# 之旅(六):F#代码的组织
1
查看完整版本: F#学习之路(5)元组类型
Modify by pin5i DZNT_ExpandPackage 2.1.3258 2007-2008 pin5i.com
  Total Unique Visitors: