博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
F#初学笔记06
阅读量:5734 次
发布时间:2019-06-18

本文共 3841 字,大约阅读时间需要 12 分钟。

活动模式
活动模式可以使你执行一个函数,来看是否发生了匹配。这也是为什么叫活动的原因。活动模式的设计目标是允许你在程序中更好的复用模式匹配逻辑。活动模式接受一个输入参数,使用该参数执行一些计算,决定是否该匹配发生过。有2种活动模式,完全活动模式和分部活动匹配。
 
完全活动模式
定义活动模式的语法和定义函数相似。主要的不同点在于活动模式的标识符有个括号和竖线,(| |)。活动模式的主体就是一个F#函数,该函数必须为每个分支提供返回,每个case可以返回额外的数据,就如联合类型那样。如下的例子:
let(|Dayu0|Xiaoyu0|Dengyu0|) value=  if value<0 then Xiaoyu0  else if value=0 then Dengyu0  else Dayu0let test input =       match input with        | Dayu0  -> printfn ">0"         | Xiaoyu0-> printfn "<0"         | Dengyu0 -> printfn "=0"test 3test -2test 0
运行test方法的时候,test内部有类型Dayu0,Xiaoyu0,Dengyu0由于自动推断类型,因此会去活动模式中匹配。依次判断是否是某种类型。再打印出相应的值。
 
看下面的例子。
 
#lightopen System// 定义活动模式let (|Bool|Int|Float|String|) input =    // attempt to parse a bool    let success, res = Boolean.TryParse input    if success then Bool(res)    else    // attempt to parse an int    let success, res = Int32.TryParse input    if success then Int(res)    else    // attempt to parse a float (Double)    let success, res = Double.TryParse input    if success then Float(res)    else String(input)// 根据模式打印的函数// matching over the active patternlet printInputWithType input =        match input with        | Bool b -> printfn "Boolean: %b" b        | Int i -> printfn "Integer: %i" i        | Float f -> printfn "Floating point: %f" f        | String s -> printfn "String: %s" s// print the resultsprintInputWithType "true"printInputWithType "12"printInputWithType "-12.1"
上述例子的模式就是判断输入的字符串是布尔,整型,浮点型还是字符串。case名字是Bool,Int,Float和String。这个例子使用TryParse方法,轮流的判断输入的值是不是布尔,整型,浮点型,如果都不是,那么就是字符串。如果转换成功,则返回case名字和值。接下来,活动模式允许你对待string好像联合类型那样。你可以匹配每一个case,通过在强类型方式中使用活动模式恢复数据。注意红色字体的,就是活动模式定义的类型。
 
分部活动模式
分部活动模式的语法和完全活动模式类似。分部活动模式只有一个case名字。和完全活动模式不同处在于必须跟随一个|符号和一个下划线,表示是分部的。(和只有一个case 的完全活动模式区别)
 
注意,完全和分部活动模式的主要不同处在于完全活动模式保证能返回一个case,然而活动模式可能匹配失败。所以分部活动模式是option类型。option类型是简单的联合类型,已经内建在F#基类库里。只有2个case,Some和None,定义如下:
type option<'a> =| Some of 'a| None
option类型,正如名字的意思,表示值是否存在。所以分部活动模式返回Some和一些数据,表示匹配。或者None表示失败。
所有的活动模式可以带有参数。看如下的例子。
#lightopen System.Text.RegularExpressions// 定义活动模式let (|Regex|_|) regexPattern input =// 创建,匹配正则表达式    let regex = new Regex(regexPattern)    let regexMatch = regex.Match(input)// 返回 Some or None    if regexMatch.Success then        Some regexMatch.Value    else        None// function to print the results by pattern// matching over different instances of the// active patternlet printInputWithType input =    match input with    | Regex "$true|false^" s -> printfn "Boolean: %s" s    | Regex @"$-?\d+^" s -> printfn "Integer: %s" s    | Regex "$-?\d+\.\d*^" s -> printfn "Floating point: %s" s    | _ -> printfn "String: %s" input// print the resultsprintInputWithType "true"printInputWithType "12"printInputWithType "-12.1"
完全活动模式的行为正如联合类型的一样,当没有case的时候,编译器会报错,一个分部活动模式总是要求一个最终的catch-all case避免编译器报错。然而,分部活动模式有利于你串接多个活动模式。后面的例子会有。
 
度量单位
度量单位允许你把数字分成不同的单位。这个功能可以避免数字操作出错,比如把代表英尺的值和表示厘米的值相加。
定义度量单位,只需要声明一个名字,前面加上熟悉Measure。如下的例子:
[<Measure>]type m
默认的,度量单位通常使用在浮点型的值上,也就是System.Double,创建带单位的值,只需要用尖括号即可。
let
meters = 1.0<m>
 
如下的代码:
[
]type liter[
]type pintlet vol1 = 2.5
let vol2 = 2.5
let newVol = vol1 + vol2
编译出错:
因为不同的单位不允许相加。但是不同单位之间的乘法和除法的运算是可以的,并且会创建一个新的度量单位。比如下面代码:
let
ratio = 1.0<liter> / 1.76056338<pint>
 
标识符ratio的类型是float<liter/pint>,明确的表达出了升和品脱之间的比率。此外,类型是float<pint>的值乘以值float<liter/pint>,得到的类型就是float<liter>。这意味着你可以写出如下的代码: 
 
#light[
]type liter[
]type pintlet vol1 = 2.5
let vol2 = 2.5
// define the ratio of pints to literslet ratio = 1.0
/ 1.76056338
// a function to convert pints to literslet convertPintToLiter pints = pints * ratio// perform the conversion and add the valueslet newVol = vol1 + (convertPintToLiter vol2)printfn "%A" newVol

转载地址:http://btrwx.baihongyu.com/

你可能感兴趣的文章
【算法】CRF
查看>>
windows 8 微软拼音输入法
查看>>
Windows UI风格的设计(7)
查看>>
SQL中使用WITH AS提高性能 使用公用表表达式(CTE)简化嵌套SQL
查看>>
oracle 强行杀掉一个用户连接
查看>>
Git提交本地库代码到远程服务器的操作
查看>>
灾难拯救——让软件项目重回轨道
查看>>
ssh链接git服务器,解决push pull要求输入密码问题
查看>>
Netty 源码解析(二):对 Netty 中一些重要接口和类的介绍
查看>>
mysql中主外键关系
查看>>
第七章:数据字典
查看>>
python 字符串 类型互相转换 str bytes 字符串连接
查看>>
service mysqld start
查看>>
linux时间
查看>>
Spring+Mybatis项目中通过继承AbstractRoutingDataSource实现数据库热切换
查看>>
让Alert弹窗只弹出一次
查看>>
用友软件操作流程(新建年度帐、年度结转步骤)
查看>>
mysql权限管理
查看>>
我的友情链接
查看>>
让你快速上手的Glide4.x教程
查看>>