F#中的自定义隐式转换
我们知道隐式变换在可控情况下会使代码变得简洁。熟悉C#的都知道C#中可以自定义隐式变换,例如
public class A
{
private int data; public static implicit operator A(int i)
{
return new A{ data = i};
}
}
众所周知,F#本身不会进行任何隐式变换。那F#中是否也可以自定义隐式变换呢?
当然可以。通过定义自己的操作符即可实现。
我们先定义一个转换操作符
let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x)
先看操作符"!>"的签名:有一个类型为a的输入参数,输出参数类型为b。再看定义部分,则是一个类型约束,指示类型a或者b至少有一个类型包含指定签名的成员
static member op_Implicit。然后接着是输入参数x。这些,就足够实现隐式转换。看一个例子
let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x) type A() = class end
type B() =
static member op_Implicit(a:A) = B()
member this.Add x y = x + y let show (b: B) = b.Add let res = show (!> A())
这段代码输入结果为3。
我们将引入一个术语duck typing,它是有关动态类型的,对一个对象建立某种适用性以达到某些目的。我们知道在正常的类型中,对象的适用性是由对象的类型决定。在duck typing中,对象的适用性在某种意义上由方法和属性决定,而非对象的类型。
在F#中,我们可以利用这种机制创建泛型函数,从而给我们编程带来很大的好处。例如以下例子中我们引入duck typing
// Longhand
let inline implicit< ^a,^b when ^a : (static member op_Implicit : ^b -> ^a)> arg =
( ^a : (static member op_Implicit : ^b -> ^a) arg) // Shorthand - let the compiler do the work
let inline implicit arg =
( ^a : (static member op_Implicit : ^b -> ^a) arg)
(代码参考http://weblogs.asp.net/podwysocki/f-duck-typing-and-structural-typing)
利用以上代码我们就可以重写!>操作符
let (!>) : A -> B = implicit
然后运行上面的最后一行代码
let res = show (!> A())
可以获得同样的结果3
当然,在F#中为了保证类型安全,不推荐使用这种自定义隐式变换特性。
F#中的自定义隐式转换的更多相关文章
- C#中的类型转换-自定义隐式转换和显式转换
目录 前言 基础知识 示例代码 实际应用 问题 答案 报错 用户定义的转换必须是转换成封闭类型,或者从封闭类型转换 参考 其他 应用和设计 读音 参考 前言 有时我们会遇到这么一种情况:在json数据 ...
- SQL Server中提前找到隐式转换提升性能的办法
http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...
- scala自定义隐式转换
Scala自定义隐式转换 一.编写隐式转换类 /** * Author Mr. Guo * Create 2019/4/20 - 17:40 */ object StringImprovments { ...
- 使用自定义隐式转换快速创建失败Result
系统要求方法都返回 Result 结果,通常我们会如此定义一个 Result 1 public class Result<T> 2 { 3 public virtual int Code ...
- ahjesus自定义隐式转换和显示转换
implicit 关键字用于声明隐式的用户定义类型转换运算符. 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换. 参考戳此 explicit ...
- js中的一些隐式转换和总结
js中的不同的数据类型之间的比较转换规则如下: 1. 对象和布尔值比较 对象和布尔值进行比较时,对象先转换为字符串,然后再转换为数字,布尔值直接转换为数字 [] == true; //false [] ...
- js中的数据类型隐式转换的三种情况
js的数据类型隐式转换主要分为三种情况: 1. 转换为boolean类型 2. 转换为number类型 3. 转换为string类型 转换为boolean类型 数据在 逻辑判断 和 逻辑运算 之中会隐 ...
- Scala中的Implicit(隐式转换,隐式参数,隐式类)
文章来自:http://www.cnblogs.com/hark0623/p/4196452.html 转发请注明 代码如下: /** * 隐式转换 隐式参数 隐式类 */ //隐式转换 class ...
- java中类型的隐式转换
byte+byte=int,低级向高级是隐式类型转换,高级向低级必须强制类型转换,byte<char<short<int<long<float<double
随机推荐
- Ubuntu14.04安装wineqq国际版出现无法输入中文的解决方法
执行命令:sudo vim /usr/bin/wine-qqintl 将"export LANG=zh_CN.utf8"改为"export LANG=en_US.utf8 ...
- Socket编程中 setsockopt的作用
功能描述: 获取或者设置与某个套接字关联的选 项.选项可能存在于多层协议中,它们总会出现在最上面的套接字层.当操作套接字选项时,选项位于的层和选项的名称必须给出.为了操作套接字层的选项,应该 将层的值 ...
- CHD 2015迎新杯题解
A.预防流感的拉面女神 简析:计算 n 的二进制表示里面 1 的个数 #include <cstdio> #include <cstring> #include <alg ...
- springMVC Helloword 入门程序
1 首先是在web.xml 中配置 <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-cl ...
- String与StringBuild、StringBuffer的区别
String与StringBuild.StringBuffer的区别相信困扰了好多新入门的JAVA程序员,而这也是笔试和面试的一道常见题型,如何全面的回答该问题,变得尤为重要. 首先我们需要清楚一点, ...
- ASP.NET Calendar(日历控件)
定义和用法 Calendar 控件用于在浏览器中显示日历. 该控件可显示某个月的日历,允许用户选择日期,也可以跳到前一个或下一个月. 属性 属性 描述 .NET Caption 日历的标题. 2.0 ...
- 手工杀毒辅助软件(PC Hunter) V1.51 免费绿色版
软件名称: 手工杀毒辅助软件(PC Hunter) 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 4.7MB 图片预览: 软件简介: PC Hunter是 ...
- 4天html总结
- C++类与static
到目前为止,我们设计的类中所有的成员变量和成员函数都是属于对象的,如我们在前面定义的book类,利用book类声明两个对象Alice和Harry,这两个对象均拥有各自的price和title成员变量, ...
- HDU 1847 Good Luck in CET-4 Everybody! 博弈
题目思路: 写出SG函数(1表示先手胜,0表示先手负) 110110110110-- 发现n%3==0时,Cici胜 #include<stdio.h> #include<strin ...