F#注解
不要问我为啥要学F#——因为气质摆在那里
标注:以下内容均来自 anderslly F#系列
1、类型推演
let square x = x * x
//接受一个某类型参数的quare函数返回一个这个参数的平方,因为支持参数*参数的类型有很多;比如int,byte,uint64,double等,而F#会默认为int类型
//这就类似与js当中var 不同的是,在js当中,函数返回一个数值需要用return关键字 而F#不需要
2、规定参数的类型(类似于C#的形参 也叫类型注解)
let concat (x : string) y = x + y;;
//一个函数接受一个x的参数,这个参数必须为string类型(这里的冒号":"的作用就是起到了约束作用)以及一个参数y
//这里有同学以为y没有约束类型,那应该是什么类型都可以
//实际上是由于因为x类型是string,返回的值又是x + y 用了"+"操作,所以类型必须相同,则y也是string(用vs的同学可以按 alt+enter检查)
3、输出打印
printfn "N^2 = %A" squares
//打印信息 这里的%A是匹配任何类型的参数(也就是空格后面的squares) 注:参数的输入 必须要已空格隔开,否则会报错
这里有几个输出的类型要注明:%d,%f,%s分别是int、float、string的占位符
4、值,变量的不可变性
跟C#不同,F#中的变量都是不可变性的,换句话说 就是固定不变的,自然同时就具备了类型安全这个优良的特点,如果你一定要改变这个值,也是可以的!
用mutable改变这个值(注意:这个改动值,不是寻常我们C#,JS中的改变变量的值,而是重新创建了一个新的变量,这一点上是不是跟我们C#中的string有点类似呢 (^_^))
然后用左箭头操作符 <- 修改变量的值
let mutable x = "the original value.";;
printfn "x's value is '%s'" x;; //x's value is 'the original value'.
x <- "the new one.";;
printfn "x's value is now '%s'" x;; //x's value is now 'x's value is the original value'
5、引用值
引用值是另一种表示可修改数据的方式。但它不是将变量存储在堆栈(stack),引用值其实是一个指向存储在堆(heap)上的变量的指针(pointer)。在F#中使用可修改的值时会有些限制(比如不可以在内部lambda表达式中使用)。而ref对象则可被安全地传递,因为它们是不可变的record值(只是它有一个可修改的字段)。原话引自——【F# 20分钟快速上手(二)】
使用引用值时,用“:=”赋一个新值,使用“!”进行解引用。
let refCell = ref 42;; //refCell = 42
refCell := -1;; //改变引用值
!refCell;; //解析引用值 显示-1
6、模块(Modules)
这个就跟C#的using引用程序集是一个道理了 直接看例子
module ProgramSettings =
let version = "1.0.0.0"
let debugMode = ref false
module MyProgram =
do printfn "Version %s" ProgramSettings.version
open ProgramSettings
debugMode := true
7、元组(Tuple)
表示值的有序集合 也是跟C#中的元组有近似相同;用来传递多个或一组值
定义一个元组,只要将一组值用逗号分割
let tuple = (1, false, "text");;
let getNumberInfo (x : int) = (x, x.ToString(), x * x);; //定义个接受int的变量x 函数返回三个变量(int,string,int)
函数可以接受元素为参数,自然C#也是可以的
let printBlogInfo (owner, title, url) = printfn "%s's blog [%s] is online at '%s'" owner title url;;
let myBlog = ("Chris", "Completely Unique View", "http://blogs.msdn.com/chrsmith");;
printBlogInfo myBlog;; //输出 Chris's blog [Completely Unique View] is online at 'http://blogs.msdn.com/chrsmith'
8、函数科里化(Function Currying)
F#中可以只接受某函数的参数 进而将参数传递给另一个新的函数
let addThree x y z = x + y + z;; //函数addThree接受三个参数 1
let addTwo x y = addThree 10 x y;; //函数addTwo接受两个参数 2
addTwo 1 1;; //调用addTwo传1,1两个参数—>由于函数2返回一个新的函数addThree 并接受一个参数10,和前一个函数的两个参数的值
9、Union类型
没有自己的一些见解,直接点击原文
10、模式匹配
看起来想swicth case模式
let listLength aList =
match aList with
| [] -> 0
| a :: [] -> 1
| a :: b :: [] -> 2
| a :: b :: c :: [] -> 3
| _ -> failwith "List is too big!" //竖线 | 表示各种case ->是lambda表达 表示输出 a::[] 意思是说 a 在 [] 之前的元素(这是空的list集合)
let isOdd x =
match x with
| _ when x % 2 = 0 -> false
| _ when x % 2 = 1 -> true //下划线 _ 是匹配任意值
也可以动态匹配
let getType (x : obj) =
match x with
| :? string -> "x is a string"
| :? int -> "x is a int"
| :? System.Exception -> "x is an exception"
| :? _ -> "invalid type" // 这里博主没有将:? 符号的意思说明 我就理解为表面意思 :匹配这个值 ?是可以是任何类型的 跟输入的类型是一样的 比如输入"a" 就是string;11 就是int
11、Forward Pipe operator(|>)
简单的理解就是一个函数A接受一个参数并返回一个值,然后把这个值又传递给另一个函数B,函数B得到这个参数并返回一个值(类型可能不同),进入接着往下传递
用C#的写法就是
Int32 result = Func3(Func2(Fun1(A)))......
我们来看看F#的写法
let square x = x * x
let toStr (x : int) = x.ToString()
let rev (x : string) = new String(Array.rev (x.ToCharArray()))
let result = rev (toStr (square 32)) //调用
上面看起来就跟C#的一样直白,好理解,那我们接着用操作符 |> 写一遍
let result = 32 |> square |> toStr |> rev
可以看出这样极大的简化了我们代码,并且更说明了Forward Pipe Operator的含义
12、集合(Collection:Seq,List,Array)
F#表示集合的有三种,Seq;List; Array
这里每个集合类型都有很多方法,大家可以用VS的智能提示了解(吐槽一下:不知道我的vs是怎么滴,一定得手动按ctrl+j才行 不能想C#中实时出现提示的)这里我记录几个常用的
iter。“iter”函数遍历集合的每一项。 跟foreach遍历一样
List.iter (fun i -> printfn "Has element %d" i) [1 .. 10] 从集合[1..10](这个是集合的元素从1到10)循环遍历输出Has element 1 2 3...
map map函数基于一个指定的函数对集合的值进行转换
Array.map (fun (i : int) -> i.ToString()) [| 1 .. 10 |] //([|1..10 |] 前后加竖线是说明此几何为整数数组) 次数是由原来的整数集合变为一个字符串集合
fold。“fold”函数接受一个集合,并将集合的值折叠为单个的值。像iter和map一样,它接受一个函数,将其应用于集合的每个元素,但它还接受另一个“accumulator”参数。fold函数基于上一次运算不断地累积 accumulator参数的值 注:是不是跟C#的ForEach(Func)很想呢
Seq.fold (fun acc i -> i + acc) 10 { 1 .. 10 }
13、可选值(Option Values)
F#中的“可选类型(option type)”有两种状态:“Some”和“None”。在下面的记录类型Person中,中间的字段可能有值,也可能没有值
type Person = { First : string; MI : string option; Last : string }
let billg = {First = "Bill"; MI = Some("H"); Last = "Gates" }
let chrsmith = {First = "Chris"; MI = None; Last = "Smith" }
14、延迟求值 (LazyValue)
延迟初始化表示一些值,它们在需要时才进行计算。F#拥有延迟求值特性。看下面的例子,“x”是一个整数,当对其进行求值时会打印“Computed”。
let x = lazy (printfn "Computed."; 42);; //初始化值42 但是被延迟了
let listOfX = [x; x; x];;
x.Force();; //直到使用Force 才会初始化x的值
F#注解的更多相关文章
- 自定义Java注解(annotation)
https://www.imooc.com/learn/456 笔记 Java从1.5开始引进注解. 首先解决一个问题,为什么要学习Java注解? 1.看懂别人写的代码,尤其是框架的代码 2.可以是 ...
- python重试库retryiny源码剖析
上篇博文介绍了常见需要进行请求重试的场景,本篇博文试着剖析有名的python第三方库retrying源码. 在剖析其源码之前,有必要讲一下retrying的用法,方便理解. 安装: pip insta ...
- python 常用的高阶函数
前言 高阶函数指的是能接收函数作为参数的函数或类:python中有一些内置的高阶函数,在某些场合使用可以提高代码的效率. map() map函数可以把一个迭代对象转换成另一个可迭代对象,不过在pyth ...
- Mysql_以案例为基准之查询
查询数据操作
- 注解式HTTP请求Feign (F版)
Spring Cloud 为开发者提供了在分布式系统中的一些常用的组件(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,决策竞选,分布式会话集群状态).使用Sprin ...
- 编写高质量代码:改善Java程序的151个建议(第6章:枚举和注解___建议88~92)
建议88:用枚举实现工厂方法模式更简洁 工厂方法模式(Factory Method Pattern)是" 创建对象的接口,让子类决定实例化哪一个类,并使一个类的实例化延迟到其它子类" ...
- Unity中关于作用力方式ForceMode的功能注解
功能注解:ForceMode为枚举类型,用来控制力的作用方式,有4个枚举成员,在以下举例中均设刚体质量为m=2.0f,力向量为f=(10.0f,0.0f,0.0f). (1)ForceMode.For ...
- Effective java笔记(五),枚举和注解
30.用enum代替int常量 枚举类型是指由一组固定的常量组成合法值的类型.在java没有引入枚举类型前,表示枚举类型的常用方法是声明一组不同的int常量,每个类型成员一个常量,这种方法称作int枚 ...
- 转载:《TypeScript 中文入门教程》 17、注解
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 随着TypeScript和ES6里引入了类,现在在一些场景下我们会需要额外的特性 ...
随机推荐
- onsrcoll和scrollTop兼容与实现
对于onscroll事件的支持 各浏览器 document.document.body.document.documentElement 对象的 onscroll 事件的支持存在差异. 所谓的支持性存 ...
- IT和非IT人士:2分钟了解什么是区块链
本文由 网易云发布. (非IT:阅读常规部分:IT:阅读引用块) 作者:任长存,网易杭州研究院工程师 前言 信息的高速发展,致使互联网风口犹如娱乐圈,移动互联网,微博.直播.共享经济.短视频.小程序 ...
- 【转】Bri's改装笔记
网上关于三菱蓝瑟的改装方案的文章不少,但在以不换发动机为前提的理性改装确是这两篇和东南汽车俱乐部科仔的那篇<4G18的低成本NA玩法>最具参考价值. 小排量NA车的乐趣不在于跟人比直线加速 ...
- leetcode 123. 买卖股票的最佳时机 III JAVA
题目: 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意: 你不能同时参与多笔交易(你必须在再次购买前出 ...
- PARSER_JS_PRECISION_RANGE_EXCEEDED 错误
{ [Error: parseLengthCodedNumber: JS precision range exceeded, number is >= 53 bit: "3037620 ...
- iOS多线程---NSOperation的常用操作
1.最大并发数: - (NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger) ...
- 批量导入数据到HBase
hbase一般用于大数据的批量分析,所以在很多情况下需要将大量数据从外部导入到hbase中,hbase提供了一种导入数据的方式,主要用于批量导入大量数据,即importtsv工具,用法如下: Us ...
- Oracle 锁问题处理
Oracle 锁问题处理 锁等待问题是一个常见的问题 查看持有锁的对象 查看事务正在执行的语句,与应用确认是否能够kill kill 对应的session
- attachEvent和addEventListener区别总结
1.attachEvent与addEventListener的区别 支持的浏览器不同.attachEvent在IE9以下的版本中受到支持.其它的都支持addEventListener. 参数不同.ad ...
- Android 开发工具类 16_NotificationActivity
在前台运行的 Activity 可以通过Dialog.Toast 向用户发出提示信息,而后台运行的程序,如下载.收到信息等 Service 应用,则需要使用 Notification(通知)向用户发出 ...