模式匹配的类型测试不能识别List<’a>

【信息科学与工程学】计算机科学与自动化——第三十九篇 编程语言模型 定义值格 L={⊥,c1​,c2​,...,⊤},其中 ⊥表示未知/未初始化,ci​为具体常数,⊤表示非常量/多重可能值。格序关系:⊥⊑ci​⊑⊤。 阅读详情

我在Visual Studio论坛上读过一个很有趣的论坛帖子,内容大致是这样的:

当试图测试一个obj对象是否是一个空的list,我们不能用模式匹配的类型测试来达到目的,具体代码如下:

let empt (o: obj) =

     match owith

     | :? List<'a> as l when l.IsEmpty->true

     | _ ->false

编译器会报一个警告:warningFS0064: This construct causes code to be less generic than indicated by thetype annotations. The type variable 'a has been constrained to be type 'obj'.

就是因为这个警告,“empt (List.tail [1]);;”会返回false因为它是List<int>,而不是List<obj>。更有趣的是如果你换而指定List<’a>为一个特定类型的List如List<int>,List<cahr>等,就能正常工作了。

你可能会很快想到使它成为强类型以摆脱这个问题,于是,有了下面的解决方案:

let emp(o : obj) =

     match owith

     | :? list<'a> as l when (l= [])->true

     | _ ->false

你可能还会想到拆箱obj类型的变量o,或者强制List<’a>为List<obj>。。。但是所有这些都将是一个美好的梦,仍然无法工作。

那么究竟如何解决它呢?为什么堕胎在这里不工作了?为什么类型推断算法统一了类型’a和obj?

答案就是:用反射而不是模式匹配的类型测试。一下代码能解决这个问题:

open System.Reflection

let empt (o : obj) =

    let genericListType = typedefof<List<_>>

    let bindingFlags = BindingFlags.GetProperty |||BindingFlags.Instance |||BindingFlags.Public

    match o.GetType()with

        |t when t.IsGenericType ->

            let genericType = t.GetGenericTypeDefinition()

            if genericType = genericListTypethen

                t.InvokeMember("IsEmpty",bindingFlags,null, o, Array.empty) :?> bool

            elsefalse

        |_ ->false

那么为什么要这样做呢?

问题就在于.NET运行时不会提供任何有效的方式来为一个未知的’a决定一个对象是否是一个List<’a>。唯一可行的机制就是像上述所用的反射,且自动转换成反射将会很不直观(例如:通常会需要创建一个泛型方法并用反射动态的调用这个方法,加上为类型测试实现反射的开销也很大)。因此,F# 要求用List<’a>来表示一个特定的类型’a;如果没有提供其它信息,类型推断将会默认它就是obj类型的。
集成电路模拟版图入门-版图基础学习笔记(一) 集成电路设计模拟版图入门笔记,了解版图的定义、意义、工具、设计流程。认识版图及版图组成的两大部件,版图编辑器有哪些,电路图编辑器,了解工艺厂商等。 阅读详情

相关推荐

避坑指南:vmdk转qcow2镜像时你可能会遇到的5个问题及解决方法

本文详细解析了将VMDK虚拟机镜像转换为QCOW2格式时可能遇到的五大核心问题,特别是启动失败的常见原因及解决方案。内容涵盖格式差异、预处理优化、转换命令详解,并针对根文件系统挂载失败、GRUB引导失败、网卡识别、性能异常等典型故障提供了具体排查与修复步骤,旨在帮助运维人员高效、可靠地完成镜像迁移。

websocket5live的博客 275

List用法整理

List 拷贝new List。取某元素并放到list。

qq_29316743的博客 220

大疆精灵3无人机2.4GHz通信系统实测:跳频扩频技术深度解析

跳频扩频(FHSS)是一种经典的扩频通信技术,其核心原理是通过让载波频率在一个宽频带上按伪随机序列快速跳变,将窄带信号的能量扩散开来。这种技术能有效对抗固定频率干扰,提升通信的可靠性和抗截获性,在无线遥控、军事通信等领域具有重要价值。在无人机、物联网等对实时性与可靠性要求高的应用场景中,FHSS技术能显著增强复杂电磁环境下的链路鲁棒性。本文以频谱分析仪实测大疆精灵3无人机为例,深入剖析其2.4GHz频段遥控与图传系统的工作特性,揭示了其采用的成熟FHSS方案,包括约76MHz的总跳频带宽、39个信道及约2M

weixin_33935636的博客 310

List<A>转型为List<B>

假设现在有两个类—— A 和 B ,其中 A 是 B 的子类。将 A(子类)的引用转换为 B(父类)的引用是很普通的事,在任何编程语言中都不存在问题。但是将 List&lt;A&gt; (子类的容器)转换成 List&lt;B&gt; (父类的容器)就不是那么简单的事情了,因为 List&lt;B&gt; 并不是 List&lt;A&gt; 的父类。 不过从 .NET 4.0起,我们已经可以在 ...

纸箱猪的专栏 2621

GB/T 27930-2023协议升级与CANoe仿真测试实践

本文深入解析GB/T 27930-2023协议的核心升级,包括A/B类系统分类与EVIN码引入,并详细指导如何使用CANoe搭建仿真测试环境、编写CAPL脚本及利用DLL库进行一致性验证与故障注入测试,助力开发人员确保电动汽车充电通信的合规性与稳定性。

y7z8a的博客 540

银河麒麟V10 SP1忘记密码?3分钟搞定单用户模式密码重置(附详细截图)

本文详细介绍了银河麒麟V10 SP1操作系统忘记登录密码后的应急恢复方法。核心是通过GRUB引导菜单进入单用户模式,无需密码即可获得root权限,从而快速重置用户密码。文章提供了从捕捉GRUB界面、编辑启动参数到执行密码修改命令的完整步骤图解与常见问题解决方案,帮助用户在几分钟内恢复系统访问。

w3x4y的博客 916

从List<A>对象集合数据 copy到List<B>对象集合中

参数: A集合 数据源 List<?> B集合 接收方 Class<T> clazz (反射 T.class)

骐骥筋力成,志在万里外 1311

别再手动抄表了!用MCGS触摸屏自动存数据到U盘,5分钟搞定报表导出

本文详细介绍了如何利用MCGS触摸屏实现工业数据自动记录与U盘导出,彻底告别传统手动抄表方式。通过昆仑通态MCGS系统,可构建零误差自动化报表系统,实现实时数据采集、双重备份及标准CSV格式导出,大幅提升数据准确性和工作效率。

weixin_30872157的博客 793

List<>接口的使用用法

A为类,list&lt;A&gt;的&lt;&gt;中只能用A的对象 A为接口,list&lt;A&gt;的&lt;&gt;中用实现接口的类的对象或者类

qq_38837415的博客 670

从Gotham到Foundry:一文读懂Palantir三大产品线(Gotham/Foundry/Apollo)的核心差异与适用场景

本文深度解析Palantir三大产品线Gotham、Foundry和Apollo的核心差异与适用场景。Gotham专为国防与情报设计,提供军事级安全分析;Foundry是企业数字化转型的通用平台,支持低代码开发;Apollo则是云原生基石,确保系统可靠运行。通过对比产品架构与典型应用,帮助技术决策者根据需求做出明智选择。

weixin_42524499的博客 841

汽车标定技术(七)--英飞凌TC3xx_Overlay实现页切换

今天说要开个专栏讲讲XCP标定,但在将标定之前,先把英飞凌专门为标定功能设计overlay功能讲解清楚。

认真搞搞汽车MCU 4016

从List<A>复制到List<B> A,B属性相同

主要利用copy 方法 /** * 从List<A> copy到List<B> * @param list * @param clazz * @param <T> * @return */ private static <T> List<T> copy(List<...

weixin_41987908的博客 998

Python爬虫实战:全方位解析前程无忧(51job)职位详情爬取及反爬破解

平台规模:覆盖全国各行业、数百万条岗位信息。数据特点:职位描述详细,职位标签丰富。数据价值:支持招聘趋势分析、职业发展研究、薪资行情调研。推荐Python 3.10+,支持最新async特性与库兼容。

2201_76125261的博客 1487

AI编程助手类型错误消融分析:提升静态类型语言开发效率

静态类型系统是现代编程语言的核心机制,它通过编译时类型检查保障代码安全性与可维护性。其工作原理基于类型推导与约束求解,能在代码执行前发现类型不匹配等错误。这项技术的核心价值在于大幅减少运行时错误,提升代码质量与团队协作效率,广泛应用于系统编程、金融科技与函数式语言开发。随着AI编程助手的普及,开发者发现其在处理复杂类型错误时存在明显局限。本文聚焦类型错误消融实验方法,通过系统化测试框架评估AI助手的类型推理能力,为开发者提供实用交互策略,帮助更高效地利用AI工具进行静态类型语言开发。

weixin_30892763的博客 339

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

深度定制Android TTS语音规则:高级JavaScript脚本处理引擎技术实现指南

在Android TTS应用开发中,如何实现智能化的文本预处理是提升朗读质量的关键技术挑战。tts-server-android通过Rhino JavaScript引擎驱动的语音规则系统,为开发者提供了高度可定制的文本处理能力。本文将深入解析该项目的语音规则引擎架构,并提供从源码级配置到高级脚本编写的完整技术实现方案。 ## 技术架构深度解析:Rhino引擎与语音规则处理链 tts-serve

gitblog_00862的博客 440

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C#串口编程进阶:利用WMI动态获取与实时监听串口设备

串口通信是工业控制、嵌入式开发和物联网设备调试中的基础技术,它通过物理或虚拟端口实现上位机与下位机之间的数据交换。其核心原理在于操作系统对硬件设备的统一管理,Windows通过WMI(Windows Management Instrumentation)提供了标准化的设备信息查询与事件通知机制。这一机制的技术价值在于,开发者可以超越传统的静态端口枚举,实现动态、实时的设备状态感知,从而构建响应更敏捷、用户体验更佳的专业级工具。在应用场景上,无论是串口调试助手、设备配置软件还是自动化测试平台,实时感知串口插拔

weixin_30634661的博客 510

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

list<int> a && list<int> a(m) 的区别(C++)

list&lt;int&gt; a &amp;&amp; list&lt;int&gt; a(m) 的区别(C++) (1) list&lt;int&gt; a; 定义一个a 链表,链表大小未知。执行 a.push_back() 操作时,向后面加元素; (2)list&lt;int&gt; a(m) ; 定义一个a 链表,链表大小为m。执行 a.pu...

code进击者 758

List的contains()方法

应用环境:从数据库中查询出满足一系列条件的记录,然后以对象的形式封装到List中去。此时假设有两个条件A和B,满足A的记录集和为ListA,满足B的记录集合为ListB,现在要将ListA和ListB合并为一个List,注意ListA和ListB中可能有重复的记录(因为可能某条记录即满足条件A又满足条件B),要过滤掉重复的记录。方法过程:我们假设List中存放的对象都是Order对象,属性or

鱼与飞鸟 7万+

不识别list的解决方法

1、 首先包含头文件 #include 2、其实使用标准命名空间 using namespace std;

dafenqie的博客 1217

解决无法识别源列表解决

安装pip3时出现的的错误,解决方法就是把对应的文件删除 Ubuntu无法识别源列表解决   当提示无法识别源列表错误时    解决方法:    sudo rm /etc/apt/sources.list.d/docker.list   sudo apt-get update

u013887486的博客 8258

python sort 部分元素_Python 犄角旮旯--List

列表的构建List 是 Python 中最常用的容器之一,它是一个可变(mutable)容器,也就是说 List 的内容可以被修改,这也意味着它不能作为 Dict 的 key,也不能出现在 set 中。List 的创建有以下几种方式:[] 是一个空列表;[a] 或者 [a, b] 构成一个列表;用推导式创建列表, [el for el in range(10)];list() 或者 list(it...

weixin_39636079的博客 209

F# 入门(一):介绍

什么是函数式编程   函数编程(FunctionalProgramming, FP)是最早的一种编程范式。第一种FP语言是IPL,产生于1955年,比Fortran的产生早一年;第二种FP语言是1958年出现的Lisp,比Cobol的产生早一年。Fortran和Cobol都是命令式编程语言,它们在科学和商业领域中的迅速崛起使得命令式编程在30多年的时间内占主导地位。随着1970年代面向对象范

fsharp_net的专栏 2981
上一篇: F#与数学(III) – 自定义数字类型(PartIII)
下一篇: F#和C#里面的NULL 值
fsharp_net
博客等级 码龄15年 20粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值