仓颉编程入门 -- 泛型概述 , 如何定义泛型函数
泛型概述 , 如何定义泛型函数
1 . 泛型的定义

在仓颉编程语言中,泛型机制允许我们定义参数化类型,这些类型在声明时不具体指定其操作的数据类型,而是作为类型形参保留,待使用时通过类型实参来明确。这种灵活性在函数和类型声明中尤为常见,如Array和Set等容器类型就是典型的泛型应用。以数组为例,由于我们可能需要在数组中存储多种不同类型的数据,因此不可能为每种数据类型都定义一个专门的数组类型。通过引入泛型,我们可以在数组类型声明时声明一个或多个类型形参(如T),并在实际使用数组时指定这些形参的具体类型,从而避免了代码的大量重复。
在仓颉编程语言的体系中,不仅函数声明可以是泛型的,就连class、interface、struct以及enum的声明也都可以声明类型形参,即它们都可以被设计为泛型。为了更清晰地讨论这一机制,我们引入了几个关键术语:类型形参用于在声明时占位,等待具体类型的填充;类型变元则是在声明体中引用这些形参的标识符;类型实参则是在实际使用泛型类型或函数时提供的具体类型;而类型构造器则是指那些需要接收类型实参以完成其定义的类型。
综上所述,泛型在仓颉编程语言中是一种强大的工具,它允许我们在不牺牲类型安全的前提下,编写出更加灵活和可复用的代码。通过声明所要使用对象的类型(以类型形参的形式),并在使用时指定具体的类型实参,我们能够实现代码的泛型化,减少重复,提高开发效率。
2 . 如何声明泛型
在声明类型或函数时,类型形参通常会被放置在类型名称或函数名称之后,并使用尖括号<…>来包围,以明确标识出这些形参的存在。例如,一个泛型列表(在支持泛型的编程语言中)可以被声明为在列表类型名称后紧跟尖括号,并在尖括号内指定一个或多个类型形参,如List所示,其中T就是一个类型形参的标识符。
class List<T> {var elem: Option<T> = Nonevar tail: Option<List<T>> = None
}
在List的声明中,T被称为类型形参,它代表了一个在声明时未具体指定,而在使用时需要被替换为具体类型的占位符。对于表达式如elem: Option中的T,以及tail: Option<List>中的T,这些在泛型类型内部被引用的标识符被称为类型变元,因为它们代表了类型形参在泛型类型定义中的具体引用点。
当我们在函数或变量声明中实际使用泛型类型时,如sumInt函数的参数List,其中的Int64就被称为List的类型实参。这些类型实参是在使用泛型类型时提供的具体类型,它们替代了泛型声明中的类型形参,从而构造出了具体的类型实例。
List本身在这里被视为一个类型构造器,因为它是一个需要类型实参来构造出具体类型的泛型类型。通过提供Int64作为类型实参给List,我们构造出了一个专门用于存储Int64类型元素的列表类型,即List。这个过程展示了泛型类型如何通过类型实参的替换来生成具体的、可操作的类型实例。
3. 全局泛型函数
在声明全局泛型函数时,只需要在函数名后使用尖括号声明类型形参,然后就可以在函数形参、返回类型及函数体中对这一类型形参进行引用。例如 id 函数定义为:
func id<T>(a: T): T {return a
}
在这里,我们定义了一个名为id的泛型函数,该函数声明了一个名为a的变量作为形参,其类型由泛型类型形参T指定。a: T是函数id的形参声明,其中T是id函数声明的类型形参,它用于在函数体内引用和操作a,同时也决定了id函数的返回类型(通常id函数会返回其输入参数,因此返回类型也是T)。
接下来,考虑一个更复杂的泛型函数定义,名为composition。这个函数声明了三个类型形参:T1、T2、和T3。composition的功能是将两个函数复合成一个新的函数。具体而言,它接受两个函数f和g作为参数,其中f是一个从T1类型到T2类型的函数(即f: (T1) -> T2),而g是一个从T2类型到T3类型的函数(即g: (T2) -> T3)。通过这两个函数的组合,composition函数生成了一个新的函数,该函数的类型是从T1到T3的(即(T1) -> T3),它首先应用f函数到其输入上,然后将f的输出作为g的输入,最后返回g的输出。这样,composition函数实现了两个函数的串联调用。
func composition<T1, T2, T3>(f: (T1) -> T2, g: (T2) -> T3): (T1) -> T3 {return {x: T1 => g(f(x))}
}
因为被用来复合的函数可以是任意类型,例如可以是 (Int32) -> Bool, (Bool) -> Int64 的复合,也可以是 (Int64) -> Rune, (Rune) -> Int8 的复合,所以才需要使用泛型函数。
func times2(a: Int64): Int64 {return a * 2
}func plus10(a: Int64): Int64 {return a + 10
}func times2plus10(a: Int64) {return composition<Int64, Int64, Int64>(times2, plus10)(a)
}main() {println(times2plus10(9))return 0
}
4. 局部泛型函数
简单来说局部泛型函数就是在一个函数中嵌套另一个泛型函数
func foo(a: Int64) {func id<T>(a: T): T { a }func double(a: Int64): Int64 { a + a }return (id<Int64> ~> double)(a) == (double ~> id<Int64>)(a)
}main() {println(foo(1))return 0
}
相关文章:
仓颉编程入门 -- 泛型概述 , 如何定义泛型函数
泛型概述 , 如何定义泛型函数 1 . 泛型的定义 在仓颉编程语言中,泛型机制允许我们定义参数化类型,这些类型在声明时不具体指定其操作的数据类型,而是作为类型形参保留,待使用时通过类型实参来明确。这种灵活性在函数和类型声明中…...
SOC估算方法之(OCV-SOC+安时积分法)
一、引言 此方法主要参考电动汽车用磷酸铁锂电池SOC估算方法这篇论文 总结: 开路电压的测量需要将电池静止相当长的一段时间才能达到平衡状态进行测量。 安时积分法存在初始SOC的估算和累积的误差。 所以上述两种方法都存在一定的缺陷,因此下面主要讲…...
指针(下)
文章目录 指针(下)野指针、空指针野指针空指针 二级指针**main**函数的原型说明 常量指针与指针常量常量指针指针常量常量指针常量 动态内存分配常用函数**malloc****calloc****realloc****free** **void**与**void***的区别扩展:形式参数和实际参数的对应关系 指针…...
C# 浅谈IEnumerable
一、IEnumerable 简介 IEnumerable 是一个接口,它定义了对集合进行迭代所需的方法。IEnumerable 接口主要用于允许开发者使用foreach循环来遍历集合中的元素。这个接口定义了一个名为 GetEnumerator 的方法,该方法返回一个实现了 IEnumerator 接口的对象…...
mmdebstrap:创建 Debian 系统 chroot 环境的利器 ️
文章目录 mmdebstrap 的一般性参数说明 📜mmdebstrap 的常见用法示例 🌈使用 mmdebstrap 的注意事项 ⚠️ 🌈你好呀!我是 山顶风景独好 🎈欢迎踏入我的博客世界,能与您在此邂逅,真是缘分使然&am…...
【Linux SQLite数据库】一、SQLite交叉编译与移植
SQLite 是一个用 C 语言编写的开源、轻量级、快速、独立且高可靠性的 SQL 数据库引擎,它提供了功能齐全的数据库解决方案。SQLite 几乎可以在所有的手机和计算机上运行,它被嵌入到无数人每天都在使用的众多应用程序中。此外,SQLite 还具有稳定…...
每天写两道(数组篇)移除元素、
27.移除元素 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作&#…...
Unity 使用 NewtonSoft Json插件报错
JsonReaderException: Unexpected character encountered while parsing value: . Path , line 0, position 0. 通过断点发现,头有一串ZWNBSP,这个是BOM格式的JSON。在文件下看不到。 解决方法:改编码格式,Remove BOM....
k8s 部署 Mysqld_exporter 以及添加告警规则
最近监控 mysql 数据库,用了 pmm-server、pmm-client 发现监控是真的不太好用,还是用回 prometheus 吧。 部署mysqld_exporter k8s 部署最新版本的 mysqld_exporter,支持的数据库版本 MySQL >5.6、MariaDB > 10.3。 先在数据库创建用…...
基于STM32开发的智能农业环境监测系统
目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码控制代码应用场景 农田环境监测温室环境控制常见问题及解决方案 常见问题解决方案结论 1. 引言 智能农业环境监测系统通过集成多种环境传感器,实时监测土壤湿度、温度…...
【SQL】平均售价
目录 题目 分析 代码 题目 表:Prices ------------------------ | Column Name | Type | ------------------------ | product_id | int | | start_date | date | | end_date | date | | price | int | ---------------…...
存储器与CPU的连接
1.单块存储芯片与CPU的连接 单独的一块独立的存储芯片提供的线有:地址总线,数据总线,读写控制线,片选线,如果该存储器只有八根数据总线用于输出数据,而cpu一次可以读64位的数据呢? 我们可以将八…...
unity--webgl 访问本地index.html
目录 1:使用本地服务器 1.1 使用 Python 的 SimpleHTTPServer 1.2 使用 Node.js 的 http-server 2:让其他人通过 IP 地址来访问你的 Unity WebGL 项目 2.1: 确保服务器可访问 2.2 获取公共 IP 地址 2.3 配置本地服务器 1.使用 Python 的 SimpleHTTPServer 2…...
慢慢欣赏DPDK RTE_MAX_ETHPORTS的定义
DPDK代码里面,RTE_MAX_ETHPORTS是一个常见的宏定义,但是在.c和.h文件找不到其定义,在全文件搜索条件下,在config/meson.build找到这么一个定义 dpdk_conf.set(RTE_MAX_ETHPORTS, get_option(max_ethports)) 该宏定义是根据构建输…...
Java Nacos与Gateway的使用
Java系列文章目录 IDEA使用指南 Java泛型总结(快速上手详解) Java Lambda表达式总结(快速上手详解) Java Optional容器总结(快速上手图解) Java 自定义注解笔记总结(油管) Jav…...
前端项目中的Server-sent Events(SSE)项目实践及其与websocket的区别
前端项目中的Server-sent Events(SSE)项目实践 前言 在前端开发中,实时数据更新是提升用户体验的重要因素之一。Server-SentEvents(SSE)是一种高效的技术,允许服务器通过单向连接将实时数据推送到客户端。下面将从SSE的基本改变,使用场景展…...
《老俞闲话|唯爱和热情不可辜负》读后感
《老俞闲话|唯爱和热情不可辜负》读后感 俞敏洪先生的这篇讲话充满了深情与智慧,他以自己丰富的人生经历和教育实践,向我们展现了一位教育家对于教育事业的热爱和对教师角色的深刻理解。 情感真挚,触动人心 俞敏洪先生的讲话中流…...
C语言 ——— 在杨氏矩阵中查找具体的某个数
目录 何为杨氏矩阵 题目要求 代码实现 何为杨氏矩阵 可以把杨氏矩阵理解为一个二维数组,这个二维数组中的每一行从左到右是递增的,每一列从上到下是递增的 题目要求 在杨氏矩阵中查找具体的某个数 要求:时间复杂度小于O(N) 代码实现…...
DAI-Net: 基于对偶自适应交互网络的药物推荐算法
引言 DAI-Net: Dual Adaptive Interaction Network for Coordinated Medication Recommendation 论文链接:https://ieeexplore.ieee.org/document/10614809 代码链接:GitHub - obananas/DAI-Net 在现代医疗保健中,如何利用电子健康记录&a…...
haproxy高级功能及配置
章节 一、haproxy 基础用法 二、haproxy 高级用法 三、haproxy之ACL的使用 目录 1 基于cookie的会话保持 1.1 cookie命名,并赋予其值 1.2 验证cookie信息 1.2.1 Windows浏览器验证 1.2.2 Linux下虚拟机验证 2 IP透传 2.1 四层与七层透传的区别 2.2 七层IP透传 2.2…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
