F# 入门(三):F# 基础数据类型
类型检查可发生在编译时期(静态检查)或运行时期(动态检查)。静态类型检查是在编译器进行语义分析中进行的。如果一个语言强制实行类型规则(即通常只允许以不丢失信息为前提的自动类型转换)就称此语言为强类型,反之称为弱类型。F#使用的是静态类型检查。这意味着,如果你传入一个string 值给 类型为int的变量,那么你将得到一个编译错误。
下面是F# 中一些数据类型:
你可以通过let关键字来定义值,事实上let 能做的事情很多。
- 常数
定义一个int型变量:
> let iInt = 1;;
val iInt : int = 1
(注意:文中的代码均在F# interactive 窗口中运行得到,在;; 之前的代码为输入部分,val 之后且包括val 都是输出部分。)
定义其它常数类型:
> let fFloat = 1.0;;
val fFloat : float = 1.0
> let ulInt = 1UL;;
val ulInt : uint64 = 1UL
下面是关于常数的表格:
类型 |
后缀 |
.NET 类型 |
范围 |
byte |
uy |
System.Byte |
0-255 |
sbyte |
y |
System.SByte |
-128 - 127 |
int16 |
s |
System.Int16 |
−32,768 - 32,767 |
uint16 |
us |
System.UInt16 |
0 - 65535 |
int,int32 |
|
System.Int32 |
−2^31 – (2^31 – 1) |
uint,uint32 |
u |
System.UInt32 |
0 – (2^32 – 1) |
int64 |
L |
System.Int64 |
−2^63 – (2^63 – 1) |
uint64 |
UL |
System.UInt64 |
0 – (2^64 – 1) |
float |
|
System.Double |
|
float32 |
f |
System.Float |
|
decimal |
M |
System.Decimal |
|
F#也支持使用前缀的形式定义常数类型:
> let iInt = 0xF1;;
val iInt : int = 241
- 字符类型char :
> let cChar = 'H';;
val cChar : char = 'H'
- 字符串类型 string:
> let sString = "Zack";;
val sString : string = "Zack"
- 输出类型值:
F# 中的输出函数:printf ,printfn ,sprint
Printf函数用来输出但不换行
Printfn函数输出并换行
Sprint 函数用来保存想打印的值, 如:let hold = sprintf "%s" "Zack Zhou"
- Unit(空类型):
> let empty = ();;
val empty : unit = ()
这里的unit就等价于其它语言中的void, 在代码中使用()来表示unit.
- Tuple(元组)类型:
> let tTuple = ( 1, "Zack" );;
val tTuple : int * string = (1, "Zack")
tuple 是一个组合类型,你可以像这样:(常量A,常量B,….)来定义一个tuple变量,其中A与B与其它常量的类型可以不同,也可以相同。 在FSI中我们可以看到此tuple的组合类型是:int*string,也就是A的类型* B的类型*其它各个常量的类型。Tuple 可以作为函数的返回值——这样就可以一次返回多个值。
那么,如何使用tuple里的值呢?我们可以如下定义一些变量:
> let ( a, b ) = ( 1, "Zack" );;
val b : string = "Zack"
val a : int = 1
也可以使用F# 定义好的两个函数来取tuple中的第一个和第二个值:
> let a = fst tTuple;;
val a : int = 1
> let b = snd tTuple;;
val b : string = "Zack"
- List(链表)类型:
> let iList = [ 1; 2; 5; 6 ];;
val iList : int list = [1; 2; 5; 6]
这里我们定义了一个int型的List,也就是说此List 中所有的元素都是int型。需要注意的是:List 中元素必须是同种类型的,这点不同于tuple 类型。
List 可以像数组那样使用下标来取得指定位置的元素:
> let iElement = iList.[1];;
val iElement : int = 2
关于List 的一些函数,在这里我就不一一列举每个函数的使用方法了,List内置了许多强大的函数,在使用时,非常方便。
List内置的函数 |
描述 |
List.length |
返回List的长度 |
List.head |
返回List 的首个元素 |
List.tail |
除去首个元素,将剩下的元素,组成一个新的List并返回 |
List.exists |
返回一个bool值用来表示此List中是否存在指定的元素 |
List.rev |
反转链表 |
List.zip |
给定两个相同长度的List ,返回一个元组类型的组合List。 |
List.filter |
返回一个由所有满足要求的元素组成的List |
下面是List的一些常用的操作符:@ ——用来连接两个List ,::——用来将单独的元素加入到已知List的头部。
如:
let combineList = [1;2;3] @ [4;5;6]
let addElem = 1 :: [2;3]
事实上,F# 还有一些其它较复杂的数据类型,如:Record ,Class,Discriminated Unions, Lazy Types, Sequence等等。这些将在后面的博客中单独介绍。