F#基本关键词学习笔记
2011-11-08 14:10 AnyKoro 阅读(240) 评论(0) 编辑 收藏 举报let
动作:绑定
作用:将一个标示符与一个值或函数关联在一起。
语法:
// Field. [static] let [ mutable ] binding1 [ and ... binding-n ] // Function. [static] let [ rec ] binding1 [ and ... binding-n ]
let默认是private性质的
说明:
其中红色字体部分表示在类定义中的let具有该属性。
例子:
let result = let i, j, k = (1, 2, 3) // Body expression: i + 2*j + 3*k
type PointWithCounter(a: int, b: int) = // A let binding that uses a pattern. let (x, y) = (a, b) // A static let binding. static let mutable count = 0 member this.Prop1 = x member this.Prop2 = y
val
动作:显示声明
作用:在类类型或结构类型中声明字段,而无需将其初始化。通过此方式声明的字段称为“显示字段”。
语法:
[ static ] val [ mutable ] [ access-modifier ] field-name : type-name
access-modifier 可以是 public、private 或 internal, public is default
val默认是public性质的
说明:
在类类型或结构类型中,定义字段的常见方式是使用let字段。但是,必须将let绑定作为类构造函数的一部分进行初始化,但这些绑定并不总是有必要初始化。当无需初始化这些字段时,可以使用val关键字。
在这里,因为val的字段不再作为构造函数的一部分进行初始化,所以,当没有传入参数时,也要起作用,那么就要设置默认值——DefaultValue特性。此特定指定字段初始为零。为以下类型时,则支持零初始化:
- 具有零值的基元类型。
- 支持将null值作为正常值、异常值或值的表示形式的类型。其中包括类、元组、记录、函数、接口、.NET引用类型、unit类型和可区分联合类型。
- .NET值类型。
- 所属字段都支持默认零值的结构。
注意:显示字段并不是惯常的用法,一般如果可能的话尽量使用let,在互操作的情况中会比较容易用到val
例子:
【1】类:有主构造函数情况,即有()部分
type MyType() = let mutable myInt1 = 10 // default private [<DefaultValue>] val mutable myInt2 : int // default public and equal zero [<DefaultValue>] val mutable myString : string member this.SetValsAndPrint( i: int, str: string) = myInt1 <- i this.myInt2 <- i + 1 this.myString <- str printfn "%d %d %s" myInt1 (this.myInt2) (this.myString) let myObject = new MyType() myObject.SetValsAndPrint(11, "abc") // The following line is not allowed because let bindings are private. // myObject.myInt1 <- 20 myObject.myInt2 <- 30 myObject.myString <- "def" printfn "%d %s" (myObject.myInt2) (myObject.myString)
【2】类:无主构造函数情况,在此示例中,不需要 DefaultValue 特性,但必须在为类型定义的构造函数中初始化所有字段。
type MyClass = val a : int val b : int // The following version of the constructor is an error // because b is not initialized. // new (a0, b0) = { a = a0; } // The following version is acceptable because all fields are initialized. new(a0, b0) = { a = a0; b = b0; } let myClassObj = new MyClass(35, 22) printfn "%d %d" (myClassObj.a) (myClassObj.b)
【3】结构体中
type MyStruct = struct val mutable myInt : int val mutable myString : string end let mutable myStructObj = new MyStruct() myStructObj.myInt <- 11 myStructObj.myString <- "xyz" printfn "%d %s" (myStructObj.myInt) (myStructObj.myString)
do
动作:执行绑定
作用:用于在不定义函数或值的情况下执行代码,同时可以再类中使用
语法:
【1】非类中,Module级别
[ attributes ] [ do ]expression
此处的do是可选的,当没有do的时候,直接是语句在Module级别也是可以的,但是在类中的话,是一定要加do的。同时在类中的do也会忽略[attributes]
【2】类中
[static] do expression
说明:
当想执行一段代码,但又不希望进行函数或值的定义,此时就可以使用do进行绑定,表示执行该段代码。
在类中的情况会稍微复杂点,但是本质也都一样就是在初始化该类的时候自动执行do后面的语句,但是有一点要注意,一般do中可能会用到类中定义的字段,所以do语句要在其用到的字段定义的后面,或者干脆就放在所有let之后,所有member之前。
类中静态的do可以引用封闭类的静态成员或字段,但不可以引用实例成员或字段。静态do绑定,可以成为类的静态初始值设定项的一部分,这可以保证第一次使用类之前执行该绑定。会比非静态的do更早执行。
例子:
【1】非类中
open System open System.Windows.Forms let form1 = new Form() form1.Text <- "XYZ" [<STAThread>] do Application.Run(form1) //会自动执行
【2】类中
open System type MyType(a:int, b:int) as this = inherit Object() let x = 2*a let y = 2*b do printfn "Initializing object %d %d %d %d %d %d" a b x y (this.Prop1) (this.Prop2) static do printfn "Initializing MyType." member this.Prop1 = 4*x member this.Prop2 = 4*y override this.ToString() = System.String.Format("{0} {1}", this.Prop1, this.Prop2) let obj1 = new MyType(1, 2)
do
动作:
作用:
语法:
说明:
例子:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)