网站开发搭建,在线平面设计软件测评,做关键词搜索的网站,用wordpress 弄面包编者#xff1a;C# 7.0也加入了模式匹配#xff0c;来源于F#。模式匹配在F#是非常普遍的#xff0c;用来对某个值进行分支匹配或流程控制。模式匹配的基本用法模式匹配通过match...with表达式来完成#xff0c;一个完整的模式表达式长下面的样子#xff1a;match [somethi… 编者C# 7.0也加入了模式匹配来源于F#。模式匹配在F#是非常普遍的用来对某个值进行分支匹配或流程控制。模式匹配的基本用法模式匹配通过match...with表达式来完成一个完整的模式表达式长下面的样子match [something] with | pattern1 - expression1| pattern2 - expression2| pattern3 - expression3当你第一次使用模式匹配你可以认为他就是命令式语言中的switch...case或者说是if...else if...else。只不过模式匹配的能力要比switch...case强大的多。考虑下面的例子let x match 1 with | 1 - a | 2 - b | _ - z显然x此时的值是a因为第一个匹配分支就匹配正确了。在这个表达式里第三个匹配分支有点特殊:| _ - z通配符_在这里起到了default的作用上面的所有分支如果都匹配失败则最终会匹配的这个分支。1.分支是有顺序的但是这三个分支的顺序是可以随便改的也就意味着我们可以把通配符分支放到第一个位置let x match 1 with | _ - z | 1 - a | 2 - b在这个例子中第一个匹配分支会胜出同时编译器也会给出一个警告:其他的分支从来都不会被用到。这说明在模式匹配中分支的顺序是非常重要的应该把更加具体的匹配分支放在前面包含通配符的分支应该放在最后面。2.模式匹配是一个表达式模式匹配是一个表达式所有的分支都应该返回同样的类型考虑下面的例子let x match 1 with | 1 - 42 | 2 - true // error wrong type | _ - hello // error wrong type不同的分支应该返回想通类型的值。3.至少有一个分支能被匹配到考虑下面的例子:let x match 42 with | 1 - a | 2 - b由于两个分支都没有匹配到编译器将会给出警告你至少要写一个能够匹配到的分支例如为其添加通配符分支。你可以通过添加通配符分支让编译器不在发出警告但是在实际实践中你应该尽可能的添加可能存在的分支例如你在对一个选择类型做模式匹配type Choices A | B | Clet x match A with | A - a | B - b | C - c如果后来某一天你在Choices类型里添加了一个新的选项D编译器就会对之前的对Choices的模式匹配发出警告提示你添加新的分支。试想如果你之前加了通配符,编译器就会吞掉这个警告进而产生bug。匹配元组(Tuple)模式匹配几乎可以匹配F#所有的类型例如元组:let y match (1,0) with | (1,x) - printfn x%A x | (_,x) - printfn other x%A x显然第一个分支会被匹配到。你可以把多个模式写在同一个分支上当多个模式是或的关系时用|隔开type Choices A | B | C | Dlet x match A with | A | B | C - a or b or c | D - d当多个模式是与的关系时用隔开:let y match (1,0) with | (2,x) (_,1) - printfn x%A x匹配list匹配list只有三种模式:[x;y;z]用来显示匹配list中的元素head::tail head会匹配到第一个元素其他的元素会匹配到tail这个模式常用来对list做递归[] 会匹配到空的listlet rec loopAndPrint aList match aList with | [] - printfn empty | x::xs - printfn element%A, x loopAndPrint xs loopAndPrint [1..5]当[]模式被匹配到说明list已经为空可以作为递归的终止条件x::xs模式会将第一个元素匹配到x中剩余的元素被匹配到xs然后xs又被当做参数做下一次递归匹配Recoard type和Descriminated Union type...//record typetype Person {First:string; Last:string}let person {Firstjohn; Lastdoe}match person with | {Firstjohn} - printfn Matched John| _ - printfn Not John//union typetype IntOrBool I of int | B of boollet intOrBool I 42match intOrBool with | I i - printfn Int%i i| B b - printfn Bool%b b其他1.as关键字你可以把模式用as关键字指向另一个名称let y match (1,0) with | (x,y) as t - printfn x%A and y%A x y printfn The whole tuple is %A t2.匹配子类:?用来匹配类型例如第一个分支用来匹配int类型:let detectType v match box v with | :? int - printfn this is an int | _ - printfn something else匹配类型并不是一种好的实践正如你在OO语言里编写if type ...一样。when条件有时候你需要对匹配完成的值做一些条件判断let elementsAreEqual aTuple match aTuple with | (x,y) - if (xy) then printfn both parts are the same else printfn both parts are different这种情况可以通过在模式中添加when条件来做到let elementsAreEqual aTuple match aTuple with | (x,y) when xy - printfn both parts are the same | _ - printfn both parts are differentActive patternwhen语句尽管可以给模式添加一些条件但是当语句过于复杂的时候可以考虑某个分支的模式定义为一个方法open System.Text.RegularExpressions// create an active pattern to match an email addresslet (|EmailAddress|_|) input let m Regex.Match(input,..) if (m.Success) then Some input else None // use the active pattern in the match let classifyString aString match aString with | EmailAddress x - printfn %s is an email x // otherwise leave alone | _ - printfn %s is something else aString//testclassifyString aliceexample.comclassifyString google.com原文地址https://www.cnblogs.com/xiandnc/p/9388259.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com