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
随机推荐
- C#动态创建两个按钮,btn2复制btn1的Click事件,匿名委托
现在有一个按钮btn1,要动态创建出一个btn2,需要btn2点击时调用btn1的点击. 在delphi中这种操作很简单:btn2.onClick:=btn1.onClick,因为onClick就是个 ...
- .Net异步函数存在的限制
本文摘录自CLR Via C# 第四版. 异步函数存在以下限制: 1.不能讲应用程序的Main方法转变成异步函数.另外,构造器.属性访问器方法和时间访问器方法不能转变成异步函数. 2.异步函数不能使用 ...
- LED的串联电阻值的计算
与LED串联的电阻被用于控制该LED导通时的电流量.为了计算电阻值,你需要知道输入电源电压(Vs,一般为5V),LED的正向电压(Vf)和你需要流过LED的电源(/)的数值. 其电阻欧姆值的计算公式( ...
- idea新建项目文件名为红色的解决办法
Perference->version Control ->Directory添加项目路径,vcs选<none> 即可.
- 敏捷开发(七)- SCRUM评估会议
本文主要是为了检测你对SCRUM 评估会议的了解和使用程度, 通过本文你可以检测一下 1.你们的SCRUM 评估会议的过程和步骤 2.SCRUM 评估的输出结果一.会议目的 1 ...
- 关于 Unchecked cast from Iterator to Iterator String 提示
遇到个这个提示:Unchecked cast from Iterator to Iterator String Iterator<String> keys = data.keys(); 修 ...
- PL SQL Developer报错框乱码
在系统变量里设置 变量名:NLS_LANG 变量值设为:SIMPLIFIED CHINESE_CHINA.ZHS16GBK
- 调皮的R文件,卑鄙的空格
毕业快一年了,由于公司业务需要,开发岗的我做了一年测试.最近,终于要开始转开发了.于是和小伙伴们合作,做一个备忘录apk.由于之前是做java的,而且差不多一年没碰代码了(这一年主要做测试,虽然有写自 ...
- ajax jsonp 跨域请求
$.ajax({ type:"get", url: "http://localhost/test/a.php", dataType: "jsonp&q ...
- 2px边框,4分之1内边框实现选中功能实现
有时候我们要实现如下选中效果: 我给出一种解决办法: 首先选中的时候,加一个class(active),未选中的全部加一个class(inactive),外层给一个1px border,每个选项给一个 ...