F#教程:向函数传入Record类型

我们继续Record的学习。我们试着定义并调用一个传入Vector类型参数的magnify函数:

type Vector = { x: int; y: int}
let    magnify v n = { x = v.x * n; y = v.y * n}
let v = { x = 10; y = 15 }
printfn "%A" (magnify v 2)

但是,如果是如下代码就会出现编译错误:

type Vector = { x: int; y: int}
type Point = { x: float; y: float}     //    新增行
let    magnify v n = { x = v.x * n; y = v.y * n}
let v : Vector = { x = 10; y = 15 }     // 显式定义为Vector类型
printfn "%A" (magnify v 2)             // 错误:无法传入Vector

原因就是由于新增行magnify函数的参数变成了Point类型。为了传入 Vector类型,必须显式地表明参数是Vector类型的。改写成如下会怎么样呢?

let magnify (v:Vector) n = { x = v.x * n; y = v.y * n}

结果还是不行。再次改写下吧!

let magnify (v:Vector) n : Vector = { x = v.x * n; y = v.y * n}

这样就OK了。(v:Vector) 部分是指定参数的类型,而=之前的: Vector是用来指定函数的返回值的类型。

总之,为了避免上述问题定义Record的时候最好不要让域值的名称相同。例如:

type Vector = { dx: int; dy: int}

这样,如果可以改变值域的名称,就不需要一一指定类型。不需要指定类型的实例代码如下:

type Vector = { dx: int; dy: int}
type Point = { x: float; y: float}
let    magnify v n = { dx = v.dx * n; dy = v.dy * n}
let v = { dx = 10; dy = 15 }
printfn "%A" (magnify v 2)

通常也是不需要指定类型的,不过最好也学习下显式指定类型的方法。这样对于比较大的程序就会有利于提高代码可读性。

时间: 2024-10-02 06:51:57

F#教程:向函数传入Record类型的相关文章

F#教程:函数

数据类型说了好几回了,有点烦了吧?这回我们就换个角度,学习下函数吧! 有两个两个输入参数并返回它们的和的简单函数如下: let Add a b = a + b 这就是函数的定义.同样使用了声明变量时的let. 确实感觉很神奇,没有了C#语言那样的冗长.看了这个定义后,有点感觉C#是冗长的语言.调用函数的代码如下: let c = Add 10 20 printfn "%d" c 其中,由于不使用括号有点怪怪的感觉.完整的程序如下: #light let Add a b = a + b

Swift教程之函数详解_Swift

函数是执行特定任务的代码自包含块.给定一个函数名称标识, 当执行其任务时就可以用这个标识来进行"调用". Swift的统一的功能语法足够灵活来表达任何东西,无论是甚至没有参数名称的简单的C风格的函数表达式,还是需要为每个本地参数和外部参数设置复杂名称的Objective-C语言风格的函数.参数提供默认值,以简化函数调用,并通过设置在输入输出参数,在函数执行完成时修改传递的变量. Swift中的每个函数都有一个类型,包括函数的参数类型和返回类型.您可以方便的使用此类型像任何其他类型一样,

F#学习之路(5) 元组类型

元组类型,表示一组有序数据类型的集合.F#通过支持元组类型,方便了我们定义临时数据结构,而不需要为了临时的数据专门定义一个数据类型. 一.元组的定义: let tuple_2=(1,2) let tuple_3=("F#",1.9,"F# Function Language") 在F#中元组使用小括号,元素之间逗号分隔来定义.元组元素可以是任何类型. 上面代码中,tuple_2的类型是int*int,而tuple_3的类型为string*float*string.元

Swift中文教程(四)--函数与闭包

原文:Swift中文教程(四)--函数与闭包 Function 函数 Swift使用func关键字来声明变量,函数通过函数名加小括号内的参数列表来调用.使用->来区分参数名和返回值的类型: 1 func greet(name: String, day: String) -> String { 2 return "Hello \(name), today is \(day)." 3 } 4 greet("Bob", "Tuesday")

js-关于一个函数传入变量的问题

问题描述 关于一个函数传入变量的问题 function count() { var arr = []; for (var i=1; i<=3; i++) { arr.push(function () { return i * i; }); } console.log(arr); return arr; } var results = count(); var f1 = results[0]; var f2 = results[1]; var f3 = results[2]; console.lo

在使用webservice开发时,然后有一个地方要传入String类型&amp;amp;amp;Long类型,然后就是...

问题描述 在使用webservice开发时,然后有一个地方要传入String类型&Long类型,然后就是... 我的代码块Long stateId = null; Call call = constructCall(url); try { call.setTargetEndpointAddress(new java.net.URL(url)); } catch (MalformedURLException e) { e.printStackTrace(); } call.setOperation

c++ 编译错误-大神请指教c++错误:返回类型与重写虚拟函数的返回类型既不相同也不协变

问题描述 大神请指教c++错误:返回类型与重写虚拟函数的返回类型既不相同也不协变 #include using namespace std; class base1{ public: virtual void display() const; }; void base1::display() const{ cout<<"base1::display()"<<endl; } class base2:public base1{ public: void displa

c++-C++成员函数前加类型,在g++下的编译错误,在vs2012下编译通过,什么原因

问题描述 C++成员函数前加类型,在g++下的编译错误,在vs2012下编译通过,什么原因 abc.cpp#include using namespace std;class MY{public: void MY::print() { cout<<""sdjflsdj""<<endl; } };int _tmain(int argc _TCHAR* argv[]){ MY my; my.print();return 0; } g++ abc.

C++11快餐教程(1)-通过using定义类型的别名

C++11快餐教程(1)-通过using定义类型的别名 在C/C++中,我们经常通过typedef来定义类型的别名. 例如: typedef unsigned char u1; typedef unsigned short u2; 但是,这样定义有一点不好,新定义的别名是放在后面的.一般我们都是通过别名找原名,从后往前找还是不方便的. 那么,我们把别名定义在前面好不好? using u4 = uint32_t; using u8 = uint64_t; 在C++11中,using不再只是用于us