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
随机推荐
- 【LeetCode】23. Merge k Sorted Lists
合并k个已合并链表. 思路:先把链表两两合并,直到合并至只有一个链表 /** * Definition for singly-linked list. * struct ListNode { * in ...
- [转]奇异值分解(We Recommend a Singular Value Decomposition)
原文作者:David Austin原文链接: http://www.ams.org/samplings/feature-column/fcarc-svd译者:richardsun(孙振龙) 在这篇文章 ...
- Shell 脚本计算时间差
在shell脚本中统计程序执行完毕所需要的时间不像在java中使用System.currentTimeMillis()方便 稍微记录一下,以供备用,免得又去花时间想(统计程序执行消耗多少s): sta ...
- java基础第三天
- C#编程之“串口通讯多次接收”
摘要: 主要记录了再C#的串口开发时遇到的问题,以便后续遇到相同问题再重复砍树造轮子. 1.问题场景 板卡和PC间通过UART进行数据通讯,由PC给板卡发送控制命令,板卡返回相应的数据. 2.遇到的问 ...
- sql数据导出导入格式化
SHELL脚本导入导出数据时,按逗号分隔,引号包含字段,null值'' gccli -uroot -h$ip -e"rmt:${sqlStr} into outfile '${name}${ ...
- SpringMVC 学习-异常处理 SimpleMappingExceptionResolver 类
Spring3.0 对异常的处理方式总共有两种: 一种是使用 HandlerExceptionResolver 接口,并且 Spring 已经提供默认的实现类 SimpleMappingExcepti ...
- Mammoth官方文档翻译
用于.NET的.docx转HTML的Mammoth Mammoth可用于将.docx文档(比如由Microsoft Word创建的)转换为HTML.Mammoth致力于通过文档中的语义信息生成简洁的H ...
- Intellij Idea使用频率较高的几个快捷键
自动补全参数定义: Ctrl+Alt+V 运行断点Expression: Alt+F8 选择具体的方法以断点步入:Shift+F7 智能操作: Alt+Enter 打开最近文件:Ctrl+E 打开最近 ...
- python入门必备知识总结
人生苦短,我用python.看图说话 一.python简介与发展: python 是一种面向对象的解释性计算机程序设计语言. python由荷兰人Guido van Rossum 于1989年发明. ...