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

embedded/2024/10/19 7:28:36/

泛型概述 , 如何定义泛型函数

1 . 泛型的定义

在这里插入图片描述

仓颉编程语言中,泛型指的是参数化类型,参数化类型是一个在声明时未知并且需要在使用时指定的类型。类型声明与函数声明可以是泛型的。最为常见的例子就是 Array、Set 等容器类型。以数组类型为例,当使用数组类型 Array 时,会需要其中存放的是不同的类型,我们不可能定义所有类型的数组,通过在类型声明中声明类型形参,在应用数组时再指定其中的类型,这样就可以减少在代码上的重复。

仓颉中,class、interface、struct 与 enum 的声明都可以声明类型形参,也就是说它们都可以是泛型的。

为了方便讨论我们先定义以下几个常用的术语:

  • 类型形参:一个类型或者函数声明可能有一个或者多个需要在使用处被指定的类型,这些类型就被称为类型形参。在声明形参时,需要给定一个标识符,以便在声明体中引用。
  • 类型变元:在声明类型形参后,当我们通过标识符来引用这些类型时,这些标识符被称为类型变元。
  • 类型实参:当我们在使用泛型声明的类型或函数时指定了泛型参数,这些参数被称为类型实参。
  • 类型构造器:一个需要零个、一个或者多个类型作为实参的类型称为类型构造器。

简而言之泛型就是声明所要使用对象的类型

2 . 如何声明泛型

类型形参在声明时一般在类型名称的声明或者函数名称的声明后,使用尖括号 <…> 括起来。例如泛型列表可声明为:

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 就是类型构造器,List 通过 Int64 类型实参构造出了一个类型 Int64 的列表类型。

3. 全局泛型函数

在声明全局泛型函数时,只需要在函数名后使用尖括号声明类型形参,然后就可以在函数形参、返回类型及函数体中对这一类型形参进行引用。例如 id 函数定义为:

func id<T>(a: T): T {return a
}

在这里我们声明了一个函数名为id的函数 , 同时给该函数定义了一个变量名为a , 类型为T 的变量

其中 (a: T) 是函数声明的形参,其中使用到了 id 函数声明的类型形参 T,并且在 id 函数的返回类型使用。

再比如另一个复杂的例子,定义如下一个泛型函数 composition,该函数声明了 3 个类型形参,分别是 T1, T2, T3,其功能是把两个函数 f: (T1) -> T2, g: (T2) -> T3 复合成类型为 (T1) -> T3 的函数。

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
}

http://www.ppmy.cn/embedded/94606.html

相关文章

知识增强的大语言模型

王海峰 百度 先从人工智能讲起&#xff1a; 大模型的出现&#xff0c;让人看到AGI的曙光 一是技术通用&#xff0c;二是能力全面 人工智能技术演进&#xff1a; 规则由人工撰写统计机器学习时代&#xff1a;自动学习&#xff0c;但算法模型仍需结合实际选择深度学习&#x…

FPC外观缺陷以及瑕疵检测

在电子元器件产业中&#xff0c;FPC占据非常重要地位。 一般来说&#xff0c;FPC是用柔性的绝缘基材制成的印刷电路&#xff0c;具有许多硬性印刷电路板不具备的优点。易弯曲、卷绕、折叠。但由于FPC具有易变形的特点&#xff0c;在加工的过程中易由静电和空气压力等因素产生弯…

【问题解决】apache.poi 3.1.4版本升级到 5.2.3,导出文件报错版本无法解析

【问题解决】apache.poi 3.1.4版本升级到 5.2.3&#xff0c;导出文件报错无法解析 3.1.4版本代码&#xff1a; /*** 创建workbook* param inp* return* throws Exception*/public Workbook createworkbook(InputStream inp) throws Exception {if (!inp.markSupported()) {inp…

前端各种文本文件预览 文本编辑excel预览编辑 pdf预览word预览 excel下载pdf下载word下载

前端各种文本文件预览 文本编辑excel预览编辑 pdf预览word预览 excel下载pdf下载word下载 各种文本文件预览&#xff08;pdf, xlsx, docx, cpp, java, sql, py, vue, html, js, json, css, xml, rust, md, txt, log, fa, fasta, tsv, csv 等各种文本文件&#xff09; 其中 除p…

MyBatis 配置与测试方式

目录 一&#xff0c;什么是MyBatis 二&#xff0c;准备工作 创建项目 配置数据库连接 持久层代码 单元测试 一&#xff0c;什么是MyBatis 简单来说&#xff0c;MyBatis 是一款优秀的持久层框架&#xff0c;用于简化JDBC的开发&#xff0c;能更简单完成程序与数据库之间…

“AI+Security”系列第2期(一):对抗!大模型自身安全的攻防博弈

近日&#xff0c;由安全极客、Wisemodel 社区和 InForSec 网络安全研究国际学术论坛联合主办的“AISecurity”系列第 2 期——对抗&#xff01;大模型自身安全的攻防博弈线上活动如期举行。本次活动邀请了君同未来创始人兼 CEO 韩蒙、前阿里云高级安全专家郑瀚、ChaMd5 AI 组负…

git 提交到远程仓库了怎么撤回

有多种方式撤回&#xff0c;以下这种方式算是最安全的一种方式&#xff0c;原理是通过创建一个新的提交来“反做”之前的提交。这不会改变项目的历史记录 1. **查找提交**: - 使用 git log -n 10 查看历史提交的hash值 2. **找到要撤回的提交**: - 在输出中找到你想要撤…

江科大/江协科技 STM32学习笔记P21

文章目录 ADC模数转换器ADC简介逐次逼近型ADCSTM32的ADCADC基本结构输入通道转换模式单次转换&#xff0c;非扫描模式连续转换&#xff0c;非扫描模式单次转换&#xff0c;扫描模式连续转换&#xff0c;扫描模式 触发控制数据对齐转换时间校准硬件电路电位器产生可调电压的电路…