|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
我以前很喜欢Serv-U,自从它用net网页编程重写之后我就再也没用过,实在是太慢了,我宁可用IIS搭建FTP,虽然IIS搭建FTP在权限管理上很不灵活。系列文章索引:《超出F#基本》
我关于F#的先容性书本“F#基本”已于2007年5月出书了。在书中一切例子所利用的这些中心语法,我们但愿未来城市坚持稳定。但是,F#作为一个来自研讨院的言语,我们一般会看到在一个3到6个月的公布周期里的新版本会带来一些新特征,关于这些新特征我们在本书中并没有触及到。
这篇文章是对举动形式这个特征的具体会商,F#已具有相称壮大的形式婚配才能。
F#是甚么?
F#是一个针对.NET框架的静态范例化函数式编程言语。它具有OCaml罕见的中心言语功效,和其他盛行的函数式编程言语的一些特征,并从良多其他编程言语猎取了一些头脑,包含Haskell、Erlang和C#。简而言之,这意味着F#是一个具有文雅语法的编程言语,当我们能交互式地实行代码的时分感到有点像剧本编程,可是它都是范例平安且有着优秀功能的编译言语。这篇文章不是F#的先容文章,不外收集上有良多资本可让我们简单地进修F#。能够参阅本文前面的一个“F#资本”列表。
形式婚配
为了了解本文解说举动形式的念头,我们必要起首了解F#中的形式婚配。年夜部分言语在某种水平上都撑持形式婚配,在C作风的言语(C、C++、java和C#)中是经由过程“switch”体现的,以是说F#中的形式婚配就像这些言语的“switch”语句。上面让我们来看一个形式婚配的复杂例子:- letintToStringx=matchxwith|1->"One"|2->"Two"|3->"Three"|x->Printf.sprintf"Bignumber:%i"x
复制代码 在这里我们界说了一个函数来猎取一个整数参数x并转换为字符串,就是把1转换为“One”,诸云云类。固然婚配一个整数值不是那末让人冲动,可是但愿你能够看到我们编写的代码是幽美恬逸的。抛开F#形式婚配的壮大功效来看,所谓的美学就是你可以婚配一系列变更的值和范例。以是正如可以婚配良多值一样,我们也可以婚配良多对象范例,如:整数、浮点数和字符串。- openSystemlettypeToStringx=matchboxxwith|:?Int32->"Int32"|:?Double->"Double"|:?String->"String"|_->"Other"
复制代码 形式婚配的别的一个有效的特征是同意你婚配F#的团结范例。F#的团结范例是指一个能流动保留在分歧布局中数值;它们一般用于树形模子如许的数据布局,以是我们在这里演示了一个代表二叉树的团结范例:- typeBinaryTree<"a>=|Leafof"a|NodeofBinaryTree<"a>*BinaryTree<"a>
复制代码 这个数据布局既能用于叶子也能用于节点;一个节点由其他两个二叉树数据布局构成,一个叶子包括一个值,这个值在此例子中具有一个泛型范例,以便让这个树中的一切叶子上的值都具有一样的数据范例。这类树形范例的事情体例就是一种形式婚配,上面我们演示一个很复杂的函数来打印出在这个树中的一切值:- letrecprintBinaryTreeValuest=matchtwith|Leafx->printfn"%i"x|Node(l,r)->printBinaryTreeValueslprintBinaryTreeValuesr
复制代码 在这个例子中必要注重的主要事变是这类体例的形式婚配同意我们处置两种情形,这个值假如是叶子那末我们打印这个值,假如是节点我们则递回挪用这个函数来搜刮树的子节点。上面这个举行了渺小增强的函数,关于树如许的布局利用缩排体例打印个中的数据是个很好的创意,以下所示:- letprintBinaryTreet=letrecprintBinaryTreetindent=matchtwith|Leafx->printfn->"%sLeaf%i"indentx|Node(l,r)->printfn"%sLeftBranch"indentprintBinaryTreel(indent+"")printfn"%sRightBranch"indentprintBinaryTreer(indent+"")printBinaryTreet""printBinaryTree(Node((Node(Leaf1,Leaf2)),(Node(Leaf3,Leaf4))))
复制代码 当实行这个例子时,就能够打印出以下内容:- LeftBranchLeftBranchLeaf1RightBranchLeaf2RightBranchLeftBranchLeaf3RightBranchLeaf4
复制代码 举动形式
举动形式的头脑就是让你能把形式婚配语法用于其他数据布局。举动形式同意我们使用.NET类构建相似如许数据布局的团结范例,那末我们就可以够婚配这些数据布局。假定我们有一个xml文档,它将被很简单地婚配个中的节点,那末第一步就是使用.NET范例创立我们这个数据布局的团结范例:- let(|Node|Leaf|)(node:#System.Xml.XmlNode)=ifnode.HasChildNodesthenNode(node.Name,{forxinnode.ChildNodes->x})elseLeaf(node.InnerText)
复制代码 在这里我们看到,我们既界说了一个叶子的形式也界说了节点的形式,假如XmlNode对象具有子节点那末它就是一个节点,不然它就是一个叶子。我们如今能把事后界说的这个叶子和节点形式用于形式婚配,比方假如我们想打印出一个xml文档,能够如许:- letprintXmlnode=letrecprintXmlindentnode=matchnodewith|Leaf(text)->printfn"%s%s"indenttext|Node(name,nodes)->printfn"%s%s:"indentnamenodes|>Seq.iter(printXml(indent+""))printXml""node
复制代码 在这个例子中假如我们发明是一个叶子那末我们打印出它包括的文本,假如我们发明是一个节点那末我们打印出它的称号并接着持续打印出它的子节点。要利用这个函数,只需初始化一个xml文档并挪用我们的打印函数:- letdoc=lettemp=newSystem.Xml.XmlDocument()lettext="<fruit><apples><gannySmiths>1</gannySmiths><coxsOrangePippin>3</coxsOrangePippin></apples><organges>2</organges><bananas>4</bananas></fruit>"temp.LoadXml(text)tempprintXml(doc.DocumentElement:>System.Xml.XmlNode)
复制代码 我以为就算是如许的复杂例子也展示了一种处置xml文档的好办法。假如我们不必要节点范例的太多信息的话,这类办法在良多实在情形下会非常有效。我们能够设想下,一个扩大的xml举动形式函数库,在我们必要关于节点的更多细节时能够处置更多的节点范例。这类办法也能便利地为其他罕见的树形布局完成举动形式函数库,比方文件体系:- let(|File|Directory|)(fileSysInfo:System.IO.FileSystemInfo)=matchfileSysInfowith|:?System.IO.FileInfoasfile->File(file.Name)|:?System.IO.DirectoryInfoasdir->Directory(dir.Name,{forxindir.GetFileSystemInfos()->x})|_->assertfalse//aSystem.IO.FileSystemInfomustbeeitherafileordirectory
复制代码 可是举动形式不单单用于树形布局。别的一个有效的中央是我们能够在数据上实行分歧的查验历程。典范地,我们用户在字符串表单中输出数据时,程序员的一个事情就是把字符串数据转换为某些更成心义和便利处置的数据。一个最简单出成绩的情形就是处置工夫,由于用于暗示工夫的格局有良多种。一般我们会对我们录进的工夫数据实行多种检测体例,以找到准确的格局,但这些暗示为一系列“ifthenelse”语句的检测历程看上往很不划一和很难保护。如今我们能够用举动形式来天生一个函数库,来剖析举动形式并把形式婚配使用到得当的检测过程当中往:- openSystemlettypeToStringx=matchboxxwith|:?Int32->"Int32"|:?Double->"Double"|:?String->"String"|_->"Other"0
复制代码 这里,我们界说了3个分歧的举动形式来剖析工夫,ParseIsoDate、ParseAmericanDate和Parse3LetterMonthDate。我们在形式开端利用了一个下划线来暗示这个形式长短完全的,即形式要不找到一个工夫数据大概不克不及。这不像之前的例子中,我们能断言一个形式的实行了局,关于xml节点来讲不是节点就是叶子,我们也不同意有其他大概的情形存在。实践上,除为了不编译告诫我们必需为形式供应一个默许值以外,利用非完全形式和利用完全形式没有很年夜的分歧;同时我们还能够在一次检测过程当中供应多个非完全形式,只需他们都能处置同品种型的录进数据。我们经由过程上面的例子来形貌怎样利用这3个工夫举动形式来将一个字符串剖析成工夫:- openSystemlettypeToStringx=matchboxxwith|:?Int32->"Int32"|:?Double->"Double"|:?String->"String"|_->"Other"1
复制代码 我们的例子乐成剖析了前3个工夫,但关于最初一个利用2位数字来暗示年的工夫字符串,因为我们没有供应对应的形式,以是它没有被乐成剖析。供应一个工夫形式的函数库的这类体例,能让我们处置如许及其他良多格局的工夫,并供应给程序员一个疾速了然的体例来表述哪些工夫格局是被同意的。最初,部分举动形式经由过程参数化处置后,可让形式更好地重用。上面我们演示一个正则表达式举动形式的例子。它是参数化的,以便我们能取得一个能够处置任何我们想要的正则表达式:- openSystemlettypeToStringx=matchboxxwith|:?Int32->"Int32"|:?Double->"Double"|:?String->"String"|_->"Other"2
复制代码 当编译并实行这个例子,会显现:- openSystemlettypeToStringx=matchboxxwith|:?Int32->"Int32"|:?Double->"Double"|:?String->"String"|_->"Other"3
复制代码 具有剖析器理论履历的读者大概会注重到,这和由“lex”作风的编程工具天生的标志器是很类似的。实在,这个例子的举动和一个lex作风的标志器举动有着几个关头的分歧点;在这里,全部字符串被用于一切婚配的搜刮,而一个lex作风的标志器会从字符串的入手下手地位实行很长的婚配。但是,我信任假如一团体必要构建一个标志器并想制止因为利用其他编程工具所带来的庞大性的话,那末他能够构建一个举动形式来满意如许的需求。
总结
这篇文章是F#中形式婚配的一个疾速扫瞄,并先容了它的新举动形式的特征。我们看到了形式婚配为何是主要的,它匡助我们构建更明晰更简单保护的代码,并看到了这个头脑是怎样被举动形式举行扩大的。假如你有乐趣进修更多关于举动形式的常识,能够看看DonSyme写的这些博客文章,个中包含了一个论文的毗连,这个论文供应了关于举动形式计划的更多细节。
F#资本
在收集上有大批不休增添的F#资本,上面是一个最好资本的小总结:
- F#官方站点,能够找到编译器的最新版本和F#手册
- DonSyme,F#开辟带头人的博客,一个公布F#通告的最好中央,而且有一些关于F#各方面的漫笔
- TheHub-FS,F#的社区站点,有博客和论坛
- RobertPickering的F#教程和资本
- FlyingFrogConsultancy的F#教程和资本
走向何方?
经由在客岁增加了一些特征到F#言语和扩大函数库后,这个言语已进进一个新的阶段。固然F#的完成已具有很高的质量,但微软团队仿佛越来越有乐趣为F#供应更多的官方撑持。F#作为.NET言语生态体系的一个增值工具,仿佛更具有一个光亮的出路。别的,F#团队盘算在来岁优化编译器,以让它更优秀,并进步函数库、工具和文档的质量。
关于作者
RobertPickering是一个软件工程师和一个手艺作家。他今朝事情于LexiFi,一个富有立异的ISV,出格专注于软件剖析和处置庞大金融相干体系——如交换买卖体系和期权买卖体系。为了开辟一个准确的体例来暗示金融文件,LexiFi创始了在金融软件体系中函数式编程的使用。他的博客是:http://strangelights.com/blog。
检察英文原文:BeyondFoundationsofF#-ActivePatterns
来自:http://www.infoq.com/cn/articles/Beyond-Foundations-FSharp
说句实话,net网页编程跨平台根本就不是外行人想想的那种,一次编译,处处运行。 |
|