0. 版本介绍
本版本为Cangjie语言LTS 1.0.0版本的更新版本(LTS版本定义及维护周期详见仓颉社区版本生命周期管理规范,版本号为Cangjie 1.0.4,主要解决部分发现的Bug,以及对某些功能进行优化。版本包含了仓颉应用开发必须的能力,包括编译器,运行时,标准库,和工具链。欢迎各位开发者使用,如有任何问题,欢迎在Cangjie社区提出issue,我们会第一时间处理。以下介绍本版本相比LTS 1.0.3版本的更新。
1. 语言特性
无特性新增。
2. 编译器
本版本仅修复问题,无特性新增。修复问题如下:
- 【issue-105】let变量在lambda中被赋值了两次,未编译报错
- 【issue-2591】当同一个包不同文件中存在同名私有函数时,无法编译
- 【issue-2533】项目cjpm build -g编译失败,cjpm test --coverage编译崩溃,报错Error Code: 13
- 【issue-2565】【缺陷】Option
作为返回值时,当T为Array,ArrayList时,多层API调用时返回值不对
3. 运行时
本版本仅修复问题,无特性新增。修复问题如下:
- 【issue-2395】新项目MacOS26报SG_READ_ONLY缺失,修复MacOS26编译失败问题
- 【issue-2649】在运行GC场景中,长时间压测情况下,偶现cangjie进程卡死现象问题解决
4. 标准库
本版本仅修复问题,无特性新增。修复问题如下:
- 【issue-2242】修复在Timer的定时任务中调用cancel()时后不能以预期的方式取消的问题
- 【issue-2408】修复TreeMap和TreeSet中出现同一key值多次出现的问题
5. 工具链
1 IDE插件
本版本仅修复问题,无特性新增。修复问题如下:
- 【issue-1961】codeArts编译错误信息的中文内容显示为
- 【issue-6】codeArts编译错误信息的中文内容显示为乱码
2 cjpm
新增支持lto-combined功能,详情请参见工具指南。
本版本修复问题如下:
- 【issue-2373】优化cjpm init报错信息
- 【issue-2650】交叉编译场景下,cjpm宏包依赖出现错误
3 cjdb
无变化。
4 cjfmt
本版本仅修复问题,无特性新增:修复问题如下:
- 【issue-2385】cjfmt文档缺少cangjie-format.toml配置的介绍
5 cjlint
本版本仅修复问题,无特性新增:修复问题如下:
- 【issue-2433】cjlint的G.VAR.02规则误报,预期无警告
6 cjcov
无变化。
7 cjprof
无变化。
8 cjtrace-recover
无变化。
6. 遗留问题
在lambda body 体内修改lambda 参数,编译崩溃
【问题现象】在lambda body体内误修改lambda 参数,可能会导致 ICE,ErrorCode 为12。
【规避措施】不要错误的在lambda body体内修改lambda 参数
调用被扩展的接口函数的部分场景会导致运行时崩溃的问题
【问题现象】当存在一个泛型类 A 扩展了某个泛型接口 I,且存在另一个非泛型类 B 继承了实例化版本的类 A,将 B 的实例赋值给 I 类型变量且调用接口 I 函数时可能导致运行时崩溃。 样例:
interface I<T> {
func foo() {}
}
open class A<T> {}
extend<T> A<T> <: I<T> {}
class B <: A<Int64> {}
main() {
let i: I<Int64> = B()
i.foo() // 此处调用会发生运行阶段崩溃
return 0
}
【规避措施】 方案一:若类 A 定义在本包,可以不使用扩展,通过 A 直接继承接口 I 以规避该问题。 规避样例:
interface I<T> {
func foo() {}
}
open class A<T> <: I<T> {} // 使 A 继承 I
open class B <: A<Int64> {}
main() {
let i: I<Int64> = B()
i.foo()
return 0
}
方案二:若类 A 是导入自其它包,可以将类B定义为泛型类以规避该问题。 规避样例:
import pkgA.A
interface I<T> {
func foo() {}
}
extend<T> A<T> <: I<T> {}
open class B<T> <: A<T> {} // 将类 B 定义为泛型类
main() {
let i: I<Int64> = B<Int64>()
i.foo()
return 0
}
7. 文档变更说明
开发指南
- 程序结构章节新增说明:函数和lambda中的静态成员变量赋值,编译器无法判断函数或者lambda是否会被执行,因此采用保守策略,即编译报错。
- 普通try表达式中新增说明:当在try块中可能发生内存溢出错误时,应避免在catch或finally块中执行任何内存分配操作,以免再次触发溢出并导致未定义行为。一旦检测到内存溢出,建议在catch块中立即终止程序(例如调用exit函数),以确保系统稳定性并防止进一步错误。
- 新增编译选项--compile-as-exe相关内容。
标准库API
- 无变化。
工具指南
- 格式化工具cjfmt章节新增说明:CANGJIE_HOME环境下的默认格式化工具配置文件路径为CANGJIE_HOME/tools/config。
- cjpm工具中的模块配置文件说明增加支持工程级LTO相关说明。
初识仓颉语言
仓颉编程语言是一种面向全场景应用开发的通用编程语言,可以兼顾开发效率和运行性能,并提供良好的编程体验,主要具有如下特点:
- 多后端支持:仓颉编程语言支持 CJNative 和 CJVM 两种后端。其中 CJNative 后端将代码编译为原生二进制代码,直接在操作系统层面上运行;CJVM 后端将代码编译为字节码,基于 VM(虚拟机)进行运行。本次发布仅提供 CJNative 后端 SDK,CJVM 后端 SDK 敬请期待。
- 语法简明高效:仓颉编程语言提供了一系列简明高效的语法,旨在减少冗余书写、提升开发效率,例如插值字符串、主构造函数、Flow 表达式、
match和重导出等语法,让开发者可以用较少编码表达相关逻辑。 - 多范式编程:仓颉编程语言支持函数式、命令式和面向对象等多范式编程,融合了高阶函数、代数数据类型、模式匹配、泛型等函数式语言的先进特性,还有封装、接口、继承、子类型多态等支持模块化开发的面向对象语言特性,以及值类型、全局函数等简洁高效的命令式语言特性。开发者可以根据开发偏好或应用场景,选用不同的编程范式。
- 类型安全:仓颉编程语言是静态强类型语言,通过编译时类型检查尽早识别程序错误,降低运行时风险,也便于代码维护。同时,仓颉编译器提供了强大的类型推断能力,可以减少类型标注工作,提高开发效率。
- 内存安全:仓颉编程语言支持自动内存管理,并在运行时进行数组下标越界检查、溢出检查等操作,确保运行时内存安全。
- 高效并发:仓颉编程语言提供了用户态轻量化线程(原生协程),以及简单易用的并发编程机制,保证并发场景的高效开发和运行。
- 兼容语言生态:仓颉编程语言支持和 C 等编程语言的互操作,并采用便捷的声明式编程范式,可实现对其他语言库的高效复用和生态兼容。
- 领域易扩展:仓颉编程语言提供了基于词法宏的元编程能力,支持在编译时变换代码。此外,还提供了尾随
lambda、属性、操作符重载、部分关键字可省略等特性,开发者可由此深度定制程序的语法和语义,这有利于内嵌式领域专用语言(Embedded Domain Specific Languages,EDSL)的构建。 - 助力 UI 开发:UI 开发是构建端侧应用的重要环节,基于仓颉编程语言的元编程和尾随
lambda等特性,用户可以搭建声明式 UI 开发框架,提升 UI 开发效率和体验。 - 内置库功能丰富:仓颉编程语言提供了功能丰富的内置库,涉及数据结构、常用算法、数学计算、正则匹配、系统交互、文件操作、网络通信、数据库访问、日志打印、解压缩、编解码、加解密和序列化等功能。
安装仓颉工具链
在开发仓颉程序时,必用的工具之一是仓颉编译器,它可以将仓颉源代码编译为可运行的二进制文件,但现代编程语言的配套工具并不止于此,实际上,仓颉为开发者提供了编译器、调试器、包管理器、静态检查工具、格式化工具和覆盖率统计工具等一整套仓颉开发工具链,同时提供了友好的安装和使用方式,基本能做到“开箱即用”。
目前仓颉工具链已适配部分版本的 Linux、macOS 和 Windows 平台,但是仅针对部分 Linux 发行版做了完整功能测试,详情可参阅附录Linux 版本工具链的支持与安装章节,在暂未进行过完整功能测试的平台上,仓颉工具链的功能完整性不受到保证。此外,当前 Windows 平台上的仓颉编译器基于 MinGW 实现,相较于 Linux 版本的仓颉编译器,功能会有部分欠缺。
Linux / macOS
环境准备
Linux
Linux 版仓颉工具链的系统环境要求如下:
| 架构 | 环境要求 |
|---|---|
| x86_64 | glibc 2.22,Linux Kernel 4.12 或更高版本,系统安装 libstdc++ 6.0.24 或更高版本 |
| aarch64 | glibc 2.27,Linux Kernel 4.15 或更高版本,系统安装 libstdc++ 6.0.24 或更高版本 |
除此之外,对于 Ubuntu 18.04,还需要安装相应的依赖软件包:
$ apt-get install binutils libc-dev libc++-dev libgcc-7-dev
更多 Linux 发行版的依赖安装命令可以参见附录Linux 版本工具链的支持与安装章节。
此外,仓颉工具链还依赖 OpenSSL 3 组件,由于该组件可能无法从以上发行版的默认软件源直接安装,因此需要自行手动安装,安装方式请参见附录Linux 版本工具链的支持与安装章节。
macOS
macOS 版仓颉工具链支持在 macOS 12.0 及以上版本(aarch64 架构)运行。
使用 macOS 版本前需要安装相应的依赖软件包,可以通过执行以下命令安装:
$ brew install libffi
安装指导
首先请前往仓颉官网,下载适配平台架构的安装包:
cangjie-sdk-linux-x64-x.y.z.tar.gz:适用于 x86_64 架构 Linux 系统的仓颉工具链cangjie-sdk-linux-aarch64-x.y.z.tar.gz:适用于 aarch64 架构 Linux 系统的仓颉工具链cangjie-sdk-mac-aarch64-x.y.z.tar.gz:适用于 aarch64/arm64 架构 macOS 系统的仓颉工具链
假设这里选择了 cangjie-sdk-linux-x64-x.y.z.tar.gz,下载到本地后,请执行如下命令解压:
tar xvf cangjie-sdk-linux-x64-x.y.z.tar.gz
解压完成,可以在当前工作路径下看到一个名为 cangjie 的目录,其中存放了仓颉工具链的全部内容,请执行如下命令完成仓颉工具链的安装配置:
source cangjie/envsetup.sh
为了验证是否安装成功,可以执行如下命令:
cjc -v
其中 cjc 是仓颉编译器的可执行文件名,如果在命令行中看到了仓颉编译器版本信息,表示已经成功安装了仓颉工具链。值得说明的是,envsetup.sh 脚本只是在当前 shell 环境中配置了工具链相关的环境变量,所以仓颉工具链仅在当前 shell 环境中可用,在新的 shell 环境中,需要重新执行 envsetup.sh 脚本配置环境。
若想使仓颉工具链的环境变量配置在 shell 启动时自动生效,可以在 $HOME/.bashrc 或 $HOME/.zshrc(依 shell 种类而定)等 shell 初始化配置文件的最后加入以下命令:
# 假设仓颉安装包解压在 /home/user/cangjie 中
source /home/user/cangjie/envsetup.sh # 即 envsetup.sh 的绝对路径
配置完成后 shell 启动即可直接使用仓颉编译工具链。
卸载与更新
在 Linux 和 macOS 平台,删除上述仓颉工具链的安装包目录,同时移除上述环境变量(最简单的,可以新开一个 shell 环境),即可完成卸载。
$ rm -rf <path>/<to>/cangjie
若需要更新仓颉工具链,需要先卸载当前版本,然后按上述指导重新安装最新版本的仓颉工具链。
Windows
本节以 Windows 10 平台为例,介绍仓颉工具链的安装方式。
安装指导
在 Windows 平台上,仓颉为开发者提供了 exe 和 zip 两种格式的安装包,请前往仓颉官网,选择和下载适配平台架构的 Windows 版安装包。
-
如果选择
exe格式的安装包(例如cangjie-sdk-windows-x64-x.y.z.exe),请直接执行此文件,跟随安装向导点击操作,即可完成安装。 -
如果选择
zip格式的安装包(例如cangjie-sdk-windows-x64-x.y.z.zip),请将它解压到适当目录,在安装包中,仓颉为开发者提供了三种不同格式的安装脚本,分别是envsetup.bat,envsetup.ps1和envsetup.sh,可以根据使用习惯及环境配置,选择一种执行:-
若使用 Windows 命令提示符(CMD)环境,请执行:
path\to\cangjie\envsetup.bat -
若使用 PowerShell 环境,请执行:
. path\to\cangjie\envsetup.ps1 -
若使用 MSYS shell、bash 等环境,请执行:
source path/to/cangjie/envsetup.sh
为了验证是否安装成功,请在以上命令环境中继续执行
cjc -v命令,如果输出了仓颉编译器版本信息,表示已经成功安装了仓颉工具链。 -
值得注意的是,基于 zip 安装包和执行脚本的安装方式,类似于 Linux 平台,即 envsetup 脚本所配置的环境变量,只在当前命令行环境中有效,如果打开新的命令行窗口,需要重新执行 envsetup 脚本配置环境。此时,若想使仓颉工具链的环境变量配置在命令提示符或终端启动时自动生效,可以对系统进行如下配置:
-
若使用 bash 环境,可以根据如下步骤操作:
在
$HOME/.bashrc初始化配置文件的最后加入以下命令($HOME为当前用户目录的路径):# 假设仓颉安装包解压在 /home/user/cangjie 中 source /home/user/cangjie/envsetup.sh # 即 envsetup.sh 的绝对路径配置完成后 bash 启动即可直接使用仓颉编译工具链。
-
若使用 Windows 命令提示符(CMD)、PowerShell 或其他环境,可以根据如下步骤操作:
-
在 Windows 搜索框中,搜索 “查看高级系统设置” 并打开对应窗口;
-
单击 “环境变量” 按钮;
-
执行如下操作,配置 CANGJIE_HOME 变量:
-
在 “用户变量”(为当前用户进行配置)或 “系统变量”(为系统所有用户进行配置)区域中,查看是否已有 CANGJIE_HOME 环境变量。若没有,则单击 “新建” 按钮,并在 “变量名” 字段中输入
CANGJIE_HOME;若有,则说明该环境可能已经进行过仓颉配置,如果想要继续为当前的仓颉版本进行配置并覆盖原配置,请点击 “编辑” 按钮,进入 “编辑系统变量” 窗口。 -
在 “变量值” 字段中输入仓颉安装包的解压路径,若原先已经存在路径,则使用新的路径覆盖原有的路径,例如仓颉安装包解压在
D:\cangjie,则输入D:\cangjie。 -
配置完成后, “编辑用户变量” 或 “编辑系统变量” 窗口中显示的变量名为
CANGJIE_HOME、变量值为D:\cangjie。确认路径正确配置后单击 “确定” 。
-
-
执行如下操作,配置 Path 变量:
-
在 “用户变量”(为当前用户进行配置)或 “系统变量”(为系统所有用户进行配置)区域中,找到并选择 Path 变量,单击 “编辑” 按钮,进入 “编辑环境变量” 窗口。
-
分别单击 “新建” 按钮,并分别输入
%CANGJIE_HOME%\bin、%CANGJIE_HOME%\tools\bin、%CANGJIE_HOME%\tools\lib、%CANGJIE_HOME%\runtime\lib\windows_x86_64_llvm(%CANGJIE_HOME%为仓颉安装包的解压路径)。例如,仓库安装包解压在D:\cangjie,则新建的环境变量分别为:D:\cangjie\bin、D:\cangjie\tools\bin、D:\cangjie\tools\lib、D:\cangjie\runtime\lib\windows_x86_64_llvm。 -
(仅适用于为当前用户设置)单击 “新建” 按钮,并输入当前用户目录路径,并在路径后面添加
.cjpm\bin。例如用户路径在C:\Users\bob,则输入C:\Users\bob\.cjpm\bin。 -
配置完成后应能在 “编辑环境变量” 窗口中看到配置的路径如下所示。确认路径正确配置后单击 “确定” 。
D:\cangjie\bin D:\cangjie\tools\bin D:\cangjie\tools\lib D:\cangjie\runtime\lib\windows_x86_64_llvm C:\Users\bob\.cjpm\bin
-
-
单击 “确定” 按钮,退出 “环境变量” 窗口。
-
单击 “确定” 按钮,完成设置。
注意:
设置完成后可能需要重启命令行窗口或重启系统以让设置生效。
配置完成后 Windows 命令提示符(CMD)或 PowerShell 启动即可直接使用仓颉编译工具链。
-
卸载与更新
-
如果选择
exe格式的安装包进行的安装,运行仓颉安装目录下的unins000.exe可执行文件,跟随卸载向导点击操作,即可完成卸载。 -
如果选择
zip格式的安装包进行的安装,删除仓颉工具链的安装包目录,同时移除上述环境变量设置(若有),即可完成卸载。
若需要更新仓颉工具链,需要先卸载当前版本,然后按上述指导重新安装最新版本的仓颉工具链。
运行第一个仓颉程序
万事俱备,开始编写和运行第一个仓颉程序吧!
首先,请在适当目录下新建一个名为 hello.cj 的文本文件,并向文件中写入以下仓颉代码:
// hello.cj
main() {
println("你好,仓颉")
}
在这段代码中,使用了仓颉的注释语法,可以在 // 符号之后写单行注释,也可以在一对 /* 和 */ 符号之间写多行注释,这与 C/C++ 等语言的注释语法相同。注释内容不影响程序的编译和运行。
然后,请在此目录下执行如下命令:
cjc hello.cj -o hello
这里仓颉编译器会将 hello.cj 中的源代码编译为此平台上的可执行文件 hello,在命令行环境中运行此文件,将看到程序输出了如下内容:
你好,仓颉
注意:
以上编译命令是针对 Linux 和 macOS 平台的,如果使用 Windows 平台,只需要将编译命令改为
cjc hello.cj -o hello.exe即可。
标识符
在仓颉编程语言中,开发者可以给一些程序元素命名,这些名字被称为“标识符”。
学习标识符之前,需要了解一些 Unicode 字符集概念。在 Unicode 标准中,XID_Start 和 XID_Continue 属性用于标记可以作为 Unicode 标识符(Identifier)的起始字符和后续字符,其详细定义请参见 Unicode 标准文档。其中, XID_Start 包含中文和英文等字符,XID_Continue 包含中文、英文和阿拉伯数字等字符。仓颉语言使用 Unicode 标准 15.0.0 。
仓颉编程语言的标识符分为普通标识符和原始标识符两类,它们遵从不同的命名规则。
普通标识符不能和仓颉关键字相同,其取自以下两类字符序列:
- 由
XID_Start字符开头,后接任意长度的XID_Continue字符。 - 由一个
_开头,后接至少一个XID_Continue字符。
仓颉把所有标识符识别为 Normalization Form C (NFC) 后的形式。两个标识符如果在 NFC 后相等,则被认为是相同的标识符。
例如,以下每行字符串都是合法的普通标识符:
abc
_abc
abc_
a1b2c3
a_b_c
a1_b2_c3
仓颉
__こんにちは
以下每行字符串都是不合法的普通标识符:
ab&c // & 不是 XID_Continue 字符
3abc // 阿拉伯数字不是 XID_Start 字符,因此,数字不能作为起始字符
_ // _ 后至少需要有一个 XID_Continue 字符
while // while 是仓颉关键字,普通标识符不能使用仓颉关键字
原始标识符是在普通标识符或仓颉关键字的首尾加上一对反引号,主要用于将仓颉关键字作为标识符的场景。
例如,以下每行字符串都是合法的原始标识符:
`abc`
`_abc`
`a1b2c3`
`if`
`while`
`à֮̅̕b`
以下每行字符串,由于反引号内的部分是不合法的普通标识符,所以它们整体也是不合法的原始标识符:
`ab&c`
`3abc`
程序结构
通常,开发者会在扩展名为 .cj 的文本文件中编写仓颉程序,这些程序和文件也被称为源代码和源文件。在程序开发的最后阶段,这些源代码将被编译为特定格式的二进制文件。
在仓颉程序的顶层作用域中,可以定义一系列的变量、函数和自定义类型(如 struct、class、enum 和 interface 等),其中的变量和函数分别被称为全局变量和全局函数。如果要将仓颉程序编译为可执行文件,需要在顶层作用域中定义一个 main 函数作为程序入口,它可以有 Array<String> 类型的参数,也可以没有参数,它的返回值类型可以是整数类型或 Unit 类型。
注意:
定义
main函数时,不需要写func修饰符。此外,如果需要获取程序启动时的命令行参数,可以声明和使用Array<String>类型参数。
例如,在以下程序中,在顶层作用域定义了全局变量 a 和全局函数 b,还有自定义类型 C、D 和 E,以及作为程序入口的 main 函数。
// example.cj
let a = 2023
func b() {}
struct C {}
class D {}
enum E { F | G }
main() {
println(a)
}
在非顶层作用域中不能定义上述自定义类型,但可以定义变量和函数,称之为局部变量和局部函数。特别地,对于定义在自定义类型中的变量和函数,称之为成员变量和成员函数。
注意:
enum和interface中仅支持定义成员函数,不支持定义成员变量。
例如,在以下程序中,在顶层作用域定义了全局函数 a 和自定义类型 A,在函数 a 中定义了局部变量 b 和局部函数 c,在自定义类型 A 中定义了成员变量 b 和成员函数 c。
// example.cj
func a() {
let b = 2023
func c() {
println(b)
}
c()
}
class A {
let b = 2024
public func c() {
println(b)
}
}
main() {
a()
A().c()
}
运行以上程序,将输出:
2023
2024
变量
在仓颉编程语言中,一个变量由对应的变量名、数据(值)和若干属性构成,开发者通过变量名访问变量对应的数据,但访问操作需要遵从相关属性的约束(如数据类型、可变性和可见性等)。
变量定义的具体形式为:
修饰符 变量名: 变量类型 = 初始值
其中修饰符用于设置变量的各类属性,可以有一个或多个,常用的修饰符包括:
- 可变性修饰符:
let与var,分别对应不可变和可变属性,可变性决定了变量被初始化后其值还能否改变,仓颉变量也由此分为不可变变量和可变变量两类。 const修饰符:const是一种特殊的变量修饰符。它用于声明常量,要求在声明时必须初始化,一旦被赋值,其值就不能被改变。这与let修饰符类似,都具有不可变的特性,但const在使用上有更严格的限制。- 可见性修饰符:
private与public等,影响全局变量和成员变量的可引用范围,详见后续章节的相关介绍。 - 静态性修饰符:
static,影响成员变量的存储和引用方式,详见后续章节的相关介绍。
变量均支持赋值操作符(=),与类型无关。let 修饰的变量只能被赋值一次,即初始化;var 修饰的变量可以被多次赋值。
在定义仓颉变量时,可变性修饰符是必要的,在此基础上,还可以根据需要添加其他修饰符。
- 变量名应是一个合法的仓颉标识符。
- 变量类型指定了变量所持有数据的类型。当初始值具有明确类型时,可以省略变量类型标注,此时编译器可以自动推断出变量类型。
- 初始值是一个仓颉表达式,用于初始化变量,如果标注了变量类型,需要保证初始值类型和变量类型一致。在定义全局变量或静态成员变量时,必须指定初始值。在定义局部变量或实例成员变量时,可以省略初始值,但需要标注变量类型,同时要在此变量被引用前完成初始化,否则编译会报错。
例如,下列程序定义了三个 Int64 类型的变量(分别为不可变变量 a 、可变变量 b 和 const 变量 c )。随后修改了变量 b 的值,同时将 b 的值赋值给a,并调用 println 函数打印 a, b 和c 的值。
main() {
let a: Int64
var b: Int64 = 14
const c: Int64 = 13
b = 12
a = b // A variable modified by let can only be assigned once, that is, initialized
println("${a}, ${b}, ${c}")
}
编译运行此程序,将输出:
12, 12, 13
如果尝试修改不可变变量,编译时会报错,例如:
main() {
let pi: Float64 = 3.14159
pi = 2.71828 // Error, cannot assign to immutable value
}
当初始值具有明确类型时,可以省略变量类型标注,例如:
main() {
let a: Int64 = 2023
let b = a
println("a - b = ${a - b}")
}
其中变量 b 的类型可以由其初值 a 的类型自动推断为 Int64,所以此程序也可以被正常编译和运行,将输出:
a - b = 0
在定义局部变量时,可以不进行初始化,但一定要在变量被引用前赋予初值,例如:
main() {
let text: String
text = "仓颉造字"
println(text)
}
编译运行此程序,将输出:
仓颉造字
在定义全局变量和静态成员变量时必须初始化,否则编译会报错,例如:
let global: Int64 // Error, variable in top-level scope must be initialized
main(): Unit{
}
class Player {
static let score: Int32 // Error, static variable 'score' needs to be initialized when declaring
}
需要注意的是,当编译器无法判断某些场景是否一定会被初始化或无法判断是否重复初始化了不可变变量时,会倾向于保守策略进行编译报错,见如下示例:
func calc(a: Int32){
println(a)
return a * a
}
main() {
let a: String
if(calc(32) == 0){
a = "1"
}
a = "2" // Error, cannot assign to immutable value
}
对于函数和 lambda 中进行的静态成员变量赋值,编译器无法判断函数或者 lambda 是否会执行,会倾向于保守策略进行编译报错,见如下示例:
func foo(a: () -> Unit) {
// do something
}
class A {
public static var ctx: Int64 // error: the static member variable 'ctx' is not initialized
static init() {
let lambda1 = {=> ctx = 10}
foo(lambda1)
}
}
main() {}
此外,对于 try-catch 场景,编译器会假设 try 块总是全部被执行,且总是抛异常,从而进行相关报错,见如下示例:
main() {
let a: String
try {
a = "1"
} catch (_) {
a = "2" // Error, cannot assign to immutable value
}
}
const 变量
const 变量是一种特殊的变量,它以关键字 const 修饰,定义在编译时完成求值,并且在运行时不可改变的变量。例如,下面的例子定义了万有引力常数 G:
const G = 6.674e-11
const 变量可以省略类型标注,但是不可省略初始化表达式。const 变量可以是全局变量,局部变量,静态成员变量。但是 const 变量不能在扩展中定义。const 变量可以访问对应类型的所有实例成员,也可以调用对应类型的所有非 mut 实例成员函数。
下例定义了一个 struct,记录行星的质量和半径,同时定义了一个 const 成员函数 gravity 用来计算该行星对距离为 r 质量为 m 的物体的万有引力:
struct Planet {
const Planet(let mass: Float64, let radius: Float64) {}
const func gravity(m: Float64, r: Float64) {
G * mass * m / r**2
}
}
main() {
const myMass = 71.0
const earth = Planet(5.972e24, 6.378e6)
println(earth.gravity(myMass, earth.radius))
}
编译执行得到地球对地面上一个质量为 71 kg 的成年人的万有引力:
695.657257
const 变量初始化后该类型实例的所有成员都是 const 的(深度 const,包含成员的成员),因此不能被用于左值。
main() {
const myMass = 71.0
myMass = 70.0 // Error, cannot assign to immutable value
}
值类型和引用类型变量
从编译器实现层面看,任何变量总会关联一个值(一般是通过内存地址/寄存器关联),只是在使用时,对有些变量,将直接取用这个值本身,这被称为值类型变量;而对另一些变量,将这个值作为索引、取用这个索引指示的数据,这被称为引用类型变量。值类型变量通常在线程栈上分配,每个变量都有自己的数据副本;引用类型变量通常在进程堆中分配,多个变量可引用同一数据对象,对一个变量执行的操作可能会影响其他变量。
从语言层面看,值类型变量对它所绑定的数据/存储空间是独占的,而引用类型变量所绑定的数据/存储空间可以和其他引用类型变量共享。
基于上述原理,在使用值类型变量和引用类型变量时,会存在一些行为差异,以下几点值得注意:
- 在给值类型变量赋值时,一般会产生拷贝操作,且原来绑定的数据/存储空间会被覆盖。在给引用类型变量赋值时,只是改变了引用关系,原来绑定的数据/存储空间不会被覆盖。
- 用
let定义的变量,要求变量被初始化后都不能再赋值。对于引用类型,这只是限定了引用关系不可改变,但是所引用的数据是可以被修改的。
在仓颉编程语言中,class 和 Array 等类型属于引用类型,其他基础数据类型和 struct 等类型属于值类型。
例如,以下程序演示了 struct 和 class 类型变量的行为差异:
struct Copy {
var data = 2012
}
class Share {
var data = 2012
}
main() {
let c1 = Copy()
var c2 = c1
c2.data = 2023
println("${c1.data}, ${c2.data}")
let s1 = Share()
let s2 = s1
s2.data = 2023
println("${s1.data}, ${s2.data}")
}
运行以上程序,将输出:
2012, 2023
2023, 2023
由此可以看出,对于值类型的 Copy 类型变量,在赋值时总是获取 Copy 实例的拷贝,如 c2 = c1,随后对 c2 成员的修改并不影响 c1。对于引用类型的 Share 类型变量,在赋值时将建立变量和实例之间的引用关系,如 s2 = s1,随后对 s2 成员的修改会影响 s1。
如果将以上程序中的 var c2 = c1 改成 let c2 = c1,则编译会报错,例如:
struct Copy {
var data = 2012
}
main() {
let c1 = Copy()
let c2 = c1
c2.data = 2023 // Error, cannot assign to immutable value
}
作用域
在前文中,初步介绍了如何给仓颉程序元素命名,实际上,除了变量,还可以给函数和自定义类型等命名,在程序中将使用这些名字访问对应的程序元素。
但在实际应用中,需要考虑一些特殊情况:
- 当程序规模较大时,那些简短的名字很容易重复,即产生命名冲突。
- 结合运行时考虑,在有些代码片段中,另一些程序元素是无效的,对它们的引用会导致运行时错误。
- 在某些逻辑构造中,为了表达元素之间的包含关系,不应通过名字直接访问子元素,而是要通过其父元素名间接访问。
为了应对这些问题,现代编程语言引入了“作用域”的概念及设计,将名字和程序元素的绑定关系限制在一定范围里。不同作用域之间可以是并列或无关的,也可以是嵌套或包含关系。一个作用域将明确开发者能用哪些名字访问哪些程序元素,具体规则是:
- 当前作用域中定义的程序元素与名字的绑定关系,在当前作用域和其内层作用域中是有效的,可以通过此名字直接访问对应的程序元素。
- 内层作用域中定义的程序元素与名字的绑定关系,在外层作用域中无效。
- 内层作用域可以使用外层作用域中的名字重新定义绑定关系,根据规则 1,此时内层作用域中的命名相当于遮盖了外层作用域中的同名定义,对此称内层作用域的级别比外层作用域的级别高。
在仓颉编程语言中,用一对大括号“{}”包围一段仓颉代码,即构造了一个新的作用域,其中可以继续使用大括号“{}”包围仓颉代码,由此产生了嵌套作用域,这些作用域均服从上述规则。特别的,在一个仓颉源文件中,不被任何大括号“{}”包围的代码,它们所属的作用域被称为“顶层作用域”,即当前文件中“最外层”的作用域,按上述规则,其作用域级别最低。
注意:
仓颉不允许使用单独的大括号“{}”,大括号必须依赖 if、match、函数体、类体、结构体等其他语法结构存在。
例如在以下名为 test.cj 的仓颉源文件里,在顶层作用域中定义了名字 element,它和字符串“仓颉”绑定,而 main 和 if 引导的代码块中也定义了名字 element,分别对应整数 9 和整数 2023。由上述作用域规则,在第 4 行,element 的值为“仓颉”,在第 8 行,element 的值为 2023,在第 10 行,element 的值为 9。
// test.cj
let element = "仓颉"
main() {
println(element)
let element = 9
if (element > 0) {
let element = 2023
println(element)
}
println(element)
}
运行以上程序,将输出:
仓颉
2023
9
表达式
在一些传统编程语言中,一个表达式由一个或多个操作数(operand)通过零个或多个操作符(operator)组合而成。表达式总是隐含着一个计算过程,因此每个表达式都会有一个计算结果。对于只有操作数而没有操作符的表达式,其计算结果就是操作数自身。对于包含操作符的表达式,计算结果是对操作数执行操作符定义的计算而得到的值。在这种定义下的表达式也被称为算术运算表达式。操作符优先级请参见操作符章节。
在仓颉编程语言中,简化并延伸了表达式的传统定义——凡是可求值的语言元素都是表达式。因此,仓颉不仅有传统的算术运算表达式,还有条件表达式、循环表达式和 try 表达式等,它们都可以被求值,并作为值去使用,如作为变量定义的初值和函数实参等。此外,因为仓颉是强类型的编程语言,所以仓颉表达式不仅可求值,还有确定的类型。
注意:
为了清晰地划分不同的程序语句或表达式,仓颉采用分号(
;)进行分隔。如果一条语句独占一行,该分号可以省略,但一行存在多条语句,这些语句必须用分号进行分隔。
仓颉编程语言的各种表达式将在后续章节中逐一介绍,本节介绍最常用的条件表达式、循环表达式以及部分控制转移表达式(break、continue)。
任何一段程序的执行流程,只会涉及三种基本结构——顺序结构、分支结构和循环结构。实际上,分支结构和循环结构,是由某些指令控制当前顺序执行流产生跳转而得到的,它们让程序能够表达更复杂的逻辑。在仓颉中,这种用来控制执行流的语言元素就是条件表达式和循环表达式。
在仓颉编程语言中,条件表达式是 if 表达式,其值与类型需要根据使用场景来确定。循环表达式有三种:for-in 表达式、while 表达式和 do-while 表达式,它们的类型都是 Unit,值为 ()。
在仓颉程序中,由一对大括号“{}”包围起来的一组表达式,被称为“代码块”,它将作为程序的一个顺序执行流,其中的表达式将按编码顺序依次执行。如果代码块中有至少一个表达式,规定此代码块的值与类型等于其中最后一个表达式的值与类型,如果代码块中没有表达式,规定这种空代码块的类型为 Unit,值为 ()。
注意:
代码块本身不是一个表达式,不能被单独使用,它将依附于函数、条件表达式和循环表达式等执行和求值。
if 表达式
if 表达式的基本形式为:
if (条件) {
分支 1
} else {
分支 2
}
其中“条件”可以是一个布尔类型的表达式,或者一个 “let pattern” (语法糖),或者多个 “let pattern” 和布尔类型的表达式之间通过逻辑与或逻辑或直接连接形成的表达式,涉及 “let pattern” 的介绍和示例,参照涉及 “let pattern” 的“条件”示例。
当表达式和模式匹配成功时,该模式匹配的值为 true,此时执行 if 分支对应的代码块;反之,为 false,执行 else 分支代码块,else 分支可以不存在。
“分支 1”和“分支 2”是两个代码块。if 表达式将按如下规则执行:
- 计算“条件”表达式,如果值为
true则转到第 2 步,值为false则转到第 3 步。 - 执行“分支 1”,转到第 4 步。
- 执行“分支 2”,转到第 4 步。
- 继续执行
if表达式后面的代码。
在一些场景中,可能只关注条件成立时该做些什么,所以 else 和对应的代码块是允许省略的。
如下程序演示了 if 表达式的基本用法:
import std.random.*
main() {
let number: Int8 = Random().nextInt8()
println(number)
if (number % 2 == 0) {
println("偶数")
} else {
println("奇数")
}
}
在这段程序中,使用仓颉标准库的 random 包生成了一个随机整数,然后使用 if 表达式判断这个整数是否能被 2 整除,并在不同的条件分支中打印“偶数”或“奇数”。
仓颉编程语言是强类型的,if 表达式的条件只能是布尔类型,不能使用整数或浮点数等类型,和 C 语言等不同,仓颉不以条件取值是否为 0 作为分支选择依据,例如以下程序将编译报错(此外,后文的错误的表达式示例补充了更多错误的表达式用例场景,可对比参照):
main() {
let number = 1
if (number) { // 编译错误,类型不匹配
println("非零数")
}
}
在许多场景中,当一个条件不成立时,可能还要判断另一个或多个条件,再执行对应的动作。仓颉允许在 else 之后跟随新的 if 表达式,由此支持多级条件判断和分支执行,例如:
import std.random.*
main() {
let speed = Random().nextFloat64() * 20.0
println("${speed} km/s")
if (speed > 16.7) {
println("第三宇宙速度,鹊桥相会")
} else if (speed > 11.2) {
println("第二宇宙速度,嫦娥奔月")
} else if (speed > 7.9) {
println("第一宇宙速度,腾云驾雾")
} else {
println("脚踏实地,仰望星空")
}
}
if 表达式的值与类型,需要根据使用形式与场景来确定:
-
当含
else分支的if表达式被求值时,需要根据求值上下文确定if表达式的类型:- 如果上下文明确要求值类型为
T,则if表达式各分支代码块的类型必须是T的子类型,这时if表达式的类型被确定为T,如果不满足子类型约束,编译会报错。 - 如果上下文没有明确的类型要求,则
if表达式的类型是其各分支代码块类型的最小公共父类型,如果最小公共父类型不存在,编译会报错。
如果编译通过,则
if表达式的值就是所执行分支代码块的值。 - 如果上下文明确要求值类型为
-
如果含
else分支的if表达式没有被求值,在这种场景里,开发者一般只想在不同分支里做不同操作,不会关注各分支最后一个表达式的值与类型,为了不让上述类型检查规则影响这一思维习惯,仓颉规定这种场景下的if表达式类型为Unit、值为(),且各分支不参与上述类型检查。 -
对于不含
else分支的if表达式,由于if分支也可能不被执行,所以规定这类if表达式的类型为Unit、值为()。
例如,以下程序基于 if 表达式求值,模拟一次简单的模数转换过程:
main() {
let zero: Int8 = 0
let one: Int8 = 1
let voltage = 5.0
let bit = if (voltage < 2.5) {
zero
} else {
one
}
}
在以上程序中,if 表达式作为变量定义的初值使用,由于变量 bit 没有被标注类型、需要从初值中推导,所以 if 表达式的类型取为两个分支代码块类型的最小公共父类型。根据前文对“代码块”的介绍,可知两个分支代码块类型都是 Int8,所以 if 表达式的类型被确定为 Int8,其值为所执行分支即 else 分支代码块的值,所以变量 bit 的类型为 Int8、值为 1。
涉及 “let pattern” 的“条件”示例
“let pattern” 属于语法糖。一个 “let pattern” 的构成为 let pattern <- expression,其中各字段含义为:
pattern:模式,用于匹配expression的值类型和内容。<-:模式匹配操作符。expression:表达式,该表达式求值后,再和模式进行匹配。expression表达式的优先级不能低于..运算符,但是可以用()改变优先级。运算符优先级请参见操作符。
此处介绍“条件”是两个 “let pattern” 进行逻辑与或逻辑或操作以及 “let pattern” 与其他表达式进行逻辑与或逻辑或操作的示例。
main() {
let a = Some(3)
let c = if (let Some(b) <- a) {
1 // 模式匹配成功,c = 1
} else {
2
}
let d = Some(1)
if (let Some(e) <- a && let Some(f) <- d) { // 两种模式都匹配,条件的值为真
println("${e} ${f}") // print 3 1
}
if (let Some(f) <- d && f > 3) { // 模式匹配;f = 1,f > 3 检查失败,跳转到 else 分支
println("${f}")
} else {
println("d is None or value of d is less or equal to 3") // 打印该行
}
if (let Some(_) <- a || let Some(_) <- d) { // 枚举模式通过||连接,没有变量绑定,正确
println("at least one of a and d is Some") // 打印该行
} else {
println("both a and d are None")
}
let g = 3
if (let Some(_) <- a || g > 1) {
println("this") // 打印该行
} else {
println("that")
}
}
“let pattern” 中表达式部分运算符优先级不能低于 .. 运算符,此处介绍对应的错误和正确示例。其中, Option 类型的相关介绍在后文给出。
if (let Some(a) <- fun() as Option<Int64>) {} // 解析错误,`as` 的优先级低于 `..`
if (let Some(a) <- (fun() as Option<Int64>)) {} // 正确
if (let Some(a) <- b && a + b > 3) {} // 正确,解析为 (let Some(a) <- b) && (a + b > 3)
if (let m <- 0..generateSomeInt()) {} // 正确
错误的表达式示例
此处介绍错误的“条件”示例。
if (let Some(a) <- b || a > 1) {} // 由 `||` 连接的条件不能使用会绑定变量的 enum 模式
if (let Some(a) <- b && a + 1) {} // `&&` 右侧既不是 let pattern,也不是类型为 Bool 的普通表达式
if (a > 3 && let Some(a) <- b) {} // a 由 Some(a) pattern 绑定,不能在绑定它的 pattern 左侧使用
if (let Some(a) <- b && a > 3) {
println("${a} > 3")
} else {
println("${a} < 3") // a 只能在 if 分支使用,不能在 else 分支使用
}
if (let Some(a) <- b where a > 3) {} // 使用 `&&` 表示条件检查,而不是 `where`
while 表达式
while 表达式的基本形式为:
while (条件) {
循环体
}
其中“条件”同 if 表达式的“条件”,“循环体”是一个代码块。while 表达式将按如下规则执行:
- 计算“条件”表达式,如果值为
true则转第 2 步,值为false转第 3 步。 - 执行“循环体”,转第 1 步。
- 结束循环,继续执行
while表达式后面的代码。
例如,以下程序使用 while 表达式,基于二分法,近似计算数字 2 的平方根:
main() {
var root = 0.0
var min = 1.0
var max = 2.0
var error = 1.0
let tolerance = 0.1 ** 10
while (error ** 2 > tolerance) {
root = (min + max) / 2.0
error = root ** 2 - 2.0
if (error > 0.0) {
max = root
} else {
min = root
}
}
println("2 的平方根约等于:${root}")
}
运行以上程序,将输出:
2 的平方根约等于:1.414215
do-while 表达式
do-while 表达式的基本形式为:
do {
循环体
} while (条件)
其中“条件”是布尔类型表达式,“循环体”是一个代码块。do-while 表达式将按如下规则执行:
- 执行“循环体”,转第 2 步。
- 计算“条件”表达式,如果值为
true则转第 1 步,值为false转第 3 步。 - 结束循环,继续执行
do-while表达式后面的代码。
例如,以下程序使用 do-while 表达式,基于蒙特卡洛算法,近似计算圆周率的值:
import std.random.*
main() {
let random = Random()
var totalPoints = 0
var hitPoints = 0
do {
// 在 ((0, 0), (1, 1)) 这个正方形中随机取点
let x = random.nextFloat64()
let y = random.nextFloat64()
// 判断是否落在正方形内接圆里
if ((x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25) {
hitPoints++
}
totalPoints++
} while (totalPoints < 1000000)
let pi = 4.0 * Float64(hitPoints) / Float64(totalPoints)
println("圆周率近似值为:${pi}")
}
运行以上程序,将输出:
圆周率近似值为:3.141872
说明:
由于算法涉及随机数,所以每次运行程序输出的数值可能都不同,但都会约等于 3.14。
for-in 表达式
for-in 表达式可以遍历那些扩展了迭代器接口 Iterable<T> 的类型实例。for-in 表达式的基本形式为:
for (迭代变量 in 序列) {
循环体
}
其中“循环体”是一个代码块。“迭代变量”是单个标识符或由多个标识符构成的元组,用于绑定每轮遍历中由迭代器指向的数据,可以作为“循环体”中的局部变量使用。“序列”是一个表达式,它只会被计算一次,遍历是针对此表达式的值进行的,其类型必须扩展了迭代器接口 Iterable<T>。for-in 表达式将按如下规则执行:
- 计算“序列”表达式,将其值作为遍历对象,并初始化遍历对象的迭代器。
- 更新迭代器,如果迭代器终止,转第 4 步,否则转第 3 步。
- 将当前迭代器指向的数据与“迭代变量”绑定,并执行“循环体”,转第 2 步。
- 结束循环,继续执行
for-in表达式后面的代码。
说明:
仓颉内置的区间和数组等类型已经扩展了
Iterable<T>接口。
例如,以下程序使用 for-in 表达式,遍历中国地支字符构成的数组 noumenonArray,输出农历 2024 年各月的干支纪法:
main() {
let metaArray = [r'甲', r'乙', r'丙', r'丁', r'戊', r'己', r'庚', r'辛', r'壬', r'癸']
let noumenonArray = [r'寅', r'卯', r'辰', r'巳', r'午', r'未', r'申', r'酉', r'戌', r'亥', r'子', r'丑']
let year = 2024
// 年份对应的天干索引
let metaOfYear = ((year % 10) + 10 - 4) % 10
// 此年首月对应的天干索引
var index = (2 * metaOfYear + 3) % 10 - 1
println("农历 2024 年各月干支:")
for (noumenon in noumenonArray) {
print("${metaArray[index]}${noumenon} ")
index = (index + 1) % 10
}
}
其中 r 开头的字符表示字符类型字面量。运行以上程序,将输出:
农历 2024 年各月干支:
丙寅 丁卯 戊辰 己巳 庚午 辛未 壬申 癸酉 甲戌 乙亥 丙子 丁丑
遍历区间
for-in 表达式可以遍历区间类型实例,例如:
main() {
var sum = 0
for (i in 1..=100) {
sum += i
}
println(sum)
}
运行以上程序,将输出:
5050
关于区间类型的详细内容,请参见基本数据类型区间类型。
遍历元组构成的序列
如果一个序列的元素是元组类型,则使用 for-in 表达式遍历时,“迭代变量”可以写成元组形式,以此实现对序列元素的解构,例如:
main() {
let array = [(1, 2), (3, 4), (5, 6)]
for ((x, y) in array) {
println("${x}, ${y}")
}
}
运行以上程序,将输出:
1, 2
3, 4
5, 6
迭代变量不可修改
在 for-in 表达式的循环体中,不能修改迭代变量,例如以下程序在编译时会报错:
main() {
for (i in 0..5) {
i = i * 10 // 错误,不能对已初始化的 `let` 常量赋值
println(i)
}
}
使用通配符 _ 代替迭代变量
在一些应用场景中,只需要循环执行某些操作,但并不使用迭代变量,这时可以使用通配符 _ 代替迭代变量,例如:
main() {
var number = 2
for (_ in 0..5) {
number *= number
}
println(number)
}
运行以上程序,将输出:
4294967296
注意:
在这种场景下,如果使用普通的标识符定义迭代变量,编译会输出“unused variable”告警,使用通配符
_则可以避免这一告警。
where 条件
在部分循环遍历场景中,对于特定取值的迭代变量,可能需要直接跳过,进入下一轮循环。虽然可以使用 if 表达式和 continue 表达式在循环体中实现这一逻辑,但仓颉为此提供了更便捷的表达方式——可以在所遍历的“序列”之后用 where 关键字引导一个布尔表达式,这样在每次将进入循环体执行前,会先计算此表达式。如果值为 true 则执行循环体,反之直接进入下一轮循环。例如:
main() {
for (i in 0..8 where i % 2 == 1) { // i 为奇数才会执行循环体
println(i)
}
}
运行以上程序,将输出:
1
3
5
7
break 与 continue 表达式
在循环结构的程序中,有时需要根据特定条件提前结束循环或跳过本轮循环,为此仓颉引入了 break 与 continue 表达式,它们可以出现在循环表达式的循环体中,break 用于终止当前循环表达式的执行、转去执行循环表达式之后的代码,continue 用于提前结束本轮循环、进入下一轮循环。break 与 continue 表达式的类型都是 Nothing。
例如,以下程序使用 for-in 表达式和 break 表达式,在给定的整数数组中,找到第一个能被 5 整除的数字:
main() {
let numbers = [12, 18, 25, 36, 49, 55]
for (number in numbers) {
if (number % 5 == 0) {
println(number)
break
}
}
}
当 for-in 迭代至 numbers 数组的第三个数 25 时,由于 25 可以被 5 整除,所以将执行 if 分支中的 println 和 break,break 将终止 for-in 循环,numbers中的后续数字不会被遍历到。因此运行以上程序,将输出:
25
以下程序使用 for-in 表达式和 continue 表达式,将给定整数数组中的奇数打印出来:
main() {
let numbers = [12, 18, 25, 36, 49, 55]
for (number in numbers) {
if (number % 2 == 0) {
continue
}
println(number)
}
}
在循环迭代中,当 number 是偶数时,continue 将被执行,这会提前结束本轮循环,进入下一轮循环,println 不会被执行。因此运行以上程序,将输出:
25
49
55
函数
仓颉使用关键字 func 来表示函数定义的开始,func 之后依次是函数名、参数列表、可选的函数返回值类型、函数体。其中,函数名可以是任意的合法标识符,参数列表定义在一对圆括号内(多个参数间使用逗号分隔),参数列表和函数返回值类型(如果存在)之间使用冒号分隔,函数体定义在一对花括号内。
函数定义举例:
func add(a: Int64, b: Int64): Int64 {
return a + b
}
上例中定义了一个名为 add 的函数,其参数列表由两个 Int64 类型的参数 a 和 b 组成,函数返回值类型为 Int64,函数体中将 a 和 b 相加并返回。
详细介绍可参见定义函数模块介绍。
基本操作符
操作符是执行特定的数学运算或逻辑操作的符号。例如,数学运算符号的加号(+)可将两个数相加(如:let i = 1 + 2),逻辑操作符号的逻辑与(&&)可用于组合并确保多个条件判断均满足(如:if (i > 0 && i < 10))。
仓颉编程语言不仅支持各种常用的操作符,同时为了减少常见编码错误对它们做了部分改进。如:赋值表达式(包含赋值操作符的表达式)的类型是 Unit,值是 (),如果将 if(a == 3) 写成 if(a = 3),赋值表达式的返回值不是布尔类型,因此会编译报错,这样可以避免将判等操作符(==)误写成赋值操作符(=)的问题。算术操作符(+、-、*、/、% 等)的结果会被检测并禁止值溢出,以此来避免保存变量时由于变量大于或小于其类型所能承载的范围时导致的异常结果。
仓颉编程语言还提供了区间操作符,例如 a..b 或 a..=b,这方便表达一个区间内的数值。
本章节只描述了仓颉编程语言中的基本操作符,其他操作符参见附录中的操作符。如何进行自定义类型的操作符重载参见操作符重载章节。
赋值操作符
用于将左操作数的值修改为右操作数的值,要求右操作数的类型是左操作数类型的子类型。对赋值表达式求值时,总是先计算 = 右边的表达式,再计算 = 左边的表达式,最后进行赋值。
main(): Int64 {
var a = 1
var b = 1
a = (b = 0) // 编译错误,赋值表达式的类型是 Unit,值是 ()
if (a = 5) { // 编译错误,赋值表达式的类型是 Unit,值是 ()
}
a = b = 0 // 语法错误,不支持链式使用赋值
return 0
}
多赋值表达式是一种特殊的赋值表达式,多赋值表达式等号左边必须是一个 tuple(元组) ,这个 tuple 里面的元素必须都是左值,等号右边的表达式也必须是 tuple 类型,右边 tuple 每个元素的类型必须是对应位置左值类型的子类型。值得注意的是当左侧 tuple 中出现 _ 时,表示忽略等号右侧 tuple 对应位置处的求值结果(意味着这个位置处的类型检查总是可以通过的)。多赋值表达式可以将右边的 tuple 类型的值,一次性赋值给左边 tuple 内的对应左值,省去逐个赋值的代码。
main(): Int64 {
var a: Int64
var b: Int64
(a, b) = (1, 2) // a = 1, b = 2
(a, b) = (b, a) // 交换, a = 2, b = 1
(a, _) = (3, 4) // a = 3
(_, _) = (5, 6) // 无赋值
return 0
}
算术操作符
仓颉编程语言支持的算术操作符包括:一元负号(-)、加(+)、减(-)、乘(*)、除(/)、取余(%)、求幂(**)。除了一元负号是一元前缀操作符,其他操作符均是二元中缀操作符。
一元负号(-)的操作数只能是数值类型的表达式。一元前缀负号表达式的值等于操作数取负的值,类型和操作数的类型相同:
let num1: Int64 = 8
let num2 = -num1 // num2 = -8, 其数据类型为“Int64”。
let num3 = -(-num1) // num3 = 8, 其数据类型为“Int64”。
对于二元操作符 *、/、%、+ 和 -,要求两个操作数的类型相同。其中 % 的操作数只支持整数类型;*、/、+ 和 - 的操作数可以是任意数值类型。
注意:
- 除法(
/)的操作数为整数时,将非整数值向 0 的方向舍入为整数。- 整数取余运算
a % b的值定义为a - b * (a / b)。- 加法操作符也可用于字符串的拼接。
let a = 2 + 3 // a = 5
let b = 3 - 1 // b = 2
let c = 3 * 4 // c = 12
let d = 7 / 3 // d = 2
let e = 7 / -3 // e = -2, 当遇到“-”时,它具有更高的优先级。
let f = -7 / 3 // f = -2
let g = -7 / -3 // g = 2, 当遇到“-”时,它具有更高的优先级。
let h = 4 % 3 // h = 1
let i = 4 % -3 // i = 1, 当遇到“-”时,它具有更高的优先级。
let j = -4 % 3 // j = -1
let k = -4 % -3 // k = -1, 当遇到“-”时,它具有更高的优先级。
let s1 = "abc"
var s2 = "ABC"
let r1 = s1 + s2 // r1 = "abcABC"
** 表示求幂运算(如 x**y 表示计算底数 x 的 y 次幂)。** 的左操作数只能为 Int64 类型或 Float64 类型。
注意:
当左操作类型为 Int64 时,右操作数只能为 UInt64 类型,表达式的类型为 Int64。 当左操作类型为 Float64 时,右操作数只能为 Int64 类型或 Float64 类型,表达式的类型为 Float64。
let p1 = 2 ** 3 // p1 = 8
let p2 = 2 ** UInt64(3 ** 2) // p2 = 512
let p3 = 2.0 ** 3 // p3 = 8.0
let p4 = 2.0 ** 3 ** 2 // p4 = 512.0
let p5 = 2.0 ** 3.0 // p5 = 8.0
let p6 = 2.0 ** 3.0 ** 2.0 // p6 = 512.0
复合赋值操作符
仓颉编程语言也提供 **=、*=、/=、%=、+=、-=、<<=、>>=、&=、^=、|=、&&= 和 ||= 复合赋值操作符。对于复合赋值表达式求值时,总是先计算 = 左边的表达式的左值,再根据这个左值取右值,然后将该右值与 = 右边的表达式做计算(若有短路规则会继续遵循短路规则),最后赋值。因为复合赋值表达式也是一个赋值表达式,所以复合赋值操作符也是非结合的。复合赋值表达式同样要求两个操作数的类型相同。
var a: Int64 = 10
a += 2 // a = 12
a -= 2 // a = 10
a **= 2 // a = 100
a *= 2 // a = 200
a /= 10 // a = 20
a %= 6 // a = 2
a <<= 2 // a = 8
关系操作符
关系操作符包括六种:相等(==)、不等(!=)、小于(<)、小于等于(<=)、大于(>)、大于等于(>=)。关系操作符都是二元操作符,并且要求两个操作数的类型是一样的。关系表达式的类型是 Bool 类型,即值只可能是 true 或 false。
关系表达式举例:
main(): Int64 {
3 < 4 // true
3 <= 3 // true
3 > 4 // false
3 >= 3 // true
3.14 == 3.15 // false
3.14 != 3.15 // true
return 0
}
对于元组类型,当且仅当所有元素均支持使用 == 进行值判等(使用 != 进行值判不等)时,此元组类型才支持使用 == 进行值判等(使用 != 进行值判不等);否则,此元组类型不支持 == 和 !=(如果使用 == 和 !=,编译报错)。两个同类型的元组实例相等,当且仅当相同位置(index)的元素全部相等(意味着它们的长度相等)。
var isTrue: Bool = (1, 3) == (0, 2) // false
isTrue = (1, "123") == (1.0, 2) // 编译错误,两个操作数的类型不一致
isTrue = (1, _) == (1.0, _) // 编译错误,通配符不可作为元组中元素进行匹配
coalescing 操作符
coalescing 操作符使用 ?? 表示,?? 是二元中缀操作符。coalescing 操作符用于 Option 类型的解构。
e1 ?? e2 表达式,在 e1 的值等于 Option<T>.Some(v) 时,e1 ?? e2 的值等于 v 的值(此时,不会再去对 e2 求值,即满足 “短路求值”);在 e1 的值等于 Option<T>.None 时,e1 ?? e2 的值等于 e2 的值。
coalescing 表达式使用举例:
main(): Int64 {
let v1 = Option<Int64>.Some(100)
let v2 = Option<Int64>.None
let r1 = v1 ?? 0
let r2 = v2 ?? 0
print("${r1}") // 100
print("${r2}") // 0
return 0
}
区间操作符
区间操作符有两种:.. 和 ..=,分别用于创建 “左闭右开” 和 “左闭右闭” 的区间实例。关于它们的介绍,请参见 区间类型。
逻辑操作符
仓颉编程语言支持三种逻辑操作符:逻辑非(!)、逻辑与(&&)、逻辑或(||)。
逻辑非(!)是一元操作符,它的作用是对其操作数的布尔值取反:!false 的值等于 true,!true 的值等于 false。
var a: Bool = true // a = true
var b: Bool = !a // b = false
var c: Bool = !false // c = true
逻辑与(&&)和逻辑或(||)均是二元操作符。对于表达式 expr1 && expr2,只有当 expr1 和 expr2 的值均等于 true 时,它的值才等于 true;对于表达式 expr1 || expr2,只有当 expr1 和 expr2 的值均等于 false 时,它的值才等于 false。
var a: Bool = true && true // a = true
var b: Bool = true && false // b = false
var c: Bool = false && false // c = false
var d: Bool = false && true // d = false
a = true || true // a = true
b = true || false // b = true
c = false || false // c = false
d = false || true // d = true
逻辑与(&&)和逻辑或(||)采用短路求值策略:计算 expr1 && expr2 时,当 expr1=false 则无需对 expr2 求值,整个表达式的值为 false;计算 expr1 || expr2 时,当 expr1=true 则无需对 expr2 求值,整个表达式的值为 true。
func isEven(a: Int64): Bool {
if((a % 2) == 0) {
println("${a} is an even number")
true
} else {
println("${a} is not an even number")
false
}
}
main() {
var a: Bool = isEven(2) && isEven(20)
var b: Bool = isEven(3) && isEven(30) // isEven(3)返回值是false, b 值为false,无需对isEven(30)求值
a = isEven(4) || isEven(40) // isEven(4)返回值是true, a 值为true,无需对isEven(40)求值
b = isEven(5) || isEven(50)
}
位运算操作符
仓颉编程语言支持一种一元前缀位运算操作符:按位求反(!),以及五种二元中缀位运算操作符:左移(<<)、右移(>>)、按位与(&)、按位异或(^)和按位或(|)。位运算操作符的操作数只能为整数类型,通过将操作数视为二进制序列,然后在每一位上进行逻辑运算(0 视为 false,1 视为 true )或移位操作来实现位运算。
对于移位操作符,要求其操作数必须是整数类型(但两个操作数可以是不同的整数类型,例如:左操作数是 Int8,右操作数是 Int16),并且无论左移还是右移,右操作数都不允许为负数(对于编译时可检查出的此类错误,编译报错,如果运行时发生此错误,则抛出异常)。对于无符号数的移位操作,移位和补齐规则是:左移低位补 0 高位丢弃,右移高位补 0 低位丢弃。对于有符号数的移位操作,移位和补齐规则是:
- 正数和无符号数的移位补齐规则一致;
- 负数左移低位补 0 高位丢弃;
- 负数右移高位补 1 低位丢弃。
另外,如果右移或左移的位数(右操作数)等于或者大于操作数的宽度,则为移位越界,如果编译时可以检测到则报错,否则运行时抛出异常。
var a = !10 // -11,符合移位和补齐规则
a = !20 // -21,符合移位和补齐规则
a = 10 << 1 // 20,符合移位和补齐规则
// a = 1000 << -1 // 编译报错,移位操作溢出(右操作数都不允许为负数)
// a = 1000 << 100000000000 // 编译报错,移位操作溢出(移位越界)
a = 10 << 1 << 1 // 40,符合移位和补齐规则
a = 10 >> 1 // 5,符合移位和补齐规则
a = 10 & 15 // 10
a = 10 ^ 15 // 5
a = 10 | 15 // 15
a = (1 ^ (8 & 15)) | 24 // 25
自增自减操作符
自增(++)和自减(--)操作符实现对值的加 1 和减 1 操作,且只能作为后缀操作符使用。自增(++)和自减(--)操作符是非结合的。
对于表达式 expr++ (或 expr-- ),规定如下:
expr的类型必须是整数类型;- 因为
expr++(或expr--)是expr += 1(或expr -= 1)的语法糖,所以此 expr 同时必须也是可被赋值的; expr++(或expr--)的类型为 Unit。
自增(自减)表达式举例:
var i: Int32 = 5
i++ // i = 6
i-- // i = 5
i--++ // 语法错误
var j = 0
j = i-- // 语义错误
整数类型
整数类型分为有符号(signed)整数类型和无符号(unsigned)整数类型。
有符号整数类型包括 Int8、Int16、Int32、Int64 和 IntNative,分别用于表示编码长度为 8-bit、16-bit、32-bit、64-bit 和平台相关大小的有符号整数值的类型。
无符号整数类型包括 UInt8、UInt16、UInt32、UInt64 和 UIntNative,分别用于表示编码长度为 8-bit、16-bit、32-bit、64-bit 和平台相关大小的无符号整数值的类型。
对于编码长度为 N 的有符号整数类型,其表示范围为:$-2^{N-1} \sim 2^{N-1}-1$;对于编码长度为 N 的无符号整数类型,其表示范围为:$0 \sim 2^{N}-1$。下表列出了所有整数类型的表示范围:
| 类型 | 表示范围 |
|---|---|
| Int8 | $-2^7 \sim 2^7-1 (-128 \sim 127)$ |
| Int16 | $-2^{15} \sim 2^{15}-1 (-32,768 \sim 32,767)$ |
| Int32 | $-2^{31} \sim 2^{31}-1 (-2,147,483,648 \sim 2,147,483,647)$ |
| Int64 | $-2^{63} \sim 2^{63}-1 (-9,223,372,036,854,775,808 \sim 9,223,372,036,854,775,807)$ |
| IntNative | platform dependent |
| UInt8 | $0 \sim 2^8-1 (0 \sim 255)$ |
| UInt16 | $0 \sim 2^{16}-1 (0 \sim 65,535)$ |
| UInt32 | $0 \sim 2^{32}-1 (0 \sim 4,294,967,295)$ |
| UInt64 | $0 \sim 2^{64}-1 (0 \sim 18,446,744,073,709,551,615)$ |
| UIntNative | platform dependent |
程序具体使用哪种整数类型,取决于该程序中需要处理的整数的性质和范围。在 Int64 类型适合的情况下,首选 Int64 类型,因为 Int64 的表示范围足够大,并且整数类型字面量在没有类型上下文的情况下默认推断为 Int64 类型,可以避免不必要的类型转换。
整数类型字面量
整数类型字面量有 4 种进制表示形式:二进制(使用 0b 或 0B 前缀)、八进制(使用 0o 或 0O 前缀)、十进制(没有前缀)、十六进制(使用 0x 或 0X 前缀)。例如,对于十进制数 24,表示成二进制是 0b00011000(或 0B00011000),表示成八进制是 0o30(或 0O30),表示成十六进制是 0x18(或 0X18)。
在各进制表示中,可以使用下划线 _ 充当分隔符的作用,方便识别数值的位数,如 0b0001_1000。
对于整数类型字面量,如果它的值超出了上下文要求的整数类型的表示范围,编译器将会报错。
let x: Int8 = 128 // Error, 128 out of the range of Int8
let y: UInt8 = 256 // Error, 256 out of the range of UInt8
let z: Int32 = 0x8000_0000 // Error, 0x8000_0000 out of the range of Int32
在使用整数类型字面量时,可以通过加入后缀来明确整数字面量的类型,后缀与类型的对应为:
| 后缀 | 类型 | 后缀 | 类型 |
|---|---|---|---|
| i8 | Int8 | u8 | UInt8 |
| i16 | Int16 | u16 | UInt16 |
| i32 | Int32 | u32 | UInt32 |
| i64 | Int64 | u64 | UInt64 |
加入了后缀的整数字面量可以通过以下方式使用:
var x = 100i8 // x is 100 with type Int8
var y = 0x10u64 // y is 16 with type UInt64
var z = 0o432i32 // z is 282 with type Int32
字符字节字面量
仓颉编程语言支持字符字节字面量,以方便使用 ASCII 码表示 UInt8 类型的值。字符字节字面量由字符 b、一对标识首尾的单引号、以及一个 ASCII 字符组成,例如:
var a = b'x' // a is 120 with type UInt8
var b = b'\n' // b is 10 with type UInt8
var c = b'\u{78}' // c is 120 with type UInt8
c = b'\u{90}' - b'\u{66}' + c // c is 162 with type UInt8
b'x' 表示类型为 UInt8 大小是 120 的字面值。另外还可以通过 b'\u{78}' 这种转义形式表示类型为 UInt8,16 进制大小为 0x78 或 10 进制大小为 120 的字面值。需要注意的是,\u 内部最多有两位 16 进制数,并且值必须小于 256(十进制)。
整数类型支持的操作
整数类型默认支持的操作符包括:算术操作符、位操作符、关系操作符、自增和自减操作符、复合赋值操作符。各操作符的优先级参见附录中的操作符。
-
算术操作符包括:一元负号(
-)、加法(+)、减法(-)、乘法(*)、除法(/)、取模(%)、幂运算(**)。-
除了一元负号(
-)和幂运算(**),其他操作符要求左右操作数是相同的类型。 -
*,/,+和-的操作数可以是整数类型或浮点类型。 -
%的操作数只支持整数类型。 -
**的左操作数只能为Int64类型或Float64类型,并且:- 当左操作数类型为
Int64时,右操作数只能为UInt64类型,表达式的类型为Int64。 - 当左操作数类型为
Float64时,右操作数只能为Int64类型或Float64类型,表达式的类型为Float64。
- 当左操作数类型为
-
-
位操作符包括:按位求反(
!)、左移(<<)、右移(>>)、按位与(&)、按位异或(^)、按位或(|)。注意,按位与、按位异或和按位或操作符要求左右操作数是相同的整数类型。 -
关系操作符包括:小于(
<)、大于(>)、小于等于(<=)、大于等于(>=)、相等(==)、不等(!=)。要求关系操作符的左右操作数是相同的整数类型。 -
自增和自减操作符包括:自增(
++)和自减(--)。注意,仓颉中的自增和自减操作符只能作为一元后缀操作符使用。 -
复合赋值操作符包括:
+=、-=、*=、/=、%=、**=、<<=、>>=、&=、^=、|=。
整数类型之间、整数类型和浮点类型之间可以互相转换,整数类型可以转换为字符类型,具体的类型转换语法及规则请参见数值类型之间的转换。
注意:
本章所提及的某个类型支持的操作,均是指在没有操作符重载的前提下。
浮点类型
浮点类型包括 Float16、 Float32 和 Float64,分别用于表示编码长度为 16-bit、 32-bit 和 64-bit 的浮点数(带小数部分的数字,如 3.14159、8.24 和 0.1 等)的类型。Float16、 Float32 和 Float64 分别对应 IEEE 754 中的半精度格式(即 binary16)、单精度格式(即 binary32)和双精度格式(即 binary64)。
Float64 的精度(有效数字位)约为 15 位,Float32 的精度(有效数字位)约为 6 位,Float16 的精度(有效数字位)约为 3 位。使用哪种浮点类型,取决于代码中需要处理的浮点数的性质和范围。在多种浮点类型都适合的情况下,首选精度高的浮点类型,因为精度低的浮点类型的累计计算误差很容易扩散,并且它能精确表示的整数范围也很有限。
浮点类型字面量
浮点类型字面量有两种进制表示形式:十进制、十六进制。在十进制表示中,一个浮点字面量至少要包含一个整数部分或一个小数部分,没有小数部分时必须包含指数部分(以 e 或 E 为前缀,底数为 10)。在十六进制表示中,一个浮点字面量除了至少要包含一个整数部分或小数部分(以 0x 或 0X 为前缀),同时必须包含指数部分(以 p 或 P 为前缀,底数为 2)。
下面的例子展示了浮点字面量的使用:
let a: Float32 = 3.14 // a is 3.140000 with type Float32
let b: Float32 = 2e3 // b is 2000.000000 with type Float32
let c: Float32 = 2.4e-1 // c is 0.240000 with type Float32
let d: Float64 = .123e2 // d is 12.300000 with type Float64
let e: Float64 = 0x1.1p0 // e is 1.062500 with type Float64
let f: Float64 = 0x1p2 // f is 4.000000 with type Float64
let g: Float64 = 0x.2p4 // g is 2.000000 with type Float64
在使用十进制浮点数字面量时,可以通过加入后缀来明确浮点数字面量的类型,后缀与类型的对应为:
| 后缀 | 类型 |
|---|---|
| f16 | Float16 |
| f32 | Float32 |
| f64 | Float64 |
加入了后缀的浮点数字面量可以像下面的方式来使用:
let a = 3.14f32 // a is 3.140000 with type Float32
let b = 2e3f32 // b is 2000.000000 with type Float32
let c = 2.4e-1f64 // c is 0.240000 with type Float64
let d = .123e2f64 // d is 12.300000 with type Float64
浮点类型支持的操作
浮点类型默认支持的操作符包括:算术操作符、关系操作符、复合赋值操作符。浮点类型不支持自增和自减操作符。
浮点类型之间、浮点类型和整数类型之间可以互相转换,具体的类型转换语法及规则请参见数值类型之间的转换。
布尔类型
布尔类型使用 Bool 表示,用来表示逻辑中的真和假。
布尔类型字面量
布尔类型只有两个字面量:true 和 false。
下面的例子展示了布尔字面量的使用:
let a: Bool = true
let b: Bool = false
布尔类型支持的操作
布尔类型支持的操作符包括:逻辑操作符(逻辑非 !,逻辑与 &&,逻辑或 ||)、部分关系操作符(== 和 !=)、部分复合赋值操作符(&&= 和 ||=)。
字符类型
字符类型使用 Rune 表示,可以表示 Unicode 字符集中的所有字符。
字符类型字面量
字符类型字面量有三种形式:单个字符、转义字符和通用字符。一个 Rune 字面量由字符 r 开头,后跟一个由一对单引号或双引号包含的字符。
单个字符的字符字面量举例:
let a: Rune = r'a'
let b: Rune = r"b"
转义字符是指在一个字符序列中对后面的字符进行另一种解释的字符。转义字符使用转义符号 \ 开头,后面加需要转义的字符。举例如下:
let slash: Rune = r'\\'
let newLine: Rune = r'\n'
let tab: Rune = r'\t'
通用字符以 \u 开头,后面加上定义在一对花括号中的 1~8 个十六进制数,即可表示对应的 Unicode 值代表的字符。举例如下:
main() {
let he: Rune = r'\u{4f60}'
let llo: Rune = r'\u{597d}'
print(he)
print(llo)
}
编译并执行上述代码,输出结果为:
你好
字符类型支持的操作
字符类型支持的操作符包括:关系操作符,即小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、相等(==)、不等(!=)。比较的是字符的 Unicode 值。
Rune 可以转换为 UInt32,整数类型可以转换为 Rune,具体的类型转换语法及规则请参见Rune 到 UInt32 和整数类型到 Rune 的转换。
字符串类型
字符串类型使用 String 表示,用于表达文本数据,由一串 Unicode 字符组合而成。
字符串字面量
字符串字面量分为三类:单行字符串字面量,多行字符串字面量,多行原始字符串字面量。
单行字符串字面量的内容定义在一对单引号或一对双引号之内,引号中的内容可以是任意数量的(除了用于定义字符串字面量的非转义的引号和单独出现的 \ 之外的)任意字符。单行字符串字面量只能写在同一行,不能跨越多行。举例如下:
let s1: String = ""
let s2 = 'Hello Cangjie Lang'
let s3 = "\"Hello Cangjie Lang\""
let s4 = 'Hello Cangjie Lang\n'
多行字符串字面量开头结尾需各存在三个双引号(""")或三个单引号(''')。字面量的内容从开头的三个引号换行后的第一行开始,到遇到的第一个非转义的三个引号为止,之间的内容可以是任意数量的(除单独出现的 \ 之外的)任意字符。不同于单行字符串字面量,多行字符串字面量可以跨越多行。举例如下:
let s1: String = """
"""
let s2 = '''
Hello,
Cangjie Lang'''
多行原始字符串字面量以一个或多个井号(#)和一个单引号(')或双引号(")开头,后跟任意数量的合法字符,直到出现与字符串开头相同的引号和与字符串开头相同数量的井号为止。在当前文件结束之前,如果还没遇到匹配的双引号和相同个数的井号,则编译报错。与多行字符串字面量一样,原始多行字符串字面量可以跨越多行。不同之处在于,转义规则不适用于多行原始字符串字面量,字面量中的内容会维持原样(转义字符不会被转义,如下例中 s2 中的 \n 不是换行符,而是由 \ 和 n 组成的字符串 \n)。举例如下:
let s1: String = #""#
let s2 = ##'#'\n'## // 输出结果为:#'\n
let s3 = ###"
Hello,
Cangjie
Lang"### // 该变量当中的换行、缩进等也会被保留
对于形如 left = right 的赋值操作,如果左操作数的类型是 Byte(内置类型 UInt8 的别名),并且右操作数是一个表示 ASCII 字符的字符串字面量,那么右操作数的字符串将分别被强制转换为 Byte 类型,再进行赋值;如果左操作数的类型是 Rune,并且右操作数是一个单字符的字符串字面量,那么右操作数的字符串将分别被强制转换为 Rune 类型,再进行赋值。
main() {
var b: Byte = "0"
print(b)
b = "1"
print(b)
var r: Rune = "0"
print(r)
r = "1"
print(r)
}
编译并执行上述代码,输出结果为:
484901
插值字符串
插值字符串是一种包含一个或多个插值表达式的字符串字面量(不适用于多行原始字符串字面量),通过将表达式插入到字符串中,可以有效避免字符串拼接的问题。插值字符串经常出现在 println 函数中输出非字符串类型的变量值,例如 println("${x}")。
插值表达式必须用花括号 {} 包起来,并在 {} 之前加上 $ 前缀。{} 中可以包含一个或者多个声明或表达式。
当插值字符串求值时,每个插值表达式所在位置会被 {} 中的最后一项的值替换,整个插值字符串最终仍是一个字符串。
下面是插值字符串的简单示例:
main() {
let fruit = "apples"
let count = 10
let s = "There are ${count * count} ${fruit}"
println(s)
let r = 2.4
let area = "The area of a circle with radius ${r} is ${let PI = 3.141592; PI * r * r}"
println(area)
}
编译并执行上述代码,输出结果为:
There are 100 apples
The area of a circle with radius 2.400000 is 18.095570
字符串类型支持的操作
字符串类型支持使用关系操作符进行比较,支持使用 + 进行拼接。下面的例子展示了字符串类型的判等和拼接:
main() {
let s1 = "abc"
var s2 = "ABC"
let r1 = s1 == s2
println("The result of 'abc' == 'ABC' is: ${r1}")
let r2 = s1 + s2
println("The result of 'abc' + 'ABC' is: ${r2}")
}
编译并执行上述代码,输出结果为:
The result of 'abc' == 'ABC' is: false
The result of 'abc' + 'ABC' is: abcABC
字符串还支持其他常见操作,例如拆分、替换等。具体操作可以参考《仓颉编程语言标准库 API 》的 String 介绍,下面给出部分常见操作:
main() {
var s1 = "abc"
var s2 = "ABCabc"
var s3 = "abcyyabcqqabcbc"
let r1 = s2.contains(s1) // 判断s2中是否包含字符串s1
println(r1) // true
let r2 = s3.split(s1) //对原字符串 s3 按照字符串 s1 分隔符分割,指定是否删除空串
println(r2[1]) // yy
s1 = s2
println(s1) // ABCabc
}
元组类型
元组(Tuple)可以将多个不同的类型组合在一起,成为一个新的类型。元组类型使用 (T1, T2, ..., TN) 表示,其中 T1 到 TN 可以是任意类型,不同类型间使用逗号(,)连接。元组至少是二元,例如,(Int64, Float64) 表示一个二元组类型,(Int64, Float64, String) 表示一个三元组类型。
元组的长度是固定的,即一旦定义了一个元组类型的实例,它的长度不能再被更改。
元组类型是不可变类型,即一旦定义了一个元组类型的实例,它的内容(即单个元素)不能再被更新。但整个元组可被覆盖替换,例如:
let tuple1 = (8, false)
var tuple2 = (true, 9, 20)
tuple2 = tuple1 // Error, mismatched types
tuple2[0] = false // Error, 'tuple element' can not be assigned
var tuple3 = (9, true)
tuple3 = tuple1
println(tuple3[0]) // 8
println(tuple3[1]) // false
元组类型的字面量
元组类型的字面量使用 (e1, e2, ..., eN) 表示,其中 e1 到 eN 是表达式,多个表达式之间使用逗号分隔。下面的例子中,分别定义了一个 (Int64, Float64) 类型的变量 x,以及一个 (Int64, Float64, String) 类型的变量 y,并且使用元组类型的字面量为它们定义了初值:
let x: (Int64, Float64) = (3, 3.141592)
let y: (Int64, Float64, String) = (3, 3.141592, "PI")
元组支持通过 t[index] 的方式访问某个具体位置的元素,其中 t 是一个元组,index 是下标,并且 index 只能是从 0 开始且小于元组元素个数的整数类型字面量,否则编译报错。下面的例子中,使用 pi[0] 和 pi[1] 可以分别访问二元组 pi 的第一个元素和第二个元素。
main() {
var pi = (3.14, "PI")
println(pi[0])
println(pi[1])
}
编译并执行上述代码,输出结果为:
3.140000
PI
在赋值表达式中,可使用元组进行多赋值,参见赋值操作符章节。
元组类型的类型参数
可以为元组类型标记显式的类型参数名,下面例子中的 name 和 price 就是 类型参数名。
func getFruitPrice (): (name: String, price: Int64) {
return ("banana", 10)
}
对于一个元组类型,只允许统一写类型参数名,或者统一不写类型参数名,不允许交替存在,并且参数名本身不能作为变量使用或用于访问元组中元素。
let a: (name: String, Int64) = ("banana", 5) // Error
let b: (name: String, price: Int64) = ("banana", 5) // OK
b.name // Error
数组类型
Array
可以使用 Array 类型来构造单一元素类型,有序序列的数据。
仓颉使用 Array<T> 来表示 Array 类型。T 表示 Array 的元素类型,T 可以是任意类型。
var a: Array<Int64> = [0, 0, 0, 0] // Array whose element type is Int64
var b: Array<String> = ["a1", "a2", "a3"] // Array whose element type is String
元素类型不相同的 Array 是不相同的类型,所以它们之间不可以互相赋值。
因此以下例子是不合法的。
b = a // Type mismatch
可以轻松使用字面量来初始化一个 Array,只需要使用方括号将逗号分隔的值列表括起来即可。
编译器会根据上下文自动推断 Array 字面量的类型。
let a: Array<String> = [] // Created an empty Array whose element type is String
let b = [1, 2, 3, 3, 2, 1] // Created a Array whose element type is Int64, containing elements 1, 2, 3, 3, 2, 1
也可以使用构造函数的方式构造一个指定元素类型的 Array。其中,repeat 属于 Array 构造函数中的一个命名参数。
需要注意的是,当通过 repeat 指定的初始值初始化 Array 时,该构造函数不会拷贝 repeat,如果 repeat 是一个引用类型,构造后数组的每一个元素都将指向相同的引用。
let a = Array<Int64>() // Created an empty Array whose element type is Int64
let c = Array<Int64>(3, repeat: 0) // Created an Array whose element type is Int64, length is 3 and all elements are initialized as 0
let d = Array<Int64>(3, {i => i + 1}) // Created an Array whose element type is Int64, length is 3 and all elements are initialized by the initialization function
示例中 let d = Array<Int64>(3, {i => i + 1}) 使用了 lambda 表达式作为初始化函数来初始化数组中的每一个元素,即 {i => i + 1}。
访问 Array 成员
当需要对 Array 的所有元素进行访问时,可以使用 for-in 循环遍历 Array 的所有元素。
Array 是按元素插入顺序排列的,因此对 Array 遍历的顺序总是恒定的。
main() {
let arr = [0, 1, 2]
for (i in arr) {
println("The element is ${i}")
}
}
编译并执行上面的代码,会输出:
The element is 0
The element is 1
The element is 2
当需要知道某个 Array 包含的元素个数时,可以使用 size 属性获得对应信息。
main() {
let arr = [0, 1, 2]
if (arr.size == 0) {
println("This is an empty array")
} else {
println("The size of array is ${arr.size}")
}
}
编译并执行上面的代码,会输出:
The size of array is 3
当想访问单个指定位置的元素时,可以使用下标语法访问(下标的类型必须是 Int64)。非空 Array 的第一个元素总是从位置 0 开始的。可以从 0 开始访问 Array 的任意一个元素,直到最后一个位置(Array 的 size - 1)。索引值不能使用负数或者大于等于 size,当编译器能检查出索引值非法时,会在编译时报错,否则会在运行时抛异常。
main() {
let arr = [0, 1, 2]
let a = arr[0] // a == 0
let b = arr[1] // b == 1
let c = arr[-1] // array size is '3', but access index is '-1', which would overflow
}
如果想获取某一段 Array 的元素,可以在下标中传入 Range 类型的值,就可以一次性取得 Range 对应范围的一段 Array。
let arr1 = [0, 1, 2, 3, 4, 5, 6]
let arr2 = arr1[0..5] // arr2 contains the elements 0, 1, 2, 3, 4
当 Range 字面量在下标语法中使用时,可以省略 start 或 end。
当省略 start 时,Range 会从 0 开始;当省略 end 时,Range 的 end 会延续到最后一位。
let arr1 = [0, 1, 2, 3, 4, 5, 6]
let arr2 = arr1[..3] // arr2 contains elements 0, 1, 2
let arr3 = arr1[2..] // arr3 contains elements 2, 3, 4, 5, 6
修改 Array
Array 是一种长度不变的 Collection 类型,因此 Array 没有提供添加和删除元素的成员函数。
但是 Array 允许对其中的元素进行修改,同样使用下标语法。
main() {
let arr = [0, 1, 2, 3, 4, 5]
arr[0] = 3
println("The first element is ${arr[0]}")
}
编译并执行上面的代码,会输出:
The first element is 3
Array 虽然是 struct 类型,但其内部持有的只是元素的引用,因此在作为表达式使用时不会拷贝副本,同一个 Array 实例的所有引用都会共享同样的元素数据。
因此对 Array 元素的修改会影响到该实例的所有引用。
let arr1 = [0, 1, 2]
let arr2 = arr1
arr2[0] = 3
// arr1 contains elements 3, 1, 2
// arr2 contains elements 3, 1, 2
VArray
除了引用类型的数组 Array,仓颉还引入了值类型数组 VArray<T, $N> ,其中 T 表示该值类型数组的元素类型,$N 是一个固定的语法。通过 $ 加上一个 Int64 类型的数值字面量表示这个值类型数组的长度。需要注意的是,VArray<T, $N> 不能省略 <T, $N>,且使用类型别名时,不允许拆分 VArray 关键字与其泛型参数。
与频繁使用引用类型 Array 相比,使用值类型 VArray 可以减少堆上内存分配和垃圾回收的压力。但是需要注意的是,由于值类型本身在传递和赋值时的拷贝,会产生额外的性能开销,因此建议不要在性能敏感场景使用较大长度的 VArray。值类型和引用类型的特点请参见值类型和引用类型变量。
type varr1 = VArray<Int64, $3> // Ok
type varr2 = VArray // Error
注意:
由于运行时后端限制,当前
VArray<T, $N>的元素类型T或T的成员不能包含引用类型、枚举类型、Lambda 表达式(CFunc除外)以及未实例化的泛型类型。
VArray 可以由一个数组的字面量来进行初始化,左值 a 必须标识出 VArray 的实例化类型:
var a: VArray<Int64, $3> = [1, 2, 3]
同时,它拥有两个构造函数:
// VArray<T, $N>(initElement: (Int64) -> T)
let b = VArray<Int64, $5>({ i => i }) // [0, 1, 2, 3, 4]
// VArray<T, $N>(repeat!: T)
let c = VArray<Int64, $5>(repeat: 0) // [0, 0, 0, 0, 0]
除此之外,VArray<T, $N> 类型提供了两个成员方法:
-
用于下标访问和修改的
[]操作符方法:var a: VArray<Int64, $3> = [1, 2, 3] let i = a[1] // i is 2 a[2] = 4 // a is [1, 2, 4]下标访问的下标类型必须为
Int64。 -
用于获取
VArray长度的size成员:var a: VArray<Int64, $3> = [1, 2, 3] let s = a.size // s is 3size 属性的类型为
Int64。
此外,VArray 还支持仓颉与 C 语言互操作场景使用,相关内容请参见数组。
区间类型
区间类型用于表示拥有固定步长的序列,区间类型是一个泛型,使用 Range<T> 表示。当 T 被实例化不同的类型时(要求此类型必须支持关系操作符,并且可以和 Int64 类型的值做加法),会得到不同的区间类型,如最常用的 Range<Int64> 用于表示整数区间。
每个区间类型的实例都会包含 start、end 和 step 三个值。其中,start 和 end 分别表示序列的起始值和终止值,step 表示序列中前后两个元素之间的差值(即步长);start 和 end 的类型相同(即 T 被实例化的类型),step 类型是 Int64,并且它的值不能等于 0。
下面的例子给出了区间类型的实例化方式(关于区间类型定义和其中的属性,详见《仓颉编程语言库 API》):
// Range<T>(start: T, end: T, step: Int64, hasStart: Bool, hasEnd: Bool, isClosed: Bool)
let r1 = Range<Int64>(0, 10, 1, true, true, true) // r1 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
let r2 = Range<Int64>(0, 10, 1, true, true, false) // r2 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
let r3 = Range<Int64>(10, 0, -2, true, true, false) // r3 contains 10, 8, 6, 4, 2
区间类型字面量
区间字面量有两种形式:“左闭右开”区间和“左闭右闭”区间。
- “左闭右开”区间的格式是
start..end : step,它表示一个从start开始,以step为步长,到end(不包含end)为止的区间; - “左闭右闭”区间的格式是
start..=end : step,它表示一个从start开始,以step为步长,到end(包含end)为止的区间。
下面的例子定义了若干区间类型的变量:
let n = 10
let r1 = 0..10 : 1 // r1 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
let r2 = 0..=n : 1 // r2 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
let r3 = n..0 : -2 // r3 contains 10, 8, 6, 4, 2
let r4 = 10..=0 : -2 // r4 contains 10, 8, 6, 4, 2, 0
区间字面量中,可以不写 step,此时 step 默认等于 1,但是step 的值不能等于 0。另外,区间也有可能是空的(即不包含任何元素的空序列),举例如下:
let r5 = 0..10 // the step of r5 is 1, and r5 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
let r6 = 0..10 : 0 // Error, step cannot be 0
let r7 = 10..0 : 1 // r7 to r10 are empty ranges
let r8 = 0..10 : -1
let r9 = 10..=0 : 1
let r10 = 0..=10 : -1
注意:
- 表达式
start..end : step中,当step > 0且start >= end,或者step < 0且start <= end时,start..end : step是一个空区间;- 表达式
start..=end : step中,当step > 0且start > end,或者step < 0且start < end时,start..=end : step是一个空区间。
Unit 类型
对于那些只关心副作用而不关心值的表达式,它们的类型是 Unit。例如,print 函数、赋值表达式、复合赋值表达式、自增和自减表达式、循环表达式,它们的类型都是 Unit。
Unit 类型只有一个值,也是它的字面量:()。除了赋值、判等和判不等外,Unit 类型不支持其他操作。
Nothing 类型
Nothing 是一种特殊的类型,它不包含任何值,并且 Nothing 类型是所有类型的子类型(这当中也包括 Unit 类型)。
break、continue、return 和 throw 表达式的类型是 Nothing,程序执行到这些表达式时,它们之后的代码将不会被执行。return 只能在函数体中使用,break、continue 只能在循环体中使用,参考如下示例:
while (true) {
func f() {
break // Error, break must be used directly inside a loop
}
let g = { =>
continue // Error, continue must be used directly inside a loop
}
}
由于函数的形参和其默认值不属于该函数的函数体,所以下面例子中的 return 表达式缺少包围它的函数体——它既不属于外层函数 f(因为内层函数定义 g 已经开始),也不在内层函数 g 的函数体中(该用例相关内容,请参考嵌套函数):
func f() {
func g(x!: Int64 = return) { // Error, return must be used inside a function body
0
}
1
}
注意:
目前编译器还不允许在使用类型的地方显式地使用 Nothing 类型。
定义函数
仓颉使用关键字 func 来表示函数定义的开始,func 之后依次是函数名、参数列表、可选的函数返回值类型、函数体。其中,函数名可以是任意的合法标识符,参数列表定义在一对圆括号内(多个参数间使用逗号分隔),参数列表和函数返回值类型(如果存在)之间使用冒号分隔,函数体定义在一对花括号内。
函数定义举例:
func add(a: Int64, b: Int64): Int64 {
return a + b
}
上例中定义了一个名为 add 的函数,其参数列表由两个 Int64 类型的参数 a 和 b 组成,函数返回值类型为 Int64,函数体中将 a 和 b 相加并返回。
下面依次对函数定义中的参数列表、函数返回值类型和函数体作进一步介绍。
参数列表
一个函数可以拥有 0 个或多个参数,这些参数均定义在函数的参数列表中。根据函数调用时是否需要给定参数名,可以将参数列表中的参数分为两类:非命名参数和命名参数。
非命名参数的定义方式是 p: T,其中 p 表示参数名,T 表示参数 p 的类型,参数名和其类型间使用冒号连接。例如,上例中 add 函数的两个参数 a 和 b 均为非命名参数。
命名参数的定义方式是 p!: T,与非命名参数的不同是在参数名 p 之后多了一个 !。可以将上例中 add 函数的两个非命名参数修改为命名参数,如下所示:
func add(a!: Int64, b!: Int64): Int64 {
return a + b
}
命名参数还可以设置默认值,通过 p!: T = e 方式将参数 p 的默认值设置为表达式 e 的值。例如,可以将上述 add 函数的两个参数的默认值都设置为 1:
func add(a!: Int64 = 1, b!: Int64 = 1): Int64 {
return a + b
}
注意:
只能为命名参数设置默认值,不能为非命名参数设置默认值。
参数列表中可以同时定义非命名参数和命名参数,但是需要注意的是,非命名参数只能定义在命名参数之前,也就意味着命名参数之后不能再出现非命名参数。例如,下例中 add 函数的参数列表定义是不合法的:
func add(a!: Int64, b: Int64): Int64 { // Error, named parameter 'a' must be defined after non-named parameter 'b'
return a + b
}
非命名参数和命名参数的主要差异在于调用时的不同,具体可参见下文调用函数中的介绍。
函数参数均为不可变变量,在函数定义内不能对其赋值。
func add(a: Int64, b: Int64): Int64 {
a = a + b // Error
return a
}
函数参数作用域从定义处起至函数体结束:
func add(a: Int64, b: Int64): Int64 {
var a_ = a // OK
var b = b // Error, redefinition of declaration 'b'
return a
}
函数返回值类型
函数返回值类型是函数被调用后得到的值的类型。函数定义时,返回值类型是可选的:可以显式地定义返回值类型(返回值类型定义在参数列表和函数体之间),也可以不定义返回值类型,交由编译器推导确定。
当显式地定义了函数返回值类型时,就要求函数体的类型(关于如何确定函数体的类型可参见下节函数体)、函数体中所有 return e 表达式中 e 的类型是返回值类型的子类型。例如,对于上述 add 函数,显式地定义了它的返回值类型为 Int64;如果将函数体中的 return a + b 修改为 return (a, b),则会因为类型不匹配而报错:
// Error, the type of the expression after return does not match the return type of the function
func add(a: Int64, b: Int64): Int64 {
return (a, b)
}
在函数定义时如果未显式定义返回值类型,编译器将根据函数体的类型以及函数体中所有的 return 表达式来共同推导出函数的返回值类型。例如,下例中 add 函数的返回值类型虽然被省略,但编译器可以根据 return a + b 推导出 add 函数的返回值类型是 Int64:
func add(a: Int64, b: Int64) {
return a + b
}
注意:
函数的返回值类型并不是任何情况下都可以被推导出来的,如果返回值类型推导失败,编译器会报错。
指定返回类型为 Unit 时,编译器会在函数体中所有可能返回的地方自动插入表达式 return (),使得函数的返回类型总是为 Unit。
函数体
函数体中定义了函数被调用时执行的操作,通常包含一系列的变量定义和表达式,也可以包含新的函数定义(即嵌套函数)。如下 add 函数的函数体中首先定义了 Int64 类型的变量 r(初始值为 0),接着将 a + b 的值赋值给 r,最后将 r 的值返回:
func add(a: Int64, b: Int64) {
var r = 0
r = a + b
return r
}
在函数体的任意位置都可以使用 return 表达式来终止函数的执行并返回。return 表达式有两种形式:return 和 return expr(expr 是一个表达式)。
对于 return expr,要求 expr 的类型与函数定义中的返回值类型保持一致。例如,下例中会因为 return 100 中 100 类型(Int64)和函数 foo 的返回值类型(String)不同而报错。
// Error, cannot convert an integer literal to type 'Struct-String'
func foo(): String {
return 100
}
对于 return,其等价于 return (),所以要求函数的返回值类型为 Unit。
func add(a: Int64, b: Int64) {
var r = 0
r = a + b
return r
}
func foo(): Unit {
add(1, 2)
return
}
注意:
return表达式作为一个整体,其类型并不由后面跟随的表达式决定,而是Nothing类型。
在函数体内定义的变量属于局部变量的一种(如上例中的 r 变量),它的作用域从其定义之后开始到函数体结束。
对于一个局部变量,允许在其外层作用域中定义同名变量,并且在此局部变量的作用域内,局部变量会“遮盖”外层作用域的同名变量。例如:
let r = 0
func add(a: Int64, b: Int64) {
var r = 0
r = a + b
return r
}
上例中,add 函数之前定义了 Int64 类型的全局变量 r,同时 add 函数体内定义了同名的局部变量 r,那么在函数体内,所有使用变量 r 的地方(如 r = a + b),用到的将是局部变量 r,即(在函数体内)局部变量 r “遮盖”了全局变量 r。
函数返回值类型中提到函数体也是有类型的,函数体的类型是函数体内最后一“项”的类型:若最后一项为表达式,则函数体的类型是此表达式的类型,若最后一项为变量定义或函数声明,或函数体为空,则函数体的类型为 Unit。例如:
func add(a: Int64, b: Int64): Int64 {
a + b
}
上例中,因为函数体的最后一“项”是 Int64 类型的表达式(即 a + b),所以函数体的类型也是 Int64,与函数定义的返回值类型相匹配。又如,下例中函数体的最后一项是 print 函数调用,所以函数体的类型是 Unit,同样与函数定义的返回值类型相匹配:
func foo(): Unit {
let s = "Hello"
print(s)
}
调用函数
函数调用的形式为 f(arg1, arg2, ..., argn)。其中,f 是要调用的函数的名字,arg1 到 argn 是 n 个调用时的参数(称为实参),要求每个实参的类型必须是对应参数类型的子类型。实参可以有 0 个或多个,当实参个数为 0 时,调用方式为 f()。
根据函数定义时参数是非命名参数还是命名参数的差异,函数调用时传实参的方式也有所不同:对于非命名参数,它对应的实参是一个表达式;对于命名参数,它对应的实参需要使用 p: e 的形式,其中 p 是命名参数的名字,e 是表达式(即传递给参数 p 的值)。
非命名参数调用举例:
func add(a: Int64, b: Int64) {
return a + b
}
main() {
let x = 1
let y = 2
let r = add(x, y)
println("The sum of x and y is ${r}")
}
执行结果为:
The sum of x and y is 3
命名参数调用举例:
func add(a: Int64, b!: Int64) {
return a + b
}
main() {
let x = 1
let y = 2
let r = add(x, b: y)
println("The sum of x and y is ${r}")
}
执行结果为:
The sum of x and y is 3
对于多个命名参数,调用时的传参顺序可以和定义时的参数顺序不同。例如,下例中调用 add 函数时 b 可以出现在 a 之前:
func add(a!: Int64, b!: Int64) {
return a + b
}
main() {
let x = 1
let y = 2
let r = add(b: y, a: x)
println("The sum of x and y is ${r}")
}
执行结果为:
The sum of x and y is 3
对于拥有默认值的命名参数,调用时如果没有传实参,那么此参数将使用默认值作为实参的值。例如,下例中调用 add 函数时没有为参数 b 传实参,那么参数 b 的值等于其定义时的默认值 2:
func add(a: Int64, b!: Int64 = 2) {
return a + b
}
main() {
let x = 1
let r = add(x)
println("The sum of x and y is ${r}")
}
执行结果为:
The sum of x and y is 3
对于拥有默认值的命名参数,调用时也可以为其传递新的实参,此时命名参数的值等于新的实参的值,即定义时的默认值将失效。例如,下例中调用 add 函数时为参数 b 传了新的实参值 20,那么参数 b 的值就等于 20:
func add(a: Int64, b!: Int64 = 2) {
return a + b
}
main() {
let x = 1
let r = add(x, b: 20)
println("The sum of x and y is ${r}")
}
执行结果为:
The sum of x and y is 21
函数类型
仓颉编程语言中,函数是一等公民(first-class citizens),可以作为函数的参数或返回值,也可以赋值给变量。因此函数本身也有类型,称之为函数类型。
函数类型由函数的参数类型和返回类型组成,参数类型和返回类型之间使用 -> 连接。参数类型使用圆括号 () 括起来,可以有 0 个或多个参数,如果参数超过一个,参数类型之间使用逗号(,)分隔。
例如:
func hello(): Unit {
println("Hello!")
}
上述示例定义了一个函数,函数名为 hello,其类型是 () -> Unit,表示该函数没有参数,返回类型为 Unit。
以下给出另一些示例:
-
示例:函数名为
display,其类型是(Int64) -> Unit,表示该函数有一个参数,参数类型为Int64,返回类型为Unit。func display(a: Int64): Unit { println(a) } -
示例:函数名为
add,其类型是(Int64, Int64) -> Int64,表示该函数有两个参数,两个参数类型均为Int64,返回类型为Int64。func add(a: Int64, b: Int64): Int64 { a + b } -
示例:函数名为
returnTuple,其类型是(Int64, Int64) -> (Int64, Int64),两个参数类型均为Int64, 返回类型为元组类型:(Int64, Int64)。func returnTuple(a: Int64, b: Int64): (Int64, Int64) { (a, b) }
函数类型的类型参数
可以为函数类型标记显式的类型参数名,下面例子中的 name 和 price 就是 类型参数名。
func showFruitPrice(name: String, price: Int64) {
println("fruit: ${name} price: ${price} yuan")
}
main() {
let fruitPriceHandler: (name: String, price: Int64) -> Unit
fruitPriceHandler = showFruitPrice
fruitPriceHandler("banana", 10)
}
另外对于一个函数类型,只允许统一写类型参数名,或者统一不写类型参数名,不能交替存在。
let handler: (name: String, Int64) -> Int64 // Error
函数类型作为参数类型
示例:函数名为 printAdd,其类型是 ((Int64, Int64) -> Int64, Int64, Int64) -> Unit,表示该函数有三个参数,参数类型分别为函数类型 (Int64, Int64) -> Int64 和两个 Int64,返回类型为 Unit。
func printAdd(add: (Int64, Int64) -> Int64, a: Int64, b: Int64): Unit {
println(add(a, b))
}
函数类型作为返回类型
函数类型可以作为另一个函数的返回类型。
如下示例中,函数名为 returnAdd,其类型是 () -> (Int64, Int64) -> Int64,表示该函数无参数,返回类型为函数类型 (Int64, Int64) -> Int64。注意,-> 是右结合的。
func add(a: Int64, b: Int64): Int64 {
a + b
}
func returnAdd(): (Int64, Int64) -> Int64 {
add
}
main() {
var a = returnAdd()
println(a(1,2))
}
函数类型作为变量类型
函数名本身也是表达式,它的类型为对应的函数类型。
func add(p1: Int64, p2: Int64): Int64 {
p1 + p2
}
let f: (Int64, Int64) -> Int64 = add
上述示例中,函数名是 add,其类型为 (Int64, Int64) -> Int64。变量 f 的类型与 add 类型相同,add 被用来初始化 f。
若一个函数在当前作用域中被重载(见函数重载)了,那么直接使用该函数名作为表达式可能产生歧义,如果产生歧义编译器会报错,例如:
func add(i: Int64, j: Int64) {
i + j
}
func add(i: Float64, j: Float64) {
i + j
}
main() {
var f = add // Error, ambiguous function 'add'
var plus: (Int64, Int64) -> Int64 = add // OK
}
嵌套函数
定义在源文件顶层的函数被称为全局函数。定义在函数体内的函数被称为嵌套函数。
示例,函数 foo 内定义了一个嵌套函数 nestAdd,可以在 foo 内调用该嵌套函数 nestAdd,也可以将嵌套函数 nestAdd 作为返回值返回,在 foo 外对其进行调用:
func foo() {
func nestAdd(a: Int64, b: Int64) {
a + b + 3
}
println(nestAdd(1, 2)) // 6
return nestAdd
}
main() {
let f = foo()
let x = f(1, 2)
println("result: ${x}")
}
程序会输出:
6
result: 6
Lambda 表达式
Lambda 表达式定义
Lambda 表达式是一种匿名函数(即没有函数名的函数),其核心设计目的是在程序中快速定义简短的函数逻辑,无需显式声明函数名称。这一概念起源于数学中的 λ 演算(lambda calculus),后被引入多种编程语言(如 C++、Python、C# 等),用于简化代码并提升灵活性。仓颉编程语言中也引入了 Lambda 表达式,具体使用介绍将在本小节展开介绍。
Lambda 表达式的语法为如下形式: { p1: T1, ..., pn: Tn => expressions | declarations }。
其中,=> 之前为参数列表,多个参数之间使用 , 分隔,每个参数名和参数类型之间使用 : 分隔。=> 之前也可以没有参数。=> 之后为 Lambda 表达式体,是一组表达式或声明序列。Lambda 表达式的参数名的作用域与函数的相同,为 Lambda 表达式的函数体部分,其作用域级别可视为与 Lambda 表达式的函数体内定义的变量等同。
let f1 = { a: Int64, b: Int64 => a + b }
var display = { => // Parameterless lambda expression.
println("Hello")
println("World")
}
Lambda 表达式不管有没有参数,都不可以省略 =>,除非其作为尾随 lambda。例如:
var display = { => println("Hello") }
func f2(lam: () -> Unit) {}
let f2Res = f2 { println("World") } // OK to omit the =>
Lambda 表达式中参数的类型标注可缺省。以下情形中,若参数类型省略,编译器会尝试进行类型推断,当编译器无法推断出类型时会编译报错:
- Lambda 表达式赋值给变量时,其参数类型根据变量类型推断;
- Lambda 表达式作为函数调用表达式的实参使用时,其参数类型根据函数的形参类型推断。
// The parameter types are inferred from the type of the variable sum1
var sum1: (Int64, Int64) -> Int64 = { a, b => a + b }
var sum2: (Int64, Int64) -> Int64 = { a: Int64, b => a + b }
func f(a1: (Int64) -> Int64): Int64 {
a1(1)
}
main(): Int64 {
// The parameter type of lambda is inferred from the type of function f
f({ a2 => a2 + 10 })
}
Lambda 表达式中不支持声明返回类型,其返回类型总是从上下文中推断出来,若无法推断则报错。
-
若上下文明确指定了 Lambda 表达式的返回类型,则其返回类型为上下文指定的类型。
-
Lambda 表达式赋值给变量时,其返回类型根据变量类型推断返回类型:
let f: () -> Unit = { ... } -
Lambda 表达式作为参数使用时,其返回类型根据使用处所在的函数调用的形参类型推断:
func f(a1: (Int64) -> Int64): Int64 { a1(1) } main(): Int64 { f({ a2: Int64 => a2 + 10 }) } -
Lambda 表达式作为返回值使用时,其返回类型根据使用处所在函数的返回类型推断:
func f(): (Int64) -> Int64 { { a: Int64 => a } }
-
-
若上下文中类型未明确,与推导函数的返回值类型类似,编译器会根据 Lambda 表达式体中所有 return 表达式
return xxx中 xxx 的类型,以及 Lambda 表达式体的类型,来共同推导出 Lambda 表达式的返回类型。-
=>右侧的内容与普通函数体的规则一样,返回类型为Int64:let sum1 = { a: Int64, b: Int64 => a + b } -
=>的右侧为空,返回类型为Unit:let f = { => }
-
Lambda 表达式调用
Lambda 表达式支持立即调用,例如:
let r1 = { a: Int64, b: Int64 => a + b }(1, 2) // r1 = 3
let r2 = { => 123 }() // r2 = 123
Lambda 表达式也可以赋值给一个变量,使用变量名进行调用,例如:
func f() {
var g = { x: Int64 => println("x = ${x}") }
g(2)
}
闭包
一个函数或 lambda 从定义它的静态作用域中捕获了变量,函数或 lambda 和捕获的变量一起被称为一个闭包,这样即使脱离了闭包定义所在的作用域,闭包也能正常运行。
函数或 lambda 的定义中对于以下几种变量的访问,称为变量捕获:
-
函数的参数缺省值中访问了本函数之外定义的局部变量;
-
函数或 lambda 内访问了本函数或本 lambda 之外定义的局部变量;
-
class/struct内定义的不是成员函数的函数或 lambda 访问了实例成员变量或this。
以下情形的变量访问不是变量捕获:
-
对定义在本函数或本 lambda 内的局部变量的访问;
-
对本函数或本 lambda 的形参的访问;
-
对全局变量和静态成员变量的访问;
-
对实例成员变量在实例成员函数或属性中的访问。由于实例成员函数或属性将
this作为参数传入,在实例成员函数或属性内通过this访问所有实例成员变量。
变量的捕获发生在闭包定义时,因此变量捕获有以下规则:
-
被捕获的变量必须在闭包定义时可见,否则编译报错;
-
被捕获的变量必须在闭包定义时已经完成初始化,否则编译报错。
示例 1:闭包 add,捕获了 let 声明的局部变量 num,之后通过返回值返回到 num 定义的作用域之外,调用 add 时仍可正常访问 num。
func returnAddNum(): (Int64) -> Int64 {
let num: Int64 = 10
func add(a: Int64) {
return a + num
}
add
}
main() {
let f = returnAddNum()
println(f(10))
}
程序输出的结果为:
20
示例 2:捕获的变量必须在闭包定义时可见。
func f() {
let x = 99
func f1() {
println(x)
}
let f2 = { =>
println(y) // Error, cannot capture 'y' which is not defined yet
}
let y = 88
f1() // Print 99
f2()
}
示例 3:捕获的变量必须在闭包定义前完成初始化。
func f() {
let x: Int64
func f1() {
println(x) // Error, x is not initialized yet
}
x = 99
f1()
}
如果捕获的变量是引用类型,可修改其可变实例成员变量的值。
class C {
public var num: Int64 = 0
}
func returnIncrementer(): () -> Unit {
let c: C = C()
func incrementer() {
c.num++
}
incrementer
}
main() {
let f = returnIncrementer()
f() // c.num increases by 1
}
为了防止捕获了 var 声明变量的闭包逃逸,这类闭包只能被调用,不能作为一等公民使用,包括不能赋值给变量,不能作为实参或返回值使用,不能直接将闭包的名字作为表达式使用。
func f() {
var x = 1
let y = 2
func g() {
println(x) // OK, captured a mutable variable
}
let b = g // Error, g cannot be assigned to a variable
g // Error, g cannot be used as an expression
g() // OK, g can be invoked
g // Error, g cannot be used as a return value
}
需要注意的是,捕获具有传递性。如果一个函数 f 调用了捕获 var 变量的函数 g,且 g 捕获的 var 变量不在函数 f 内定义,那么函数 f 同样捕获了 var 变量,此时,f 也不能作为一等公民使用。
以下示例中,g 捕获了 var 声明的变量 x,f 调用了 g,且 g 捕获的 x 不在 f 内定义,f 同样不能作为一等公民使用:
func h(){
var x = 1
func g() { x } // captured a mutable variable
func f() {
g() // invoked g
}
return f // Error
}
以下示例中,g 捕获了 var 声明的变量 x,f 调用了 g。但 g 捕获的 x 在 f 内定义,f 没有捕获其他 var 声明的变量。因此,f 仍作为一等公民使用:
func h(){
func f() {
var x = 1
func g() { x } // captured a mutable variable
g()
}
return f // Ok
}
静态成员变量和全局变量的访问,不属于变量捕获,因此访问了 var 修饰的全局变量、静态成员变量的函数或 lambda 仍可作为一等公民使用。
class C {
static public var a: Int32 = 0
static public func foo() {
a++ // OK
return a
}
}
var globalV1 = 0
func countGlobalV1() {
globalV1++
C.a = 99
let g = C.foo // OK
}
func g(){
let f = countGlobalV1 // OK
f()
}
函数调用语法糖
尾随 lambda
尾随 lambda 可以使函数的调用看起来像是语言内置的语法一样,增加语言的可扩展性。
当函数最后一个形参是函数类型,并且函数调用对应的实参是 lambda 时,可以使用尾随 lambda 语法,将 lambda 放在函数调用的尾部,圆括号外面。
例如,下例中定义了一个 myIf 函数,它的第一个参数是 Bool 类型,第二个参数是函数类型。当第一个参数的值为 true 时,返回第二个参数调用后的值,否则返回 0。调用 myIf 时可以像普通函数一样调用,也可以使用尾随 lambda 的方式调用。
func myIf(a: Bool, fn: () -> Int64) {
if(a) {
fn()
} else {
0
}
}
func test() {
myIf(true, { => 100 }) // General function call
myIf(true) { // Trailing closure call
100
}
}
当函数调用有且只有一个 lambda 实参时,还可以省略 (),只写 lambda。
示例:
func f(fn: (Int64) -> Int64) { fn(1) }
func test() {
f { i => i * i }
}
Flow 表达式
流操作符包括两种:表示数据流向的中缀操作符 |> (称为 pipeline)和表示函数组合的中缀操作符 ~> (称为 composition)。
Pipeline 表达式
当需要对输入数据做一系列的处理时,可以使用 pipeline 表达式来简化描述。pipeline 表达式的语法形式如下:e1 |> e2。等价于如下形式的语法糖:let v = e1; e2(v) 。
其中 e2 是函数类型的表达式,e1 的类型是 e2 的参数类型的子类型。
示例:
func inc(x: Array<Int64>): Array<Int64> { // Increasing the value of each element in the array by '1'
let s = x.size
var i = 0
for (e in x where i < s) {
x[i] = e + 1
i++
}
x
}
func sum(y: Array<Int64>): Int64 { // Get the sum of elements in the array
var s = 0
for (j in y) {
s += j
}
s
}
let arr: Array<Int64> = [1, 3, 5]
let res = arr |> inc |> sum // res = 12
Composition 表达式
composition 表达式表示两个单参函数的组合。composition 表达式语法为 f ~> g,等价于 { x => g(f(x)) }。
其中 f,g 均为只有一个参数的函数类型的表达式。
f 和 g 组合,则要求 f(x) 的返回类型是 g(...) 的参数类型的子类型。
示例 1:
func f(x: Int64): Float64 {
Float64(x)
}
func g(x: Float64): Float64 {
x
}
var fg = f ~> g // The same as { x: Int64 => g(f(x)) }
示例 2:
func f(x: Int64): Float64 {
Float64(x)
}
let lambdaComp = ({x: Int64 => x}) ~> f // The same as { x: Int64 => f({x: Int64 => x}(x)) }
示例 3:
func h1<T>(x: T): T { x }
func h2<T>(x: T): T { x }
var hh = h1<Int64> ~> h2<Int64> // The same as { x: Int64 => h2<Int64>(h1<Int64>(x)) }
注意:
表达式 f ~> g 中,会先对 f 求值,然后对 g 求值,最后才会进行函数的组合。
另外,流操作符不能与无默认值的命名形参函数直接一同使用,这是因为无默认值的命名形参函数必须给出命名实参才可以调用。例如:
func f(a!: Int64): Unit {}
var a = 1 |> f // Error
如果需要使用,开发者可以通过 lambda 表达式传入 f 函数的命名实参:
func f(a!: Int64): Unit {}
var x = 1 |> { x: Int64 => f(a: x) } // Ok
由于相同的原因,当 f 的参数有默认值时,直接与流运算符一起使用也是错误的,例如:
func f(a!: Int64 = 2): Unit {}
var a = 1 |> f // Error
但是当命名形参都存在默认值时,不需要给出命名实参也可以调用该函数,函数仅需要传入非命名形参,那么这种函数是可以同流运算符一起使用的,例如:
func f(a: Int64, b!: Int64 = 2): Unit {}
var a = 1 |> f // Ok
当然,如果想要在调用 f 时,为参数 b 传入其他参数,那么也需要借助 lambda 表达式:
func f(a: Int64, b!: Int64 = 2): Unit {}
var a = 1 |> {x: Int64 => f(x, b: 3)} // Ok
变长参数
变长参数是一种特殊的函数调用语法糖。当形参最后一个非命名参数是 Array 类型时,实参中对应位置可以直接传入参数序列代替 Array 字面量(参数个数可以是 0 个或多个)。示例如下:
func sum(arr: Array<Int64>) {
var total = 0
for (x in arr) {
total += x
}
return total
}
main() {
println(sum())
println(sum(1, 2, 3))
}
程序输出:
0
6
需要注意,只有最后一个非命名参数可以作为变长参数,命名参数不能使用这个语法糖。
func length(arr!: Array<Int64>) {
return arr.size
}
main() {
println(length()) // Error, expected 1 argument, found 0
println(length(1, 2, 3)) // Error, expected 1 argument, found 3
}
变长参数可以出现在全局函数、静态成员函数、实例成员函数、局部函数、构造函数、函数变量、lambda、函数调用操作符重载、索引操作符重载的调用处。不支持其他操作符重载、composition、pipeline 这几种调用方式。示例如下:
class Counter {
var total = 0
init(data: Array<Int64>) { total = data.size }
operator func ()(data: Array<Int64>) { total += data.size }
}
main() {
let counter = Counter(1, 2)
println(counter.total)
counter(3, 4, 5)
println(counter.total)
}
程序输出:
2
5
函数重载决议总是会优先考虑不使用变长参数就能匹配的函数,只有在所有函数都不能匹配,才尝试使用变长参数解析。示例如下:
func f<T>(x: T) where T <: ToString {
println("item: ${x}")
}
func f(arr: Array<Int64>) {
println("array: ${arr}")
}
main() {
f()
f(1)
f(1, 2)
}
程序输出:
array: []
item: 1
array: [1, 2]
当编译器无法决议时会报错:
func f(arr: Array<Int64>) { arr.size }
func f(first: Int64, arr: Array<Int64>) { first + arr.size }
main() {
println(f(1, 2, 3)) // Error
}
函数重载
函数重载定义
在仓颉编程语言中,如果一个作用域中,一个函数名对应多个函数定义,这种现象称为函数重载。
-
函数名相同,函数参数不同(是指参数个数不同,或者参数个数相同但参数类型不同)的两个函数构成重载。示例如下:
// Scenario 1 func f(a: Int64): Unit { } func f(a: Float64): Unit { } func f(a: Int64, b: Float64): Unit { } -
对于两个同名泛型函数 (详见泛型函数章节),如果重命名一个函数的泛型形参后(使泛型参数顺序相同),其非泛型部分与另一个函数的非泛型部分函数参数不同,则两个函数构成重载,否则这两个泛型函数构成重复定义错误(类型变元的约束不参与判断)。示例如下:
interface I1{} interface I2{} func f1<X, Y>(a: X, b: Y) {} func f1<Y, X>(a: X, b: Y) {} // Ok: after rename generic type parameter, it will be 'func f1<X, Y>(a: Y, b: X)' func f2<T>(a: T) where T <: I1 {} func f2<T>(a: T) where T <: I2 {} // Error, not overloading -
同一个类内的两个构造函数参数不同,构成重载。示例如下:
// Scenario 2 class C { var a: Int64 var b: Float64 public init(a: Int64, b: Float64) { this.a = a this.b = b } public init(a: Int64) { b = 0.0 this.a = a } } -
同一个类内的主构造函数和
init构造函数参数不同,构成重载(认为主构造函数和init函数具有相同的名字)。示例如下:// Scenario 3 class C { C(var a!: Int64, var b!: Float64) { this.a = a this.b = b } public init(a: Int64) { b = 0.0 this.a = a } } -
两个函数名相同,参数不同的函数定义在不同的作用域,在两个函数都可见的作用域中构成重载。示例如下:
// Scenario 4 func f(a: Int64): Unit { } func g() { func f(a: Float64): Unit { } } -
如果子类中存在与父类同名的函数,并且函数的参数类型不同,则构成函数重载。示例如下:
// Scenario 5 open class Base { public func f(a: Int64): Unit { } } class Sub <: Base { public func f(a: Float64): Unit { } }
只允许函数声明引入的函数重载,但是以下情形不构成重载,不构成重载的两个名字不能定义或声明在同一个作用域内:
- class、interface、struct 类型的静态成员函数和实例成员函数之间不能重载
- enum 类型的 constructor、静态成员函数和实例成员函数之间不能重载
如下示例,两个变量均为函数类型且函数参数类型不同,但由于它们不是函数声明所以不能重载,如下示例将编译报错(重定义错):
main() {
var f: (Int64) -> Unit
var f: (Float64) -> Unit
}
如下示例,虽然变量 f 为函数类型,但由于变量和函数之间不能同名,如下示例将编译报错(重定义错):
main() {
var f: (Int64) -> Unit
func f(a: Float64): Unit { // Error, functions and variables cannot have the same name
}
}
如下示例,静态成员函数 f 与实例成员函数 f 的参数类型不同,但由于类内静态成员函数和实例成员函数之间不能重载,如下示例将编译报错:
class C {
public static func f(a: Int64): Unit {
}
public func f(a: Float64): Unit {
}
}
函数重载决议
函数调用时,所有可被调用的函数(是指当前作用域可见且能通过类型检查的函数)构成候选集,候选集中有多个函数,究竟选择候选集中哪个函数,需要进行函数重载决议,有如下规则:
-
优先选择作用域级别高的作用域内的函数。在嵌套的表达式或函数中,越是内层作用域级别越高。
如下示例中在
inner函数体内调用g(Sub())时,候选集包括inner函数内定义的函数g和inner函数外定义的函数g,函数决议选择作用域级别更高的inner函数内定义的函数g。open class Base {} class Sub <: Base {} func outer() { func g(a: Sub) { print("1") } func inner() { func g(a: Base) { print("2") } g(Sub()) // Output: 2 } } -
如果作用域级别相对最高的仍有多个函数,则需要选择最匹配的函数(对于函数 f 和 g 以及给定的实参,如果 f 可以被调用时 g 也总是可以被调用的,但反之不然,则称 f 比 g 更匹配)。如果不存在唯一最匹配的函数,则报错。
如下示例中,两个函数
g定义在同一作用域,选择更匹配的函数g(a: Sub): Unit。open class Base {} class Sub <: Base {} func outer() { func g(a: Sub) { print("1") } func g(a: Base) { print("2") } g(Sub()) // Output: 1 } -
子类和父类认为是同一作用域。如下示例中,一个函数
g定义在父类中,另一个函数g定义在子类中,在调用s.g(Sub())时,两个函数g当成同一作用域级别决议,则选择更匹配的父类中定义的函数g(a: Sub): Unit。open class Base { public func g(a: Sub) { print("1") } } class Sub <: Base { public func g(a: Base) { print("2") } } func outer() { let s: Sub = Sub() s.g(Sub()) // Output: 1 }
操作符重载
如果希望在某个类型上支持此类型默认不支持的操作符,可以使用操作符重载实现。
如果需要在某个类型上重载某个操作符,可以通过为类型定义一个函数名为此操作符的函数的方式实现,这样,在该类型的实例使用该操作符时,就会自动调用此操作符函数。
操作符函数定义与普通函数定义相似,区别如下:
- 定义操作符函数时需要在
func关键字前面添加operator修饰符; - 操作符函数的参数个数需要匹配对应操作符的要求(详见附录操作符);
- 操作符函数只能定义在 class、interface、struct、enum 和 extend 中;
- 操作符函数具有实例成员函数的语义,所以禁止使用
static修饰符; - 操作符函数不能为泛型函数。
另外,需要注意的是,被重载后的操作符不改变它们固有的优先级和结合性(详见附录操作符)。
操作符重载函数定义和使用
定义操作符函数有两种方式:
- 对于可以直接包含函数定义的类型 (包括
struct、enum、class和interface),可以直接在其内部定义操作符函数的方式实现操作符的重载。 - 使用
extend的方式为其添加操作符函数,从而实现操作符在这些类型上的重载。对于无法直接包含函数定义的类型(是指除struct、class、enum和interface之外其他的类型)或无法改变其实现的类型,比如第三方定义的struct、class、enum和interface,只能采用这种方式(参见扩展)。
操作符函数对参数类型的约定如下:
-
对于一元操作符,操作符函数没有参数,对返回值的类型没有要求。
-
对于二元操作符,操作符函数只有一个参数,对返回值的类型没有要求。
如下示例中介绍了一元操作符和二元操作符的定义和使用:
-实现对一个Point实例中两个成员变量x和y取负值,然后返回一个新的Point对象,+实现对两个Point实例中两个成员变量x和y分别求和,然后返回一个新的Point对象。open class Point { var x: Int64 = 0 var y: Int64 = 0 public init (a: Int64, b: Int64) { x = a y = b } public operator func -(): Point { Point(-x, -y) } public operator func +(right: Point): Point { Point(this.x + right.x, this.y + right.y) } }接下来,就可以在
Point的实例上直接使用一元-操作符和二元+操作符:main() { let p1 = Point(8, 24) let p2 = -p1 // p2 = Point(-8, -24) let p3 = p1 + p2 // p3 = Point(0, 0) } -
索引操作符(
[])分为取值let a = arr[i]和赋值arr[i] = a两种形式,它们通过是否存在特殊的命名参数 value 来区分不同的重载。索引操作符重载不要求同时重载两种形式,可以只重载赋值不重载取值,反之亦可。索引操作符取值形式
[]内的参数序列对应操作符重载的非命名参数,可以是 1 个或多个,可以是任意类型。不可以有其他命名参数。返回类型可以是任意类型。class A { operator func [](arg1: Int64, arg2: String): Int64 { return 0 } } func f() { let a = A() let b: Int64 = a[1, "2"] // b == 0 }索引操作符赋值形式
[]内的参数序列对应操作符重载的非命名参数,可以是 1 个或多个,可以是任意类型。=右侧的表达式对应操作符重载的命名参数,有且只能有一个命名参数,该命名参数的名称必须是 value, 不能有默认值,value 可以是任意类型。返回类型必须是 Unit 类型。需要注意的是,value 只是一种特殊的标记,在索引操作符赋值时并不需要使用命名参数的形式调用。
class A { operator func [](arg1: Int64, arg2: String, value!: Int64): Unit { return } } func f() { let a = A() a[1, "2"] = 0 }特别的,除
enum外的不可变类型不支持重载索引操作符赋值形式。 -
函数调用操作符(
())重载函数,输入参数和返回值类型可以是任意类型。示例如下:open class A { public init() {} public operator func ()(): Unit {} } func test1() { let a = A() // Ok, A() is call the constructor of A a() // Ok, a() is to call the operator () overloading function }不能使用
this或super调用()操作符重载函数。示例如下:open class A { public init() {} public init(x: Int64) { this() // Ok, this() calls the constructor of A } public operator func ()(): Unit {} public func foo() { this() // Error, this() calls the constructor of A super() // Error } } class B <: A { public init() { super() // Ok, super() calls the constuctor of the super class } public func goo() { super() // Error } }对于枚举类型,当构造器形式和
()操作符重载函数形式都满足时,优先匹配构造器形式。示例如下:enum E { Y | X | X(Int64) public operator func ()(p: Int64) {} public operator func ()(p: Float64) {} } main() { let e = X(1) // Ok, X(1) is to call the constructor X(Int64) X(1.0) // Ok, X(1.0) is to call the operator () overloading function let e1 = X e1(1) // Ok, e1(1) is to call the operator () overloading function Y(1) // oK, Y(1) is to call the operator () overloading function }
可以被重载的操作符
下表列出了所有可以被重载的操作符(优先级从高到低):
| Operator | Description |
|---|---|
() | Function call |
[] | Indexing |
! | NOT |
- | Negative |
** | Power |
* | Multiply |
/ | Divide |
% | Remainder |
+ | Add |
- | Subtract |
<< | Bitwise left shift |
>> | Bitwise right shift |
< | Less than |
<= | Less than or equal |
> | Greater than |
>= | Greater than or equal |
== | Equal |
!= | Not equal |
& | Bitwise AND |
^ | Bitwise XOR |
| | Bitwise OR |
需要注意的是:
注意:
- 一旦在某个类型上重载了除关系操作符(
<、<=、>、>=、==和!=)之外的其他二元操作符,并且操作符函数的返回类型与左操作数的类型一致或是其子类型,那么此类型支持对应的复合赋值操作符。当操作符函数的返回类型与左操作数的类型不一致且不是其子类型时,在使用对应的复合赋值符号时将报类型不匹配错误。- 仓颉编程语言不支持自定义操作符,即不允许定义除上表中所列
operator之外的其他操作符函数。- 对于类型
T, 如果T已经默认支持了上述若干可重载操作符,那么通过扩展的方式再次为其实现同签名的操作符函数时将报重定义错误。例如,为数值类型重载其已支持的同签名算术操作符、位操作符或关系操作符等操作符时,为Rune重载同签名的关系操作符时,为Bool类型重载同签名的逻辑操作符、判等或不等操作符时,等等这些情况,均会报重定义错误。
const 函数和常量求值
常量求值允许某些特定形式的表达式在编译时求值,可以减少程序运行时需要的计算。本章主要介绍常量求值的使用方法与规则。
const 上下文与 const 表达式
const 上下文是指 const 变量初始化表达式,这些表达式始终在编译时求值。因此需要对 const 上下文中允许的表达式加以限制,避免修改全局状态、I/O 等副作用,确保其可以在编译时求值。
const 表达式具备了可以在编译时求值的能力。满足如下规则的表达式是 const 表达式:
- 数值类型、
Bool、Unit、Rune、String类型的字面量(不包含插值字符串)。 - 所有元素都是
const表达式的Array字面量(不能是Array类型,可以使用VArray类型),tuple字面量。 const变量,const函数形参,const函数中的局部变量。const函数,包含使用const声明的函数名、符合const函数要求的lambda、以及这些函数返回的函数表达式。const函数调用(包含const构造函数),该函数的表达式必须是const表达式,所有实参必须都是const表达式。- 所有参数都是
const表达式的enum构造器调用,和无参数的enum构造器。 - 数值类型、
Bool、Unit、Rune、String类型的算术表达式、关系表达式、位运算表达式,所有操作数都必须是const表达式。 if、match、try、throw、return、is、as。这些表达式内的表达式必须都是const表达式。const表达式的成员访问(不包含属性的访问),tuple的索引访问。const init和const函数中的this和super表达式。const表达式的const实例成员函数调用,且所有实参必须都是const表达式。
注意:
当前编译器实现暂不支持
throw作为const表达式使用。
const 函数
const 函数是一类特殊的函数,这些函数具备了可以在编译时求值的能力。在 const 上下文中调用这种函数时,这些函数会在编译时执行计算。而在其他非 const 上下文,const 函数会和普通函数一样在运行时执行。
下例是一个计算平面上两点距离的 const 函数,distance 中使用 let 定义了两个局部变量 dx 和 dy:
struct Point {
const Point(let x: Float64, let y: Float64) {}
}
const func distance(a: Point, b: Point) {
let dx = a.x - b.x
let dy = a.y - b.y
(dx**2 + dy**2)**0.5
}
main() {
const a = Point(3.0, 0.0)
const b = Point(0.0, 4.0)
const d = distance(a, b)
println(d)
}
编译运行输出:
5.000000
需要注意:
const函数声明必须使用const修饰。- 全局
const函数和static const函数中只能访问const声明的外部变量,包含const全局变量、const静态成员变量,其他外部变量都不可访问。const init函数和const实例成员函数除了能访问const声明的外部变量,还可以访问当前类型的实例成员变量。 const函数中的表达式都必须是const表达式,const init函数除外。const函数中可以使用let、const声明新的局部变量。但不支持var。const函数中的参数类型和返回类型没有特殊规定。如果该函数调用的实参不符合const表达式要求,那这个函数调用不能作为const表达式使用,但仍然可以作为普通表达式使用。const函数不一定都会在编译时执行,例如可以在非const函数中运行时调用。const函数与非const函数重载规则一致。- 数值类型、
Bool、Unit、Rune、String类型 和enum支持定义const实例成员函数。 - 对于
struct和class,只有定义了const init才能定义const实例成员函数。class中的const实例成员函数不能是open的。struct中的const实例成员函数不能是mut的。
另外,接口中也可以定义 const 函数,但会受到以下规则限制:
- 接口中的
const函数,实现类型必须也用const函数才算实现接口。 - 接口中的非
const函数,实现类型使用const或非const函数都算实现接口。 - 接口中的
const函数与接口的static函数一样,只有在该接口作为泛型约束的时候,受约束的泛型变元或变量才能使用这些const函数。
在下面的例子中,在接口 I 里定义了两个 const 函数,类 A 实现了接口 I,泛型函数 g 的形参类型上界是 I。
interface I {
const func f(): Int64
const static func f2(): Int64
}
class A <: I {
public const func f() { 0 }
public const static func f2() { 1 }
const init() {}
}
const func g<T>(i: T) where T <: I {
return i.f() + T.f2()
}
main() {
println(g(A()))
}
编译执行上述代码,输出结果为:
1
const init
如果一个 struct 或 class 定义了 const 构造器,那么这个 struct/class 实例可以用在 const 表达式中。
- 如果当前类型是
class,则不能具有var声明的实例成员变量,否则不允许定义const init。如果当前类型具有父类,当前的const init必须调用父类的const init(可以显式调用或者隐式调用无参const init),如果父类没有const init则报错。 - 当前类型的实例成员变量如果有初始值,初始值必须要是
const表达式,否则不允许定义const init。 const init内可以使用赋值表达式对实例成员变量赋值,除此以外不能有其他赋值表达式。
const init 与 const 函数的区别是 const init 内允许对实例成员变量进行赋值(需要使用赋值表达式)。
定义 struct 类型
struct 类型的定义以关键字 struct 开头,后跟 struct 的名字,接着是定义在一对花括号中的 struct 定义体。struct 定义体中可以定义一系列的成员变量、成员属性(参见属性)、静态初始化器、构造函数和成员函数。
struct Rectangle {
let width: Int64
let height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
}
上例中定义了名为 Rectangle 的 struct 类型,它有两个 Int64 类型的成员变量 width 和 height,一个有两个 Int64 类型参数的构造函数(使用关键字 init 定义,函数体中通常是对成员变量的初始化),以及一个成员函数 area(返回 width 和 height 的乘积)。
注意:
struct只能定义在源文件的顶层作用域。
struct 成员变量
struct 成员变量分为实例成员变量和静态成员变量(使用 static 修饰符修饰),二者访问上的区别在于实例成员变量只能通过 struct 实例(说 a 是 T 类型的实例,指的是 a 是一个 T 类型的值)访问,静态成员变量只能通过 struct 类型名访问。
实例成员变量定义时可以不设置初值(但必须标注类型,如上例中的 width 和 height),也可以设置初值,例如:
struct Rectangle {
let width = 10
let height = 20
}
struct 静态初始化器
struct 支持定义静态初始化器,并在静态初始化器中通过赋值表达式来对静态成员变量进行初始化。
静态初始化器以关键字组合 static init 开头,后跟无参参数列表和函数体,且不能被访问修饰符修饰。函数体中必须完成对所有未初始化的静态成员变量的初始化,否则编译报错。
struct Rectangle {
static let degree: Int64
static init() {
degree = 180
}
}
一个 struct 中最多允许定义一个静态初始化器,否则报重定义错误。
struct Rectangle {
static let degree: Int64
static init() {
degree = 180
}
static init() { // Error, redefinition with the previous static init function
degree = 180
}
}
struct 构造函数
struct 支持两类构造函数:普通构造函数和主构造函数。
普通构造函数以关键字 init 开头,后跟参数列表和函数体,函数体中必须完成对所有未初始化的实例成员变量的初始化(如果参数名和成员变量名无法区分,可以在成员变量前使用 this 加以区分,this 表示 struct 的当前实例),否则编译报错。
struct Rectangle {
let width: Int64
let height: Int64
public init(width: Int64, height: Int64) { // Error, 'height' is not initialized in the constructor
this.width = width
}
}
一个 struct 中可以定义多个普通构造函数,但它们必须构成重载(参见函数重载),否则报重定义错误。
struct Rectangle {
let width: Int64
let height: Int64
public init(width: Int64) {
this.width = width
this.height = width
}
public init(width: Int64, height: Int64) { // Ok: overloading with the first init function
this.width = width
this.height = height
}
public init(height: Int64) { // Error, redefinition with the first init function
this.width = height
this.height = height
}
}
除了可以定义若干普通的以 init 为名字的构造函数外,struct 内还可以定义(最多)一个主构造函数。主构造函数的名字和 struct 类型名相同,它的参数列表中可以有两种形式的形参:普通形参和成员变量形参(需要在参数名前加上 let 或 var),成员变量形参同时扮演定义成员变量和构造函数参数的功能。
使用主构造函数通常可以简化 struct 的定义,例如,上述包含一个 init 构造函数的 Rectangle 可以简化为如下定义:
struct Rectangle {
public Rectangle(let width: Int64, let height: Int64) {}
}
主构造函数的参数列表中也可以定义普通形参,例如:
struct Rectangle {
public Rectangle(name: String, let width: Int64, let height: Int64) {}
}
如果 struct 定义中不存在自定义构造函数(包括主构造函数),并且所有实例成员变量都有初始值,则会自动为其生成一个无参构造函数(调用此无参构造函数会创建一个所有实例成员变量的值均等于其初值的对象);否则,不会自动生成此无参构造函数。例如,对于如下 struct 定义,注释中给出了自动生成的无参构造函数:
struct Rectangle {
let width: Int64 = 10
let height: Int64 = 10
/* Auto-generated memberwise constructor:
public init() {
}
*/
}
struct 成员函数
struct 成员函数分为实例成员函数和静态成员函数(使用 static 修饰符修饰),二者的区别在于:实例成员函数只能通过 struct 实例访问,静态成员函数只能通过 struct 类型名访问;静态成员函数中不能访问实例成员变量,也不能调用实例成员函数,但在实例成员函数中可以访问静态成员变量以及静态成员函数。
下例中,area 是实例成员函数,typeName 是静态成员函数。
struct Rectangle {
let width: Int64 = 10
let height: Int64 = 20
public func area() {
this.width * this.height
}
public static func typeName(): String {
"Rectangle"
}
}
实例成员函数中可以通过 this 访问实例成员变量,例如:
struct Rectangle {
let width: Int64 = 1
let height: Int64 = 1
public func area() {
this.width * this.height
}
}
struct 成员的访问修饰符
struct 的成员(包括成员变量、成员属性、构造函数、成员函数、操作符函数(详见操作符重载章节))用 4 种访问修饰符修饰:private、internal、protected 和 public,缺省的修饰符是 internal。
private表示在struct定义内可见。internal表示仅当前包及子包(包括子包的子包,详见包章节)内可见。protected表示当前模块(详见包章节)可见。public表示模块内外均可见。
下面的例子中,width 是 public 修饰的成员,在类外可以访问,height 是缺省访问修饰符的成员,仅在当前包及子包可见,其他包无法访问。
package a
public struct Rectangle {
public var width: Int64
var height: Int64
private var area: Int64
...
}
func samePkgFunc() {
var r = Rectangle(10, 20)
r.width = 8 // Ok: public 'width' can be accessed here
r.height = 24 // Ok: 'height' has no modifier and can be accessed here
r.area = 30 // Error, private 'area' can't be accessed here
}
package b
import a.*
main() {
var r = Rectangle(10, 20)
r.width = 8 // Ok: public 'width' can be accessed here
r.height = 24 // Error, no modifier 'height' can't be accessed here
r.area = 30 // Error, private 'area' can't be accessed here
}
禁止递归 struct
递归和互递归定义的 struct 均是非法的。例如:
struct R1 { // Error, 'R1' recursively references itself
let other: R1
}
struct R2 { // Error, 'R2' and 'R3' are mutually recursive
let other: R3
}
struct R3 { // Error, 'R2' and 'R3' are mutually recursive
let other: R2
}
创建 struct 实例
定义了 struct 类型后,即可通过调用 struct 的构造函数来创建 struct 实例。在 struct 定义之外,通过 struct 类型名调用构造函数创建该类型实例,并可以通过实例访问满足可见性修饰符(如public )的实例成员变量和实例成员函数。例如,下例中定义了一个 Rectangle 类型的变量 r,通过 r.width 和 r.height 可分别访问 r 中 width 和 height 的值,通过 r.area() 可以调用 r 的成员函数 area。
struct Rectangle {
public var width: Int64
public var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
}
let r = Rectangle(10, 20)
let width = r.width // width = 10
let height = r.height // height = 20
let a = r.area() // a = 200
如果希望通过 struct 实例去修改成员变量的值,需要将 struct 类型的变量定义为可变变量,并且被修改的成员变量也必须是可变成员变量(使用 var 定义)。举例如下:
struct Rectangle {
public var width: Int64
public var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
}
main() {
var r = Rectangle(10, 20) // r.width = 10, r.height = 20
r.width = 8 // r.width = 8
r.height = 24 // r.height = 24
let a = r.area() // a = 192
}
在赋值或传参时,会对 struct 实例进行复制(成员变量为引用类型时,仅复制引用而不会复制引用的对象),生成新的实例,对其中一个实例的修改并不会影响另外一个实例。以赋值为例,下面的例子中,将 r1 赋值给 r2 之后,修改 r1 的 width 和 height 的值,并不会影响 r2 的 width 和 height 值。
struct Rectangle {
public var width: Int64
public var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
}
main() {
var r1 = Rectangle(10, 20) // r1.width = 10, r1.height = 20
var r2 = r1 // r2.width = 10, r2.height = 20
r1.width = 8 // r1.width = 8
r1.height = 24 // r1.height = 24
let a1 = r1.area() // a1 = 192
let a2 = r2.area() // a2 = 200
}
mut 函数
struct 类型是值类型,其实例成员函数无法修改实例本身。例如,下例中,成员函数 g 中不能修改成员变量 i 的值。
struct Foo {
var i = 0
public func g() {
i += 1 // Error, the value of a instance member variable cannot be modified in an instance member function
}
}
mut 函数是一种可以修改 struct 实例本身的特殊的实例成员函数。在 mut 函数内部,this 的语义是特殊的,这种 this 拥有原地修改字段的能力。
注意:
只允许在 interface、struct 和 struct 的扩展内定义
mut函数(class 是引用类型,实例成员函数不需要加mut也可以修改实例成员变量,所以禁止在 class 中定义mut函数)。
mut 函数定义
mut 函数与普通的实例成员函数相比,多一个 mut 关键字来修饰。
例如,下例中在函数 g 之前增加 mut 修饰符之后,即可在函数体内修改成员变量 i 的值。
struct Foo {
var i = 0
public mut func g() {
i += 1 // Ok
}
}
mut 只能修饰实例成员函数,不能修饰静态成员函数。
struct A {
public mut func f(): Unit {} // Ok
public mut operator func +(rhs: A): A { // Ok
A()
}
public mut static func g(): Unit {} // Error, static member functions cannot be modified with 'mut'
}
mut 函数中的 this 不能被捕获,也不能作为表达式。mut 函数中的 lambda 或嵌套函数不能对 struct 的实例成员变量进行捕获。
示例:
struct Foo {
var i = 0
public mut func f(): Foo {
let f1 = { => this } // Error, 'this' in mut functions cannot be captured
let f2 = { => this.i = 2 } // Error, instance member variables in mut functions cannot be captured
let f3 = { => this.i } // Error, instance member variables in mut functions cannot be captured
let f4 = { => i } // Error, instance member variables in mut functions cannot be captured
this // Error, 'this' in mut functions cannot be used as expressions
}
}
接口中的 mut 函数
接口中的实例成员函数,也可以使用 mut 修饰。
struct 类型在实现 interface 的函数时必须保持一样的 mut 修饰。struct 以外的类型实现 interface 的函数时不能使用 mut 修饰。
示例:
interface I {
mut func f1(): Unit
func f2(): Unit
}
struct A <: I {
public mut func f1(): Unit {} // Ok: as in the interface, the 'mut' modifier is used
public func f2(): Unit {} // Ok: as in the interface, the 'mut' modifier is not used
}
struct B <: I {
public func f1(): Unit {} // Error, 'f1' is modified with 'mut' in interface, but not in struct
public mut func f2(): Unit {} // Error, 'f2' is not modified with 'mut' in interface, but did in struct
}
class C <: I {
public func f1(): Unit {} // Ok
public func f2(): Unit {} // Ok
}
当 struct 的实例赋值给 interface 类型时是拷贝语义,因此 interface 的 mut 函数并不能修改 struct 实例的值。
示例:
interface I {
mut func f(): Unit
}
struct Foo <: I {
public var v = 0
public mut func f(): Unit {
v += 1
}
}
main() {
var a = Foo()
var b: I = a
b.f() // Calling 'f' via 'b' cannot modify the value of 'a'
println(a.v) // 0
}
程序输出结果为:
0
mut 函数的使用限制
因为 struct 是值类型,所以如果一个变量是 struct 类型且使用 let 声明,那么不能通过这个变量访问该类型的 mut 函数。
示例:
interface I {
mut func f(): Unit
}
struct Foo <: I {
public var i = 0
public mut func f(): Unit {
i += 1
}
}
main() {
let a = Foo()
a.f() // Error, 'a' is of type struct and is declared with 'let', the 'mut' function cannot be accessed via 'a'
var b = Foo()
b.f() // Ok
let c: I = Foo()
c.f() // Ok, 变量 c 为接口 I 类型,非 struct 类型,此处允许访问。
}
为避免逃逸,如果一个变量的类型是 struct 类型,那么这个变量不能将该类型使用 mut 修饰的函数作为一等公民来使用,只能调用这些 mut 函数。
示例:
interface I {
mut func f(): Unit
}
struct Foo <: I {
var i = 0
public mut func f(): Unit {
i += 1
}
}
main() {
var a = Foo()
var fn = a.f // Error, mut function 'f' of 'a' cannot be used as a first class citizen.
var b: I = Foo()
fn = b.f // Ok
}
为避免逃逸,非 mut 的实例成员函数(包括 lambda 表达式)不能直接访问所在类型的 mut 函数,反之可以。
示例:
struct Foo {
var i = 0
public mut func f(): Unit {
i += 1
g() // Ok
}
public func g(): Unit {
f() // Error, mut functions cannot be invoked in non-mut functions
}
}
interface I {
mut func f(): Unit {
g() // Ok
}
func g(): Unit {
f() // Error, mut functions cannot be invoked in non-mut functions
}
}
枚举类型
本节介绍仓颉中的 enum 类型。enum 类型提供了通过列举一个类型的所有可能取值来定义此类型的方式。
在很多语言中都有 enum 类型(或者称枚举类型),但是不同语言中的 enum 类型的使用方式和表达能力均有所差异,仓颉中的 enum 类型可以理解为函数式编程语言中的代数数据类型(Algebraic Data Types)。
enum 的定义
定义 enum 时需要把它所有可能的取值一一列出,称这些值为 enum 的构造器(或者 constructor)。
enum 类型的定义以关键字 enum 开头,接着是 enum 的名字,之后是定义在一对花括号中的 enum 体,enum 体中定义了若干构造器,多个构造器之间使用 | 进行分隔(第一个构造器之前的 | 是可选的)。构造器可以是有名字的,也可以是没有名字的 ...。
每个 enum 中至少存在一个有名字的构造器。有名字的构造器可以没有参数(即“无参构造器”),也可以携带若干个参数(即“有参构造器”)。如下示例代码定义了一个名为 RGBColor 的 enum 类型,它有 3 个构造器:Red、Green 和 Blue,分别表示 RGB 色彩模式中的红色、绿色和蓝色。每个构造器有一个 UInt8 类型的参数,用来表示每个颜色的亮度级别。
enum RGBColor {
| Red(UInt8) | Green(UInt8) | Blue(UInt8)
}
仓颉支持同一个 enum 中定义多个同名构造器,但是要求这些构造器的参数个数不同(认为没有参数的构造器的参数个数等于 0),例如:
enum RGBColor {
| Red | Green | Blue
| Red(UInt8) | Green(UInt8) | Blue(UInt8)
}
每个 enum 中最多只有一个没有名字的 ... 构造器,且 ... 只能是最后一个构造器。拥有 ... 构造器的 enum 称为 non-exhaustive enum。由于没有名字,这个构造器不能被直接匹配,在解构时,需要使用可匹配所有构造器的模式,如通配符模式 _ 或绑定模式,具体可参见match 表达式的定义 。例如:
enum T {
| Red | Green | Blue | ...
}
enum 支持递归定义,例如,下面的例子中使用 enum 定义了一种表达式(即 Expr),此表达式只能有 3 种形式:单独的一个数字 Num(携带一个 Int64 类型的参数)、加法表达式 Add(携带两个 Expr 类型的参数)、减法表达式 Sub(携带两个 Expr 类型的参数)。对于 Add 和 Sub 这两个构造器,其参数中递归地使用到了 Expr 自身。
enum Expr {
| Num(Int64)
| Add(Expr, Expr)
| Sub(Expr, Expr)
}
另外,在 enum 体中还可以定义一系列成员函数、操作符函数(详见操作符重载)和成员属性(详见属性),但是要求构造器、成员函数、成员属性之间不能重名。例如,下面的例子在 RGBColor 中定义了一个名为 printType 的函数,它会输出字符串 RGBColor:
enum RGBColor {
| Red | Green | Blue
public static func printType() {
print("RGBColor")
}
}
注意:
enum只能定义在源文件的顶层作用域。
enum 的使用
定义了 enum 类型之后,就可以创建此类型的实例(即 enum 值),enum 值只能取 enum 类型定义中的一个构造器。enum 没有构造函数,可以通过 类型名.构造器,或者直接使用构造器的方式来构造一个 enum 值(对于有参构造器,需要传实参)。
下例中,RGBColor 中定义了三个构造器,其中有两个无参构造器(Red 和 Green)和一个有参构造器(Blue(UInt8)),main 中定义了三个 RGBColor 类型的变量 r,g 和 b,其中,r 的值使用 RGBColor.Red 进行初始化,g 的值直接使用 Green 进行初始化,b 的值使用 Blue(100) 进行初始化:
enum RGBColor {
| Red | Green | Blue(UInt8)
}
main() {
let r = RGBColor.Red
let g = Green
let b = Blue(100)
}
当省略类型名时,enum 构造器的名字可能和类型名、变量名、函数名发生冲突。此时必须加上 enum 类型名来使用 enum 构造器,否则只会选择同名的类型、变量、函数定义。
下面的例子中,只有构造器 Blue(UInt8) 可以不带类型名使用,Red 和 Green(UInt8) 皆会因为名字冲突而不能直接使用,必须加上类型名 RGBColor。
let Red = 1
func Green(g: UInt8) {
return g
}
enum RGBColor {
| Red | Green(UInt8) | Blue(UInt8)
}
let r1 = Red // Will choose 'let Red'
let r2 = RGBColor.Red // Ok: constructed by enum type name
let g1 = Green(100) // Will choose 'func Green'
let g2 = RGBColor.Green(100) // Ok: constructed by enum type name
let b = Blue(100) // Ok: can be uniquely identified as an enum constructor
如下的例子中,只有构造器 Blue 会因为名称冲突而不能直接使用,必须加上类型名 RGBColor。
class Blue {}
enum RGBColor {
| Red | Green(UInt8) | Blue(UInt8)
}
let r = Red // Ok: constructed by enum type name
let g = Green(100) // Ok: constructed by enum type name
let b = Blue(100) // Will choose constructor of 'class Blue' and report an error
Option 类型
Option 类型使用 enum 定义,它包含两个构造器:Some 和 None。其中,Some 会携带一个参数,表示有值;None 不带参数,表示无值。当需要表示某个类型可能有值,也可能没有值时,可以选择使用 Option 类型。
Option 类型被定义为一个泛型 enum 类型,定义如下(这里仅需要知道尖括号中的 T 是一个类型形参,当 T 为不同类型时会得到不同的 Option 类型即可。关于泛型的详细介绍,可参见泛型):
enum Option<T> {
| Some(T)
| None
}
其中,Some 构造器的参数类型就是类型形参 T,当 T 被实例化为不同的类型时,会得到不同的 Option 类型,例如:Option<Int64>、Option<String>等。
Option 类型还有一种简单的写法:在类型名前加 ?。也就是说,对于任意类型 Ty,?Ty 等价于 Option<Ty>。例如,?Int64 等价于 Option<Int64>,?String 等价于 Option<String> 等等。
下面的例子展示了如何定义 Option 类型的变量:
let a: Option<Int64> = Some(100)
let b: ?Int64 = Some(100)
let c: Option<String> = Some("Hello")
let d: ?String = None
另外,虽然 T 和 Option<T> 是不同的类型,但是当明确知道某个位置需要的是 Option<T> 类型的值时,可以直接传一个 T 类型的值,编译器会用 Option<T> 类型的 Some 构造器将 T 类型的值封装成 Option<T> 类型的值(注意:这里并不是类型转换)。例如,下面的定义是合法的(等价于上例中变量 a,b 和 c 的定义):
let a: Option<Int64> = 100
let b: ?Int64 = 100
let c: Option<String> = "100"
在上下文没有明确的类型要求时,无法使用 None 直接构造出想要的类型,此时应使用 None<T> 这样的语法来构造 Option<T> 类型的数据,例如:
let a = None<Int64> // a: Option<Int64>
let b = None<Bool> // b: Option<Bool>
最后,关于 Option 的使用,请参见使用 Option。
模式概述
对于包含匹配值的 match 表达式,case 之后支持哪些模式决定了 match 表达式的表达能力。本节中将依次介绍仓颉支持的模式,包括:常量模式、通配符模式、绑定模式、tuple 模式、类型模式和 enum 模式。
常量模式
常量模式可以是整数字面量、浮点数字面量、字符字面量、布尔字面量、字符串字面量(不支持字符串插值)、Unit 字面量。
在包含匹配值的 match 表达式(参见match 表达式)中使用常量模式时,要求常量模式表示的值的类型与待匹配值的类型相同,匹配成功的条件是待匹配的值与常量模式表示的值相等。
下面的例子中,根据 score 的值(假设 score 只能取 0 到 100 间被 10 整除的值),输出考试成绩的等级:
main() {
let score = 90
let level = match (score) {
case 0 | 10 | 20 | 30 | 40 | 50 => "D"
case 60 => "C"
case 70 | 80 => "B"
case 90 | 100 => "A" // Matched.
case _ => "Not a valid score"
}
println(level)
}
编译执行上述代码,输出结果为:
A
-
在模式匹配的目标是静态类型为
Rune的值时,Rune字面量和单字符字符串字面量都可用于表示Rune类型字面量的常量 pattern。func translate(n: Rune) { match (n) { case "A" => 1 case "B" => 2 case "C" => 3 case _ => -1 } } main() { println(translate(r"C")) }编译执行上述代码,输出结果为:
3 -
在模式匹配的目标是静态类型为
Byte的值时,一个表示 ASCII 字符的字符串字面量可用于表示Byte类型字面量的常量 pattern。func translate(n: Byte) { match (n) { case "1" => 1 case "2" => 2 case "3" => 3 case _ => -1 } } main() { println(translate(51)) // UInt32(r'3') == 51 }编译执行上述代码,输出结果为:
3
通配符模式
通配符模式使用下划线 _ 表示,可以匹配任意值。通配符模式通常作为最后一个 case 中的模式,用来匹配其他 case 未覆盖到的情况,如常量模式中匹配 score 值的示例中,最后一个 case 中使用 _ 来匹配无效的 score 值。
绑定模式
绑定模式使用 id 表示,id 是一个合法的标识符。与通配符模式相比,绑定模式同样可以匹配任意值,但绑定模式会将匹配到的值与 id 进行绑定,在 => 之后可以通过 id 访问其绑定的值。
下面的例子中,最后一个 case 中使用了绑定模式,用于绑定非 0 值:
main() {
let x = -10
let y = match (x) {
case 0 => "zero"
case n => "x is not zero and x = ${n}" // Matched.
}
println(y)
}
编译执行上述代码,输出结果为:
x is not zero and x = -10
使用 | 连接多个模式时不能使用绑定模式,也不可嵌套出现在其他模式中,否则会报错:
main() {
let opt = Some(0)
match (opt) {
case x | x => {} // Error, variable cannot be introduced in patterns connected by '|'
case Some(x) | Some(x) => {} // Error, variable cannot be introduced in patterns connected by '|'
case x: Int64 | x: String => {} // Error, variable cannot be introduced in patterns connected by '|'
}
}
绑定模式 id 相当于新定义了一个名为 id 的不可变变量(其作用域从引入处开始到该 case 结尾处),因此在 => 之后无法对 id 进行修改。例如,下例中最后一个 case 中对 n 的修改是不允许的。
main() {
let x = -10
let y = match (x) {
case 0 => "zero"
case n => n = n + 0 // Error, 'n' cannot be modified.
"x is not zero"
}
println(y)
}
对于每个 case 分支,=> 之后变量作用域级别与 case 后 => 前引入的变量作用域级别相同,在 => 之后再次引入相同名字会触发重定义错误。例如:
main() {
let x = -10
let y = match (x) {
case 0 => "zero"
case n => let n = 0 // Error, redefinition
println(n)
"x is not zero"
}
println(y)
}
注意:
当模式的 identifier 为 enum 构造器时,该模式会被当成 enum 模式进行匹配,而不是绑定模式(关于 enum 模式,详见 enum 模式章节)。
enum RGBColor {
| Red | Green | Blue
}
main() {
let x = Red
let y = match (x) {
case Red => "red" // The 'Red' is enum mode here.
case _ => "not red"
}
println(y)
}
编译执行上述代码,输出结果为:
red
Tuple 模式
Tuple 模式用于 tuple 值的匹配,它的定义和 tuple 字面量类似:(p_1, p_2, ..., p_n),区别在于这里的 p_1 到 p_n(n 大于等于 2)是模式(可以是本章节中介绍的任何模式,多个模式间使用逗号分隔)而不是表达式。
例如,(1, 2, 3) 是一个包含三个常量模式的 tuple 模式,(x, y, _) 是一个包含两个绑定模式,一个通配符模式的 tuple 模式。
给定一个 tuple 值 tv 和一个 tuple 模式 tp,当且仅当 tv 每个位置处的值均能与 tp 中对应位置处的模式相匹配,才称 tp 能匹配 tv。例如,(1, 2, 3) 仅可以匹配 tuple 值 (1, 2, 3),(x, y, _) 可以匹配任何三元 tuple 值。
下面的例子中,展示了 tuple 模式的使用:
main() {
let tv = ("Alice", 24)
let s = match (tv) {
case ("Bob", age) => "Bob is ${age} years old"
case ("Alice", age) => "Alice is ${age} years old" // Matched, "Alice" is a constant pattern, and 'age' is a variable pattern.
case (name, 100) => "${name} is 100 years old"
case (_, _) => "someone"
}
println(s)
}
编译执行上述代码,输出结果为:
Alice is 24 years old
同一个 tuple 模式中不允许引入多个名称相同的绑定模式。例如,下例中最后一个 case 中的 case (x, x) 是不合法的。
main() {
let tv = ("Alice", 24)
let s = match (tv) {
case ("Bob", age) => "Bob is ${age} years old"
case ("Alice", age) => "Alice is ${age} years old"
case (name, 100) => "${name} is 100 years old"
case (x, x) => "someone" // Error, Cannot introduce a variable pattern with the same name, which will be a redefinition error.
}
println(s)
}
类型模式
类型模式用于判断一个值的运行时类型是否是某个类型的子类型。类型模式有两种形式:_: Type(嵌套一个通配符模式 _)和 id: Type(嵌套一个绑定模式 id),它们的区别是后者会发生变量绑定,而前者不会。
对于待匹配值 v 和类型模式 id: Type(或 _: Type),首先判断 v 的运行时类型是否是 Type 的子类型,若成立则视为匹配成功,否则视为匹配失败;如匹配成功,则将 v 的类型转换为 Type 并与 id 进行绑定(对于 _: Type,不存在绑定这一操作)。
假设有如下两个类,Base 和 Derived,并且 Derived 是 Base 的子类,Base 的无参构造函数中将 a 的值设置为 10,Derived 的无参构造函数中将 a 的值设置为 20:
open class Base {
var a: Int64
public init() {
a = 10
}
}
class Derived <: Base {
public init() {
a = 20
}
}
下面的代码展示了使用类型模式并匹配成功的例子:
main() {
var d = Derived()
var r = match (d) {
case b: Base => b.a // Matched.
case _ => 0
}
println("r = ${r}")
}
编译执行上述代码,输出结果为:
r = 20
下面的代码展示了使用类型模式但类型模式匹配失败的例子:
open class Base {
var a: Int64
public init() {
a = 10
}
}
class Derived <: Base {
public init() {
a = 20
}
}
main() {
var b = Base()
var r = match (b) {
case d: Derived => d.a // Type pattern match failed.
case _ => 0 // Matched.
}
println("r = ${r}")
}
编译执行上述代码,输出结果为:
r = 0
enum 模式
enum 模式用于匹配 enum 类型的实例,它的定义和 enum 的构造器类似:无参构造器 C 或有参构造器 C(p_1, p_2, ..., p_n),构造器的类型前缀可以省略,区别在于这里的 p_1 到 p_n(n 大于等于 1)是模式。例如,Some(1) 是一个包含一个常量模式的 enum 模式,Some(x) 是一个包含一个绑定模式的 enum 模式。
给定一个 enum 实例 ev 和一个 enum 模式 ep,当且仅当 ev 的构造器名字和 ep 的构造器名字相同,且 ev 参数列表中每个位置处的值均能与 ep 中对应位置处的模式相匹配,才称 ep 能匹配 ev。例如,Some("one") 仅可以匹配 Option<String> 类型的Some 构造器 Option<String>.Some("one"),Some(x) 可以匹配任何 Option 类型的 Some 构造器。
下面的例子中,展示了 enum 模式的使用,因为 x 的构造器是 Year,所以会和第一个 case 匹配:
enum TimeUnit {
| Year(UInt64)
| Month(UInt64)
}
main() {
let x = Year(2)
let s = match (x) {
case Year(n) => "x has ${n * 12} months" // Matched.
case TimeUnit.Month(n) => "x has ${n} months"
}
println(s)
}
编译执行上述代码,输出结果为:
x has 24 months
使用 | 连接多个 enum 模式:
enum TimeUnit {
| Year(UInt64)
| Month(UInt64)
}
main() {
let x = Year(2)
let s = match (x) {
case Year(0) | Year(1) | Month(_) => "Ok" // Ok
case Year(2) | Month(m) => "invalid" // Error, Variable cannot be introduced in patterns connected by '|'
case Year(n: UInt64) | Month(n: UInt64) => "invalid" // Error, Variable cannot be introduced in patterns connected by '|'
}
println(s)
}
使用 match 表达式匹配 enum 值时,要求 case 之后的模式要覆盖待匹配 enum 类型中的所有构造器,如果未做到完全覆盖,编译器将报错:
enum RGBColor {
| Red | Green | Blue
}
main() {
let c = Green
let cs = match (c) { // Error, Not all constructors of RGBColor are covered.
case Red => "Red"
case Green => "Green"
}
println(cs)
}
可以通过加上 case Blue 来实现完全覆盖,也可以在 match 表达式的最后通过使用 case _ 来覆盖其他 case 未覆盖的到的情况,如:
enum RGBColor {
| Red | Green | Blue
}
main() {
let c = Blue
let cs = match (c) {
case Red => "Red"
case Green => "Green"
case _ => "Other" // Matched.
}
println(cs)
}
上述代码的执行结果为:
Other
模式的嵌套组合
Tuple 模式和 enum 模式可以嵌套任意模式。下面的代码展示了不同模式嵌套组合使用:
enum TimeUnit {
| Year(UInt64)
| Month(UInt64)
}
enum Command {
| SetTimeUnit(TimeUnit)
| GetTimeUnit
| Quit
}
main() {
let command = (SetTimeUnit(Year(2022)), SetTimeUnit(Year(2024)))
match (command) {
case (SetTimeUnit(Year(year)), _) => println("Set year ${year}")
case (_, SetTimeUnit(Month(month))) => println("Set month ${month}")
case _ => ()
}
}
编译并执行上述代码,输出结果为:
Set year 2022
模式的 Refutability
模式可以分为两类:refutable 模式和 irrefutable 模式。在类型匹配的前提下,当一个模式有可能和待匹配值不匹配时,称此模式为 refutable 模式;反之,当一个模式总是可以和待匹配值匹配时,称此模式为 irrefutable 模式。
对于上述介绍的各种模式,规定如下:
常量模式是 refutable 模式。例如,下例中第一个 case 中的 1 和第二个 case 中的 2 都有可能和 x 的值不相等。
func constPat(x: Int64) {
match (x) {
case 1 => "one"
case 2 => "two"
case _ => "_"
}
}
通配符模式是 irrefutable 模式。例如,下例中无论 x 的值是多少,_ 总能和其匹配。
func wildcardPat(x: Int64) {
match (x) {
case _ => "_"
}
}
绑定模式是 irrefutable 模式。例如,下例中无论 x 的值是多少,绑定模式 a 总能和其匹配。
func varPat(x: Int64) {
match (x) {
case a => "x = ${a}"
}
}
Tuple 模式是 irrefutable 模式,当且仅当其包含的每个模式都是 irrefutable 模式。例如,下例中 (1, 2) 和 (a, 2) 都有可能和 x 的值不匹配,所以它们是 refutable 模式,而 (a, b) 可以匹配任何 x 的值,所以它是 irrefutable 模式。
func tuplePat(x: (Int64, Int64)) {
match (x) {
case (1, 2) => "(1, 2)"
case (a, 2) => "(${a}, 2)"
case (a, b) => "(${a}, ${b})"
}
}
类型模式是 refutable 模式。例如,下例中(假设 Base 是 Derived 的父类,并且 Base 实现了接口 I),x 的运行时类型有可能既不是 Base 也不是 Derived,所以 a: Derived 和 b: Base 均是 refutable 模式。
interface I {}
open class Base <: I {}
class Derived <: Base {}
func typePat(x: I) {
match (x) {
case a: Derived => "Derived"
case b: Base => "Base"
case _ => "Other"
}
}
enum 模式是 irrefutable 模式,当且仅当它对应的 enum 类型中只有一个有参构造器,且 enum 模式中包含的其他模式也是 irrefutable 模式。例如,对于下例中的 E1 和 E2 定义,函数 enumPat1 中的 A(1) 是 refutable 模式,A(a) 是 irrefutable 模式;而函数 enumPat2 中的 B(b) 和 C(c) 均是 refutable 模式。
enum E1 {
A(Int64)
}
enum E2 {
B(Int64) | C(Int64)
}
func enumPat1(x: E1) {
match (x) {
case A(1) => "A(1)"
case A(a) => "A(${a})"
}
}
func enumPat2(x: E2) {
match (x) {
case B(b) => "B(${b})"
case C(c) => "C(${c})"
}
}
match 表达式
match 表达式的定义
仓颉支持两种 match 表达式,第一种是包含待匹配值的 match 表达式,第二种是不含待匹配值的 match 表达式。
含匹配值的 match 表达式:
main() {
let x = 0
match (x) {
case 1 => let r1 = "x = 1"
print(r1)
case 0 => let r2 = "x = 0" // Matched.
print(r2)
case _ => let r3 = "x != 1 and x != 0"
print(r3)
}
}
match 表达式以关键字 match 开头,后跟要匹配的值(如上例中的 x,x 可以是任意表达式),接着是定义在一对花括号内的若干 case 分支。
每个 case 分支以关键字 case 开头,case 之后是一个模式或多个由 | 连接的相同种类的模式(如上例中的 1、0、_ 都是模式,详见模式概述章节);模式之后可以接一个可选的 pattern guard,表示本条 case 匹配成功后额外需要满足的条件,pattern guard 使用 where cond 表示,要求表达式 cond 的类型为 Bool;接着是一个 =>,=> 之后即本条 case 分支匹配成功后需要执行的操作,可以是一系列表达式、变量和函数定义(新定义的变量或函数的作用域从其定义处开始到下一个 case 之前结束),如上例中的变量定义和 print 函数调用。
match 表达式执行时依次将 match 之后的表达式与每个 case 中的模式进行匹配,一旦匹配成功(如果有 pattern guard,也需要 where 之后的表达式的值为 true;如果 case 中有多个由 | 连接的模式,只要待匹配值和其中一个模式匹配则认为匹配成功)则执行 => 之后的代码然后退出 match 表达式的执行(意味着不会再去匹配它之后的 case),如果匹配不成功则继续与它之后的 case 中的模式进行匹配,直到匹配成功(match 表达式可以保证一定存在匹配的 case 分支)。
上例中,因为 x 的值等于 0,所以会和第二条 case 分支匹配(此处使用的是常量模式,匹配的是值是否相等,详见常量模式章节),最后输出 x = 0。
编译并执行上述代码,输出结果为:
x = 0
match 表达式要求所有匹配必须是穷尽(exhaustive)的,意味着待匹配表达式的所有可能取值都应该被考虑到。当 match 表达式非穷尽,或者编译器判断不出是否穷尽时,均会编译报错,换言之,所有 case 分支(包含 pattern guard)所覆盖的取值范围的并集,应该包含待匹配表达式的所有可能取值。常用的确保 match 表达式穷尽的方式是在最后一个 case 分支中使用通配符模式 _,因为 _ 可以匹配任何值。
match 表达式的穷尽性保证了一定存在和待匹配值相匹配的 case 分支。下面的例子将编译报错,因为所有的 case 并没有覆盖 x 的所有可能取值:
func nonExhaustive(x: Int64) {
match (x) {
case 0 => print("x = 0")
case 1 => print("x = 1")
case 2 => print("x = 2")
}
}
如果被匹配值的类型包含 enum 类型且该 enum 为 non-exhaustive enum,则其在匹配时需要使用可匹配所有构造器的模式,如通配符模式 _ 和绑定模式。
enum T {
| Red | Green | Blue | ...
}
func foo(a: T) {
match (a) {
case Red => 0
case Green => 1
case Blue => 2
case _ => -1
}
}
func bar(a: T) {
match (a) {
case Red => 0
case k => -1 // simple binding pattern
}
}
func baz(a: T) {
match (a) {
case Red => 0
case k: T => -1 // binding pattern with nested type pattern
}
}
在 case 分支的模式之后,可以使用 pattern guard 进一步对匹配出来的结果进行判断。
在下面的例子中(使用到了 enum 模式,详见 enum 模式章节),当 RGBColor 的构造器的参数值大于等于 0 时,输出它们的值,当参数值小于 0 时,认为它们的值等于 0:
enum RGBColor {
| Red(Int16) | Green(Int16) | Blue(Int16)
}
main() {
let c = RGBColor.Green(-100)
let cs = match (c) {
case Red(r) where r < 0 => "Red = 0"
case Red(r) => "Red = ${r}"
case Green(g) where g < 0 => "Green = 0" // Matched.
case Green(g) => "Green = ${g}"
case Blue(b) where b < 0 => "Blue = 0"
case Blue(b) => "Blue = ${b}"
}
print(cs)
}
编译执行上述代码,输出结果为:
Green = 0
没有匹配值的 match 表达式:
main() {
let x = -1
match {
case x > 0 => print("x > 0")
case x < 0 => print("x < 0") // Matched.
case _ => print("x = 0")
}
}
与包含待匹配值的 match 表达式相比,关键字 match 之后并没有待匹配的表达式,并且 case 之后不再是 pattern,而是类型为 Bool 的表达式(上述代码中的 x > 0 和 x < 0)或者 _(表示 true),当然,case 中也不再有 pattern guard。
无匹配值的 match 表达式执行时依次判断 case 之后的表达式的值,直到遇到值为 true 的 case 分支;一旦某个 case 之后的表达式值等于 true,则执行此 case 中 => 之后的代码,然后退出 match 表达式的执行(意味着不会再去判断该 case 之后的其他 case)。
上例中,因为 x 的值等于 -1,所以第二条 case 分支中的表达式(即 x < 0)的值等于 true,执行 print("x < 0")。
编译并执行上述代码,输出结果为:
x < 0
match 表达式的类型
对于 match 表达式(无论是否有匹配值):
-
在上下文有明确的类型要求时,要求每个
case分支中=>之后的代码块的类型是上下文所要求的类型的子类型; -
在上下文没有明确的类型要求时,
match表达式的类型是每个case分支中=>之后的代码块的类型的最小公共父类型; -
当
match表达式的值没有被使用时,其类型为Unit,不要求各分支的类型有最小公共父类型。
下面分别举例说明。
let x = 2
let s: String = match (x) {
case 0 => "x = 0"
case 1 => "x = 1"
case _ => "x != 0 and x != 1" // Matched.
}
上面的例子中,定义变量 s 时,显式地标注了其类型为 String,属于上下文类型信息明确的情况,因此要求每个 case 的 => 之后的代码块的类型均是 String 的子类型,显然上例中 => 之后的字符串类型的字面量均满足要求。
再来看一个没有上下文类型信息的例子:
let x = 2
let s = match (x) {
case 0 => "x = 0"
case 1 => "x = 1"
case _ => "x != 0 and x != 1" // Matched.
}
上例中,定义变量 s 时,未显式标注其类型,因为每个 case 的 => 之后的代码块的类型均是 String,所以 match 表达式的类型是 String,进而可确定 s 的类型也是 String。
其他使用模式的地方
模式除了可以在 match 表达式中使用外,还可以使用在变量定义(等号左侧是一个模式)和 for in 表达式(for 关键字和 in 关键字之间是一个模式)中。
但是,并不是所有的模式都能使用在变量定义和 for in 表达式中,只有 irrefutable 的模式才能在这两处被使用,所以只有通配符模式、绑定模式、irrefutable tuple 模式和 irrefutable enum 模式是允许的。
-
变量定义和
for in表达式中使用通配符模式的例子如下:main() { let _ = 100 for (_ in 1..5) { println("0") } }上例中,变量定义时使用了通配符模式,表示定义了一个没有名字的变量(当然此后也就没办法对其进行访问),
for in表达式中使用了通配符模式,表示不会将1..5中的元素与某个变量绑定(当然循环体中就无法访问1..5中元素值)。编译执行上述代码,输出结果为:0 0 0 0 -
变量定义和
for in表达式中使用绑定模式的例子如下:main() { let x = 100 println("x = ${x}") for (i in 1..5) { println(i) } }上例中,变量定义中的
x以及for in表达式中的i都是绑定模式。编译执行上述代码,输出结果为:x = 100 1 2 3 4 -
变量定义和
for in表达式中使用irrefutabletuple 模式的例子如下:main() { let (x, y) = (100, 200) println("x = ${x}") println("y = ${y}") for ((i, j) in [(1, 2), (3, 4), (5, 6)]) { println("Sum = ${i + j}") } }上例中,变量定义时使用了 tuple 模式,表示对
(100, 200)进行解构并分别和x与y进行绑定,效果上相当于定义了两个变量x和y。for in表达式中使用了 tuple 模式,表示依次将[(1, 2), (3, 4), (5, 6)]中的 tuple 类型的元素取出,然后解构并分别和i与j进行绑定,循环体中输出i + j的值。编译执行上述代码,输出结果为:x = 100 y = 200 Sum = 3 Sum = 7 Sum = 11 -
变量定义和
for in表达式中使用irrefutableenum 模式的例子如下:enum RedColor { Red(Int64) } main() { let Red(red) = Red(0) println("red = ${red}") for (Red(r) in [Red(10), Red(20), Red(30)]) { println("r = ${r}") } }上例中,变量定义时使用了 enum 模式,表示对
Red(0)进行解构并将构造器的参数值(即0)与red进行绑定。for in表达式中使用了 enum 模式,表示依次将[Red(10), Red(20), Red(30)]中的元素取出,然后解构并将构造器的参数值与r进行绑定,循环体中输出r的值。编译执行上述代码,输出结果为:red = 0 r = 10 r = 20 r = 30
类
class 类型是面向对象编程中的经典概念,仓颉中同样支持使用 class 来实现面向对象编程。class 与 struct 的主要区别在于:class 是引用类型,struct 是值类型,它们在赋值或传参时行为是不同的;class 之间可以继承,但 struct 之间不能继承。
本节依次介绍如何定义 class 类型,如何创建对象,以及 class 的继承。
class 定义
class 类型的定义以关键字 class 开头,后跟 class 的名字,接着是定义在一对花括号中的 class 定义体。class 定义体中可以定义一系列的成员变量、成员属性(参见属性)、静态初始化器、构造函数、成员函数和操作符函数(详见操作符重载)。
class Rectangle {
let width: Int64
let height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
}
上例中定义了名为 Rectangle 的 class 类型,它有两个 Int64 类型的成员变量 width 和 height,一个有两个 Int64 类型参数的构造函数,以及一个成员函数 area(返回 width 和 height 的乘积)。
注意:
class只能定义在源文件的顶层作用域。
使用 abstract 修饰的类为抽象类,与普通类不同的是,在抽象类中除了可以定义普通的函数,还允许声明抽象函数(没有函数体)。抽象类定义时的 open 修饰符是可选的,也可以使用 sealed 修饰符修饰抽象类,表示该抽象类只能在本包被继承。下例中在抽象类 AbRectangle 中定义了抽象函数 foo。
abstract class AbRectangle {
public func foo(): Unit
}
注意:
- 抽象类中禁止定义
private的抽象函数;- 不能为抽象类创建实例;
- 抽象类的非抽象子类必须实现父类中的所有抽象函数。
class 成员变量
class 成员变量分为实例成员变量和静态成员变量,静态成员变量使用 static 修饰符修饰,没有静态初始化器时必须有初值,只能通过类型名访问,参考如下示例:
class Rectangle {
let width = 10
static let height = 20
}
let l = Rectangle.height // l = 20
实例成员变量定义时可以不设置初值(但必须标注类型),也可以设置初值,只能通过对象(即类的实例)访问,参考如下示例:
class Rectangle {
let width = 10
let height: Int64
init(h: Int64){
height = h
}
}
let rec = Rectangle(20)
let l = rec.height // l = 20
class 静态初始化器
class 支持定义静态初始化器,并在静态初始化器中通过赋值表达式来对静态成员变量进行初始化。
静态初始化器以关键字组合 static init 开头,后跟无参参数列表和函数体,且不能被访问修饰符修饰。函数体中必须完成对所有未初始化的静态成员变量的初始化,否则编译报错。
class Rectangle {
static let degree: Int64
static init() {
degree = 180
}
}
一个 class 中最多允许定义一个静态初始化器,否则报重定义错误。
class Rectangle {
static let degree: Int64
static init() {
degree = 180
}
static init() { // Error, redefinition with the previous static init function
degree = 180
}
}
class 构造函数
和 struct 一样,class 中也支持定义普通构造函数和主构造函数。
普通构造函数以关键字 init 开头,后跟参数列表和函数体,函数体中必须完成所有未初始化实例成员变量的初始化,否则编译报错。
class Rectangle {
let width: Int64
let height: Int64
public init(width: Int64, height: Int64) { // Error, 'height' is not initialized in the constructor
this.width = width
}
}
一个类中可以定义多个普通构造函数,但它们必须构成重载(参见函数重载),否则报重定义错误。
class Rectangle {
let width: Int64
let height: Int64
public init(width: Int64) {
this.width = width
this.height = width
}
public init(width: Int64, height: Int64) { // Ok: overloading with the first init function
this.width = width
this.height = height
}
public init(height: Int64) { // Error, redefinition with the first init function
this.width = height
this.height = height
}
}
除了可以定义若干普通的以 init 为名字的构造函数外,class 内还可以定义(最多)一个主构造函数。主构造函数的名字和 class 类型名相同,它的参数列表中可以有两种形式的形参:普通形参和成员变量形参(需要在参数名前加上 let 或 var),成员变量形参同时具有定义成员变量和构造函数参数的功能。
使用主构造函数通常可以简化 class 的定义,例如,上述包含一个 init 构造函数的 Rectangle 可以简化为如下定义:
class Rectangle {
public Rectangle(let width: Int64, let height: Int64) {}
}
主构造函数的参数列表中也可以定义普通形参,例如:
class Rectangle {
public Rectangle(name: String, let width: Int64, let height: Int64) {}
}
创建类的实例时调用的构造函数,将根据以下顺序执行类中的表达式:
- 先初始化主构造函数之外定义的有缺省值的变量;
- 如果构造函数体内未显式调用父类构造函数或本类其他构造函数,则调用父类的无参构造函数
super(),如果父类没有无参构造函数,则报错; - 执行构造函数体内的代码。
func foo(x: Int64): Int64 {
println("I'm foo, got ${x}")
x
}
open class A {
init() {
println("I'm A")
}
}
class B <: A {
var x = foo(0)
init() {
x = foo(1)
println("init B finished")
}
}
main() {
B()
0
}
上述例子中,调用 B 的构造函数时,首先初始化有缺省值的变量 x,此时 foo(0) 被调用;之后调用父类的无参构造函数,此时 A 的构造函数被调用;接下来执行构造函数体内的代码,此时 foo(1) 被调用,并打印字符串。因此上例的输出为:
I'm foo, got 0
I'm A
I'm foo, got 1
init B finished
如果 class 定义中不存在自定义构造函数(包括主构造函数),并且所有实例成员变量都有初始值,则会自动为其生成一个无参构造函数(调用此无参构造函数会创建一个所有实例成员变量的值均等于其初值的对象);否则,不会自动生成此无参构造函数。例如,对于如下 class 定义,编译器会为其自动生成一个无参构造函数:
class Rectangle {
let width = 10
let height = 20
/* Auto-generated parameterless constructor:
public init() {
}
*/
}
// Invoke the auto-generated parameterless constructor
let r = Rectangle() // r.width = 10,r.height = 20
class 终结器
class 支持定义终结器,这个函数在类的实例被垃圾回收的时候被调用。终结器的函数名固定为 ~init。终结器通常用于释放系统资源:
class C {
var p: CString
init(s: String) {
p = unsafe { LibC.mallocCString(s) }
println(s)
}
~init() {
unsafe { LibC.free(p) }
}
}
使用终结器有些限制条件,需要开发者注意:
-
终结器没有参数,没有返回类型,没有泛型类型参数,没有任何修饰符,也不可以被显式调用。
-
带有终结器的类不可被
open修饰,只有非open的类可以拥有终结器。 -
一个类最多只能定义一个终结器。
-
终结器不可以定义在扩展中。
-
终结器被触发的时机是不确定的。
-
终结器可能在任意一个线程上执行。
-
多个终结器的执行顺序是不确定的。
-
终结器向外抛出未捕获异常属于未定义行为。
-
终结器中创建线程或者使用线程同步功能属于未定义行为。
-
终结器执行结束之后,如果这个对象还可以被继续访问,则属于未定义行为。
-
如果对象在初始化过程中抛出异常,这样未完整初始化的对象的终结器不会执行。
-
依赖终结器的同步行为属于未定义行为。例如,下例中
main函数通过while (Test.t0 != 0)等待Test类中的终结器修改t0的值,属于未定义行为。import std.collection.* import std.runtime.* class Test { public static var t0 : Int32 = 0 public init () { t0++ } ~init () { t0-- } } var list: ArrayList<Test> = ArrayList<Test>() func foo() : Int32 { let o1 = Test() list.add(o1) if (Test.t0 != 1) { return 1 } list.remove(at: 0) return 0 } main() : Int64 { var i : Int64 = 0 while (i < 100) { if (foo() != 0) { print("fail: obj is freed before gc!") return 1 } gc(heavy: true) // blocking gc expected // wait ~init() to be executed while (Test.t0 != 0) { // error, this is undefined behavior continue } i++ } return 0 }
class 成员函数
class 成员函数同样分为实例成员函数和静态成员函数(使用 static 修饰符修饰),实例成员函数只能通过对象访问,静态成员函数只能通过 class 类型名访问;静态成员函数中不能访问实例成员变量,也不能调用实例成员函数,但在实例成员函数中可以访问静态成员变量以及静态成员函数。
下例中,area 是实例成员函数,typeName 是静态成员函数。
class Rectangle {
let width: Int64 = 10
let height: Int64 = 20
public func area() {
this.width * this.height
}
public static func typeName(): String {
"Rectangle"
}
}
根据是否有函数体,实例成员函数又可以分为抽象成员函数和非抽象成员函数。抽象成员函数没有函数体,只能定义在抽象类或接口(详见接口)中。需要注意的是,抽象实例成员函数默认具有 open 的语义,open 修饰符是可选的,且必须使用 public 或 protected 进行修饰。
非抽象函数必须有函数体,在函数体中可以通过 this 访问实例成员变量,例如:
class Rectangle {
let width: Int64 = 10
let height: Int64 = 20
public func area() {
this.width * this.height
}
}
class 成员的访问修饰符
对于 class 的成员(包括成员变量、成员属性、构造函数、成员函数),可以使用的访问修饰符有 4 种访问修饰符修饰:private、internal、protected 和 public,缺省的含义是 internal。
private表示在class定义内可见。internal表示仅当前包及子包(包括子包的子包,详见包)内可见。protected表示当前模块(详见包)及当前类的子类可见。public表示模块内外均可见。
package a
public open class Rectangle {
public var width: Int64
protected var height: Int64
private var area: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
this.area = this.width * this.height
}
init(width: Int64, height: Int64, multiple: Int64) {
this.width = width
this.height = height
this.area = width * height * multiple
}
}
func samePkgFunc() {
var r = Rectangle(10, 20) // Ok: constructor 'Rectangle' can be accessed here
r.width = 8 // Ok: public 'width' can be accessed here
r.height = 24 // Ok: protected 'height' can be accessed here
r.area = 30 // Error, private 'area' cannot be accessed here
}
package b
import a.*
public class Cuboid <: Rectangle {
private var length: Int64
public init(width: Int64, height: Int64, length: Int64) {
super(width, height)
this.length = length
}
public func volume() {
this.width * this.height * this.length // Ok: protected 'height' can be accessed here
}
}
main() {
var r = Rectangle(10, 20, 2) // Error, Rectangle has no `public` constructor with three parameters
var c = Cuboid(20, 20, 20)
c.width = 8 // Ok: public 'width' can be accessed here
c.height = 24 // Error, protected 'height' cannot be accessed here
c.area = 30 // Error, private 'area' cannot be accessed here
}
This 类型
在类内部,支持 This 类型占位符,代指当前类的类型。它只能被作为实例成员函数的返回类型来使用,当使用子类对象调用在父类中定义的返回 This 类型的函数时,该函数调用的类型会被识别为子类类型,而非定义所在的父类类型。
如果实例成员函数没有声明返回类型,并且只存在返回 This 类型表达式时,当前函数的返回类型会推断为 This。示例如下:
open class C1 {
func f(): This { // its type is `() -> C1`
return this
}
func f2() { // its type is `() -> C1`
return this
}
public open func f3(): C1 {
return this
}
}
class C2 <: C1 {
// member function f is inherited from C1, and its type is `() -> C2` now
public override func f3(): This { // Ok
return this
}
}
var obj1: C2 = C2()
var obj2: C1 = C2()
var x = obj1.f() // During compilation, the type of x is C2
var y = obj2.f() // During compilation, the type of y is C1
创建对象
定义了 class 类型后,即可通过调用其构造函数来创建对象(通过 class 类型名调用构造函数)。例如,下例中通过 Rectangle(10, 20) 创建 Rectangle 类型的对象并赋值给变量 r。创建对象之后,可以通过对象访问(public 修饰的)实例成员变量和实例成员函数。例如,下例中通过 r.width 和 r.height 可分别访问 r 中 width 和 height 的值,通过 r.area() 可以调用成员函数 area。
class Rectangle {
let width: Int64
let height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
this.width * this.height
}
}
let r = Rectangle(10, 20) // r.width = 10, r.height = 20
let width = r.width // width = 10
let height = r.height // height = 20
let a = r.area() // a = 200
如果希望通过对象去修改成员变量的值(不鼓励这种方式,最好还是通过成员函数去修改),需要将 class 类型中的成员变量定义为可变成员变量(即使用 var 定义)。举例如下:
class Rectangle {
public var width: Int64
public var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
}
main() {
let r = Rectangle(10, 20) // r.width = 10, r.height = 20
r.width = 8 // r.width = 8
r.height = 24 // r.height = 24
let a = r.area() // a = 192
}
不同于 struct,对象在赋值或传参时,不会将对象进行复制,多个变量指向的是同一个对象,通过一个变量去修改对象中成员的值,其他变量中对应的成员变量也会被修改。以赋值为例,下面的例子中,将 r1 赋值给 r2 之后,修改 r1 的 width 和 height 的值,r2 的 width 和 height 值也同样会被修改。
class Rectangle {
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
this.width * this.height
}
}
main() {
var r1 = Rectangle(10, 20) // r1.width = 10, r1.height = 20
var r2 = r1 // r2.width = 10, r2.height = 20
r1.width = 8 // r1.width = 8
r1.height = 24 // r1.height = 24
let a1 = r1.area() // a1 = 192
let a2 = r2.area() // a2 = 192
}
class 的继承
像大多数支持 class 的编程语言一样,仓颉中的 class 同样支持继承。如果类 B 继承类 A,则称 A 为父类,B 为子类。子类将继承父类中除 private 成员和构造函数以外的所有成员。
抽象类总是可被继承的,故抽象类定义时的 open 修饰符是可选的,也可以使用 sealed 修饰符修饰抽象类,表示该抽象类只能在本包被继承。但非抽象的类可被继承是有条件的:定义时必须使用修饰符 open 修饰。当带 open 修饰的实例成员被 class 继承时,该 open 的修饰符也会被继承。当非 open 修饰的类中存在 open 修饰的成员时,编译器会给出告警。
可以在子类定义处通过 <: 指定其继承的父类,但要求父类必须是可继承的。例如,下面的例子中,class A 使用 open 修饰,是可以被类 B 继承的,但是因为类 B 是不可继承的,所以 C 在继承 B 的时候会报错。
open class A {
let a: Int64 = 10
}
class B <: A { // Ok: 'B' Inheritance 'A'
let b: Int64 = 20
}
class C <: B { // Error, 'B' is not inheritable
let c: Int64 = 30
}
class 仅支持单继承,因此下面这样一个类继承两个类的代码是不合法的(& 是类实现多个接口时的语法,详见接口)。
open class A {
let a: Int64 = 10
}
open class B {
let b: Int64 = 20
}
class C <: A & B { // Error, 'C' can only inherit one class
let c: Int64 = 30
}
因为类是单继承的,所以任何类都最多只能有一个直接父类。对于定义时指定了父类的 class,它的直接父类就是定义时指定的类,对于定义时未指定父类的 class,它的直接父类是 Object 类型。Object 是所有类的父类(注意,Object 没有直接父类,并且 Object 中不包含任何成员)。
因为子类是继承自父类的,所以子类的对象天然可以当做父类的对象使用,但是反之不然。例如,下例中 B 是 A 的子类,那么 B 类型的对象可以赋值给 A 类型的变量,但是 A 类型的对象不能赋值给 B 类型的变量。
open class A {
let a: Int64 = 10
}
class B <: A {
let b: Int64 = 20
}
let a: A = B() // Ok: subclass objects can be assigned to superclass variables
open class A {
let a: Int64 = 10
}
class B <: A {
let b: Int64 = 20
}
let b: B = A() // Error, superclass objects can not be assigned to subclass variables
class 定义的类型不允许继承类型本身。
class A <: A {} // Error, 'A' inherits itself.
抽象类可以使用 sealed 修饰符,表示被修饰的类定义只能在本定义所在的包内被其他类继承。sealed 已经蕴含了 public/open 的语义,因此定义 sealed abstract class 时若提供 public/open 修饰符,编译器将会告警。sealed 的子类可以不是 sealed 类,仍可被 open/sealed 修饰,或不使用任何继承性修饰符。若 sealed 类的子类被 open 修饰,则其子类可在包外被继承。sealed 的子类可以不被 public 修饰。
package A
public sealed abstract class C1 {} // Warning, redundant modifier, 'sealed' implies 'public'
sealed open abstract class C2 {} // Warning, redundant modifier, 'sealed' implies 'open'
sealed abstract class C3 {} // OK, 'public' is optional when 'sealed' is used
class S1 <: C1 {} // OK
public open class S2 <: C1 {} // OK
public sealed abstract class S3 <: C1 {} // OK
open class S4 <: C1 {} // OK
package B
import A.*
class SS1 <: S2 {} // OK
class SS2 <: S3 {} // Error, S3 is sealed class, cannot be inherited here.
sealed class SS3 {} // Error, 'sealed' cannot be used on non-abstract class.
父类构造函数调用
子类的 init 构造函数可以使用 super(args) 的形式调用父类构造函数,或使用 this(args) 的形式调用本类其他构造函数,但两者之间只能调用一个。如果调用,必须在构造函数体内的第一个表达式处,在此之前不能有任何表达式或声明。
open class A {
A(let a: Int64) {}
}
class B <: A {
let b: Int64
init(b: Int64) {
super(30)
this.b = b
}
init() {
this(20)
}
}
子类的主构造函数中,可以使用 super(args) 的形式调用父类构造函数,但不能使用 this(args) 的形式调用本类其他构造函数。
如果子类的构造函数没有显式调用父类构造函数,也没有显式调用其他构造函数,编译器会在该构造函数体的开始处插入直接父类的无参构造函数的调用。如果此时父类没有无参构造函数,则会编译报错。
open class A {
let a: Int64
init() {
a = 100
}
}
open class B <: A {
let b: Int64
init(b: Int64) {
// OK, `super()` added by compiler
this.b = b
}
}
open class C <: B {
let c: Int64
init(c: Int64) { // Error, there is no non-parameter constructor in super class
this.c = c
}
}
覆盖和重定义
子类中可以覆盖(override)父类中的同名非抽象实例成员函数,即在子类中为父类中的某个实例成员函数定义新的实现。覆盖时,要求父类中的成员函数使用 open 修饰,子类中的同名函数使用 override 修饰,其中 override 是可选的。例如,下面的例子中,子类 B 中的函数 f 覆盖了父类 A 中的函数 f。
open class A {
public open func f(): Unit {
println("I am superclass")
}
}
class B <: A {
public override func f(): Unit {
println("I am subclass")
}
}
main() {
let a: A = A()
let b: A = B()
a.f()
b.f()
}
对于被覆盖的函数,调用时将根据变量的运行时类型(由实际赋给该变量的对象决定)确定调用的版本(即所谓的动态派发)。例如,上例中 a 的运行时类型是 A,因此 a.f() 调用的是父类 A 中的函数 f;b 的运行时类型是 B(编译时类型是 A),因此 b.f() 调用的是子类 B 中的函数 f。所以程序会输出:
I am superclass
I am subclass
对于静态函数,子类中可以重定义父类中的同名非抽象静态函数,即在子类中为父类中的某个静态函数定义新的实现。重定义时,要求子类中的同名静态函数使用 redef 修饰,其中 redef 是可选的。例如,下面的例子中,子类 D 中的函数 foo 重定义了父类 C 中的函数 foo。
open class C {
public static func foo(): Unit {
println("I am class C")
}
}
class D <: C {
public redef static func foo(): Unit {
println("I am class D")
}
}
main() {
C.foo()
D.foo()
}
对于被重定义的函数,调用时将根据 class 的类型决定调用的版本。例如,上例中 C.foo() 调用的是父类 C 中的函数 foo,D.foo() 调用的是子类 D 中的函数 foo。
I am class C
I am class D
如果抽象函数或 open 修饰的函数有命名形参,那么实现函数或 override 修饰的函数也需要保持同样的命名形参。
open class A {
public open func f(a!: Int32): Int32 {
a + 1
}
}
class B <: A {
public override func f(a!: Int32): Int32 { // Ok
a + 2
}
}
class C <: A {
public override func f(b!: Int32): Int32 { // Error
b + 3
}
}
main() {
B().f(a: 0)
C().f(b: 0)
}
还需要注意的是,当实现或重定义的函数为泛型函数时,子类型函数的类型变元约束需要比父类型中对应函数更宽松或相同。
open class A {}
open class B <: A {}
open class C <: B {}
open class Base {
public open func foo<T>(a: T): Unit where T <: B {}
public open func bar<T>(a: T): Unit where T <: B {}
public static func f<T>(a: T): Unit where T <: B {}
public static func g<T>(): Unit where T <: B {}
}
class D <: Base {
public override func foo<T>(a: T): Unit where T <: C {} // Error, stricter constraint
public override func bar<T>(a: T): Unit where T <: C {} // Error, stricter constraint
public redef static func f<T>(a: T): Unit where T <: C {} // Error, stricter constraint
public redef static func g<T>(): Unit where T <: C {} // Error, stricter constraint
}
class E <: Base {
public override func foo<T>(a: T): Unit where T <: A {} // OK: looser constraint
public override func bar<V>(a: V): Unit where V <: A {} // OK: looser constraint, names of generic parameters do not matter
public redef static func f<T>(a: T): Unit where T <: A {} // OK: looser constraint
public redef static func g<T>(): Unit where T <: A {} // OK: looser constraint
}
class F <: Base {
public override func foo<T>(a: T): Unit where T <: B {} // OK: same constraint
public override func bar<V>(a: V): Unit where V <: B {} // OK: same constraint
public redef static func f<T>(a: T): Unit where T <: B {} // OK: same constraint
public redef static func g<T>(): Unit where T <: B {} // OK: same constraint
}
接口
接口用来定义一个抽象类型,它不包含数据,但可以定义类型的行为。一个类型如果声明实现某接口,并且实现了该接口中所有的成员,就被称为实现了该接口。
接口的成员可以包含:
- 成员函数
- 操作符重载函数
- 成员属性
这些成员都是抽象的,要求实现类型必须拥有对应的成员实现。
接口定义
一个简单的接口定义如下:
interface I { // 'open' modifier is optional.
func f(): Unit
}
接口使用关键字 interface 声明,其后是接口的标识符 I 和接口的成员。接口成员可被 open 修饰符修饰,并且 open 修饰符是可选的。
当接口 I 声明了一个成员函数 f 之后,要为一个类型实现 I 时,就必须在该类型中实现一个对应的 f 函数。
因为 interface 默认具有 open 语义,所以 interface 定义时的 open 修饰符是可选的。
如下面的代码所示,定义了一个 class Foo,使用 Foo <: I 的形式声明了 Foo 实现 I 接口。
在 Foo 中必须包含 I 声明的所有成员的实现,即需要定义一个相同类型的 f,否则会由于没有实现接口而编译报错。
class Foo <: I {
public func f(): Unit {
println("Foo")
}
}
main() {
let a = Foo()
let b: I = a
b.f() // "Foo"
}
当某个类型实现了某个接口之后,该类型就会成为该接口的子类型。
对于上面的例子,Foo 是 I 的子类型,因此任何一个 Foo 类型的实例,都可以当作 I 类型的实例使用。
在 main 中将一个 Foo 类型的变量 a,赋值给一个 I 类型的变量 b。然后再调用 b 中的函数 f,就会打印出 Foo 实现的 f 版本。程序的输出结果为:
Foo
interface 也可以使用 sealed 修饰符表示只能在 interface 定义所在的包内继承、实现或扩展该 interface。sealed 已经蕴含了 public/open 的语义,因此定义 sealed interface 时若提供 public/open 修饰符,编译器将会告警。继承 sealed 接口的子接口或实现 sealed 接口的抽象类仍可被 sealed 修饰或不使用 sealed 修饰。若 sealed 接口的子接口被 public 修饰,且不被 sealed 修饰,则其子接口可在包外被继承、实现或扩展。继承、实现 sealed 接口的类型可以不被 public 修饰。
package A
public interface I1 {}
sealed interface I2 {} // OK
public sealed interface I3 {} // Warning, redundant modifier, 'sealed' implies 'public'
sealed open interface I4 {} // Warning, redundant modifier, 'sealed' implies 'open'
class C1 <: I1 {}
public open class C2 <: I1 {}
sealed abstract class C3 <: I2 {}
extend Int64 <: I2 {}
package B
import A.*
class S1 <: I1 {} // OK
class S2 <: I2 {} // Error, I2 is sealed interface, cannot be inherited here.
通过接口的这种约束能力,可以对一系列的类型约定共同的功能,达到对功能进行抽象的目的。
例如下面的代码,可以定义一个 Flyable 接口,并且让其他具有 Flyable 属性的类实现它。
interface Flyable {
func fly(): Unit
}
class Bird <: Flyable {
public func fly(): Unit {
println("Bird flying")
}
}
class Bat <: Flyable {
public func fly(): Unit {
println("Bat flying")
}
}
class Airplane <: Flyable {
public func fly(): Unit {
println("Airplane flying")
}
}
func fly(item: Flyable): Unit {
item.fly()
}
main() {
let bird = Bird()
let bat = Bat()
let airplane = Airplane()
fly(bird)
fly(bat)
fly(airplane)
}
编译并执行上面的代码,会看到如下输出:
Bird flying
Bat flying
Airplane flying
接口的成员可以是实例的或者静态的,以上的例子已经展示过实例成员函数的作用,接下来来看看静态成员函数的作用。
静态成员函数和实例成员函数类似,都要求实现类型提供实现。
例如下面的例子,定义了一个 NamedType 接口,这个接口含有一个静态成员函数 typename 用来获得每个类型的字符串名称。
这样其他类型在实现 NamedType 接口时就必须实现 typename 函数,之后就可以安全地在 NamedType 的子类型上获得类型的名称。
interface NamedType {
static func typename(): String
}
class A <: NamedType {
public static func typename(): String {
"A"
}
}
class B <: NamedType {
public static func typename(): String {
"B"
}
}
main() {
println("the type is ${ A.typename() }")
println("the type is ${ B.typename() }")
}
程序输出结果为:
the type is A
the type is B
接口中的静态成员函数(或属性)可以没有默认实现,也可以拥有默认实现。
当其没有默认实现时,将无法通过接口类型名对其进行访问。例如下面的代码,直接访问 NamedType 的 typename 函数会发生编译报错,因为 NamedType 不具有 typename 函数的实现。
interface NamedType {
static func typename(): String
}
main() {
NamedType.typename() // Error
}
接口中的静态成员函数(或属性)也可以拥有默认实现,当另一个类型继承拥有默认静态函数(或属性)实现的接口时,该类型可以不再实现这个静态成员函数(或属性),该函数(或属性)可以通过接口名和该类型名直接访问。如下用例,NamedType 的成员函数 typename 拥有默认实现,且在 A 中都可以不用再重新实现它,同时,也可以通过接口名和该类型名对其进行直接访问。
interface NamedType {
static func typename(): String {
"interface NamedType"
}
}
class A <: NamedType {}
main() {
println(NamedType.typename())
println(A.typename())
0
}
程序输出结果为:
interface NamedType
interface NamedType
通常会通过泛型约束,在泛型函数中使用这类静态成员。
例如下面的 printTypeName 函数,当约束泛型变元 T 是 NamedType 的子类型时,需要保证 T 的实例化类型中所有的静态成员函数(或属性)都必须拥有实现,以保证可以使用 T.typename 的方式访问泛型变元的实现,达到了对静态成员抽象的目的。详见泛型。
interface NamedType {
static func typename(): String
}
interface I <: NamedType {
static func typename(): String {
f()
}
static func f(): String
}
class A <: NamedType {
public static func typename(): String {
"A"
}
}
class B <: NamedType {
public static func typename(): String {
"B"
}
}
func printTypeName<T>() where T <: NamedType {
println("the type is ${ T.typename() }")
}
main() {
printTypeName<A>() // Ok
printTypeName<B>() // Ok
printTypeName<I>() // Error, 'I' must implement all static function. Otherwise, an unimplemented 'f' is called, causing problems.
}
接口中可以定义泛型实例成员函数或泛型静态成员函数,与非泛型函数一样具有 open 语义。
import std.collection.*
interface M {
func foo<T>(a: T): T
static func toString<T>(b: ArrayList<T>): String where T <: ToString
}
class C <: M {
public func foo<S>(a: S): S { // implements M::foo, names of generic parameters do not matter
a
}
public static func toString<T>(b: ArrayList<T>) where T <: ToString {
var res = ""
for (s in b) {
res += s.toString()
}
res
}
}
需要注意的是,接口的成员默认就被 public 修饰,不可以声明额外的访问控制修饰符,同时也要求实现类型必须使用 public 实现。
interface I {
func f(): Unit
}
open class C <: I {
protected func f() {} // Compiler Error, f needs to be public semantics
}
接口继承与接口实现
当想为一个类型实现多个接口,可以在声明处使用 & 分隔多个接口,实现的接口之间没有顺序要求。
例如下面的例子,可以让 MyInt 同时实现 Addable 和 Subtractable 两个接口。
interface Addable {
func add(other: Int64): Int64
}
interface Subtractable {
func sub(other: Int64): Int64
}
class MyInt <: Addable & Subtractable {
var value = 0
public func add(other: Int64): Int64 {
value + other
}
public func sub(other: Int64): Int64 {
value - other
}
}
接口可以继承一个或多个接口,但不能继承类。与此同时,接口继承的时候可以添加新的接口成员。
例如下面的例子,Calculable 接口继承了 Addable 和 Subtractable 两个接口,并且增加了乘除两种运算符重载。
interface Addable {
func add(other: Int64): Int64
}
interface Subtractable {
func sub(other: Int64): Int64
}
interface Calculable <: Addable & Subtractable {
func mul(other: Int64): Int64
func div(other: Int64): Int64
}
这样实现类型实现 Calculable 接口时就必须同时实现加减乘除四种运算符重载,不能缺少任何一个成员。
class MyInt <: Calculable {
var value = 0
public func add(other: Int64): Int64 {
value + other
}
public func sub(other: Int64): Int64 {
value - other
}
public func mul(other: Int64): Int64 {
value * other
}
public func div(other: Int64): Int64 {
value / other
}
}
MyInt 实现 Calculable 的同时,也同时实现了 Calculable 继承的所有接口,因此 MyInt 也实现了 Addable 和 Subtractable,即同时是它们的子类型。
main() {
let myInt = MyInt()
let add: Addable = myInt
let sub: Subtractable = myInt
let calc: Calculable = myInt
}
对于 interface 的继承,子接口如果继承了父接口中有默认实现的函数或属性,则在子接口中不允许仅写此函数或属性的声明(即没有默认实现),而是必须要给出新的默认实现,并且函数定义前的 override 修饰符(或 redef 修饰符)是可选的;子接口如果继承了父接口中没有默认实现的函数或属性,则在子接口中允许仅写此函数或属性的声明(当然也允许定义默认实现),并且函数声明或定义前的 override 修饰符(或 redef 修饰符)是可选的。
interface I1 {
func f(a: Int64) {
a
}
static func g(a: Int64) {
a
}
func f1(a: Int64): Unit
static func g1(a: Int64): Unit
}
interface I2 <: I1 {
/*'override' is optional*/ func f(a: Int64) {
a + 1
}
override func f(a: Int32) {} // Error, override function 'f' does not have an overridden function from its supertypes
static /*'redef' is optional*/ func g(a: Int64) {
a + 1
}
/*'override' is optional*/ func f1(a: Int64): Unit {}
static /*'redef' is optional*/ func g1(a: Int64): Unit {}
}
接口实现的要求
仓颉除 Tuple、VArray 和函数外的其他类型都可以实现接口。
一个类型实现接口有三种途径:
- 在定义类型时就声明实现接口,在以上的内容中已经见过相关例子。
- 通过扩展实现接口,这种方式详见扩展。
- 由语言内置实现,具体详见《仓颉编程语言库 API》相关文档。
实现类型声明实现接口时,需要实现接口中要求的所有成员,为此需要满足下面一些规则。
- 对于成员函数和操作符重载函数,要求实现类型提供的函数实现与接口对应的函数名称相同、参数列表相同、返回类型相同。
- 对于成员属性,要求是否被
mut修饰保持一致,并且属性的类型相同。
所以大部分情况都如同上面的例子,需要让实现类型中包含与接口要求的一样的成员的实现。
但有个地方是个例外,如果接口中的成员函数或操作符重载函数的返回值类型是 class 类型,那么允许实现函数的返回类型是其子类型。
例如下面这个例子,I 中的 f 返回类型是一个 class 类型 Base,因此 C 中实现的 f 返回类型可以是 Base 的子类型 Sub。
open class Base {}
class Sub <: Base {}
interface I {
func f(): Base
}
class C <: I {
public func f(): Sub {
Sub()
}
}
除此以外,接口的成员还可以提供默认实现。例如下面的代码中,SayHi 中的 say 拥有默认实现,因此 A 实现 SayHi 时可以继承 say 的实现,而 B 也可以选择提供自己的 say 实现。
interface SayHi {
func say() {
"hi"
}
}
class A <: SayHi {}
class B <: SayHi {
public func say() {
"hi, B"
}
}
特别地,如果一个类型在实现多个接口时,多个接口中包含同一个成员的默认实现,这时会发生多重继承的冲突,语言无法选择最适合的实现,因此这时接口中的默认实现也会失效,需要实现类型提供自己的实现。
例如下面的例子,SayHi 和 SayHello 中都包含了 say 的实现,Foo 在实现这两个接口时就必须提供自己的实现,否则会出现编译错误。
interface SayHi {
func say() {
"hi"
}
}
interface SayHello {
func say() {
"hello"
}
}
class Foo <: SayHi & SayHello {
public func say() {
"Foo"
}
}
struct、enum 和 class 在实现接口时,函数或属性定义前的 override 修饰符(或 redef 修饰符)是可选的,无论接口中的函数或属性是否存在默认实现。
interface I {
func foo(): Int64 {
return 0
}
}
enum E <: I{
elem
public override func foo(): Int64 {
return 1
}
}
struct S <: I {
public override func foo(): Int64 {
return 1
}
}
Any 类型
Any 类型是一个内置的接口,它的定义如下:
interface Any {}
仓颉中所有接口都默认继承它,所有非接口类型都默认实现它,因此所有类型都可以作为 Any 类型的子类型使用。
如下面的代码,可以将一系列不同类型的变量赋值给 Any 类型的变量。
main() {
var any: Any = 1
any = 2.0
any = "hello, world!"
}
属性
属性(Properties)提供了一个 getter 和一个可选的 setter 来间接获取和设置值。
使用属性的时候与普通变量无异,只需要对数据操作,对内部的实现无感知,可以更便利地实现访问控制、数据监控、跟踪调试、数据绑定等机制。
属性在使用时可以作为表达式或被赋值。此处以类和接口为例进行说明,但属性不仅限于类和接口。
以下是一个简单的例子,b 是一个典型的属性,封装了外部对 a 的访问:
class Foo {
private var a = 0
public mut prop b: Int64 {
get() {
println("get")
a
}
set(value) {
println("set")
a = value
}
}
}
main() {
var x = Foo()
let y = x.b + 1 // get
x.b = y // set
}
此处 Foo 提供了一个名为 b 的属性,针对 getter/setter 这两个功能,仓颉提供了 get 和 set 两种语法来定义。当一个类型为 Foo 的变量 x 在访问 b 时,会调用 b 的 get 操作返回类型为 Int64 的值,因此可以用来与 1 相加;而当 x 在对 b 进行赋值时,会调用 b 的 set 操作,将 y 的值传给 set 的 value,最终将 value 的值赋值给 a。
通过属性 b,外部对 Foo 的成员变量 a 完全不感知,但却可以通过 b 做到同样地访问和修改操作,实现了有效的封装性。所以程序的输出如下:
get
set
属性定义
属性可以在 interface、class、struct、enum、extend 中定义。
一个典型的属性语法结构如下:
class Foo {
public prop a: Int64 {
get() { 0 }
}
public mut prop b: Int64 {
get() { 0 }
set(v) {}
}
}
其中使用 prop 声明的 a 和 b 都是属性,a 和 b 的类型都是 Int64。a 是无 mut 修饰符的属性,这类属性有且仅有定义 getter(对应取值)实现。b 是使用 mut 修饰的属性,这类属性必须分别定义 getter(对应取值)和 setter(对应赋值)的实现。
注意:
对于数值、元组、函数、
Bool、Unit、Nothing、String、Range和enum类型,在它们的扩展和声明中不能声明 mut 修饰的属性,也不能实现有 mut 属性的接口。
属性的 getter 和 setter 分别对应两个不同的函数。
- getter 函数类型是
() -> T,T 是该属性的类型,当使用该属性作为表达式时会执行 getter 函数。 - setter 函数类型是
(T) -> Unit,T 是该属性的类型,形参名需要显式指定,当对该属性赋值时会执行 setter 函数。
getter 和 setter 的实现中可以和函数体一样包含声明和表达式,与函数体的规则一样,详见函数体章节。
setter 中的参数对应的是赋值时传入的值。
class Foo {
private var j = 0
public mut prop i: Int64 {
get() {
j
}
set(v) {
j = v
}
}
}
需要注意的是,在属性的 getter 和 setter 中访问属性自身属于递归调用,与函数调用一样可能会出现死循环的情况。
修饰符
可以在 prop 前面声明需要的修饰符。
class Foo {
public prop a: Int64 {
get() {
0
}
}
private prop b: Int64 {
get() {
0
}
}
}
和成员函数一样,成员属性也支持 open、override、redef 修饰,所以也可以在子类型中覆盖/重定义父类型属性的实现。
子类型覆盖父类型的属性时,如果父类型属性带有 mut 修饰符,则子类型属性也需要带有 mut 修饰符,同时也必须保持一样的类型。
如下代码所示,A 中定义了 x 和 y 两个属性,B 中可以分别对 x 和 y 进行 override/redef:
open class A {
private var valueX = 0
private static var valueY = 0
public open prop x: Int64 {
get() { valueX }
}
public static mut prop y: Int64 {
get() { valueY }
set(v) {
valueY = v
}
}
}
class B <: A {
private var valueX2 = 0
private static var valueY2 = 0
public override prop x: Int64 {
get() { valueX2 }
}
public redef static mut prop y: Int64 {
get() { valueY2 }
set(v) {
valueY2 = v
}
}
}
抽象属性
类似于抽象函数,在 interface 和抽象类中也可以声明抽象属性,这些抽象属性没有实现。
interface I {
prop a: Int64
}
abstract class C {
public prop a: Int64
}
当实现类型实现 interface 或者非抽象子类继承抽象类时,必须要实现这些抽象属性。
与覆盖的规则一样,实现类型或子类在实现这些属性时,如果父类型属性带有 mut 修饰符,则子类型属性也需要带有 mut 修饰符,同时也必须保持一样的类型。
interface I {
prop a: Int64
mut prop b: Int64
}
class C <: I {
private var value = 0
public prop a: Int64 {
get() { value }
}
public mut prop b: Int64 {
get() { value }
set(v) {
value = v
}
}
}
通过抽象属性,可以让接口和抽象类对一些数据操作能以更加易用的方式进行约定,相比函数的方式要更加直观。
如下代码所示,如果要对一个 size 值的获取和设置进行约定,使用属性的方式 (I1) 相比使用函数的方式 (I2) 代码更少,也更加符合对数据操作的意图。
interface I1 {
mut prop size: Int64
}
interface I2 {
func getSize(): Int64
func setSize(value: Int64): Unit
}
class C <: I1 & I2 {
private var mySize = 0
public mut prop size: Int64 {
get() {
mySize
}
set(value) {
mySize = value
}
}
public func getSize() {
mySize
}
public func setSize(value: Int64) {
mySize = value
}
}
main() {
let a: I1 = C()
a.size = 5
println(a.size)
let b: I2 = C()
b.setSize(5)
println(b.getSize())
}
5
5
属性使用
属性分为实例成员属性和静态成员属性。成员属性的使用和成员变量的使用方式一样,详见成员变量章节。
class A {
public prop x: Int64 {
get() {
123
}
}
public static prop y: Int64 {
get() {
321
}
}
}
main() {
var a = A()
println(a.x) // 123
println(A.y) // 321
}
结果为:
123
321
无 mut 修饰符的属性类似 let 声明的变量,不能被赋值。
class A {
private let value = 0
public prop i: Int64 {
get() {
value
}
}
}
main() {
var x = A()
println(x.i) // OK
x.i = 1 // Error
}
带有 mut 修饰符的属性类似 var 声明的变量,可以取值也可以被赋值。
class A {
private var value: Int64 = 0
public mut prop i: Int64 {
get() {
value
}
set(v) {
value = v
}
}
}
main() {
var x = A()
println(x.i) // OK
x.i = 1 // OK
}
0
子类型关系
与其他面向对象语言一样,仓颉语言提供子类型关系和子类型多态。举例说明(不限于下述用例):
- 假设函数的形参是类型
T,则函数调用时传入的参数的实际类型既可以是T也可以是T的子类型(严格地说,T的子类型已经包括T自身,下同)。 - 假设赋值表达式
=左侧的变量的类型是T,则=右侧的表达式的实际类型既可以是T也可以是T的子类型。 - 假设函数定义中用户标注的返回类型是
T,则函数体的类型(以及函数体内所有return表达式的类型)既可以是T也可以是T的子类型。
下文将说明两个类型为子类型关系的几种情况。
继承 class 带来的子类型关系
继承 class 后,子类即为父类的子类型。如下代码中, Sub 即为 Super 的子类型。
open class Super { }
class Sub <: Super { }
实现接口带来的子类型关系
实现接口(含扩展实现)后,实现接口的类型即为接口的子类型。如下代码中,I3 是 I1 和 I2 的子类型, C 是 I1 的子类型, Int64 是 I2 的子类型:
interface I1 { }
interface I2 { }
interface I3 <: I1 & I2 { }
class C <: I1 { }
extend Int64 <: I2 { }
元组类型的子类型关系
仓颉语言中的元组类型也有子类型关系。直观的,如果一个元组 t1 的每个元素的类型都是另一个元组 t2 的对应位置元素类型的子类型,那么元组 t1 的类型也是元组 t2 的类型的子类型。例如下面的代码中,由于 C2 <: C1 和 C4 <: C3,因此也有 (C2, C4) <: (C1, C3) 以及 (C4, C2) <: (C3, C1)。
open class C1 { }
class C2 <: C1 { }
open class C3 { }
class C4 <: C3 { }
let t1: (C1, C3) = (C2(), C4()) // OK
let t2: (C3, C1) = (C4(), C2()) // OK
函数类型的子类型关系
仓颉语言中,函数是一等公民,而函数类型亦有子类型关系:给定两个函数类型 (U1) -> S2 和 (U2) -> S1,如果存在 (U1) -> S2 是 (U2) -> S1的子类型,当且仅当 U2 是 U1 的子类型,且 S2 是 S1 的子类型(注意顺序)。例如下面的代码定义了两个函数 f : (U1) -> S2 和 g : (U2) -> S1,且 f 的类型是 g 的类型的子类型。由于 f 的类型是 g 的子类型,所以代码中使用到 g 的地方都可以换为 f。
open class U1 { }
class U2 <: U1 { }
open class S1 { }
class S2 <: S1 { }
func f(a: U1): S2 { S2() }
func g(a: U2): S1 { S1() }
func call1() {
g(U2()) // Ok.
f(U2()) // Ok.
}
func h(lam: (U2) -> S1): S1 {
lam(U2())
}
func call2() {
h(g) // Ok.
h(f) // Ok.
}
对于上面的规则,S2 <: S1 部分很好理解:函数调用产生的结果数据会被后续程序使用,函数 g 可以产生 S1 类型的结果数据,函数 f 可以产生 S2 类型的结果,而 g 产生的结果数据应当能被 f 产生的结果数据替代,因此要求 S2 <: S1。
对于 U2 <: U1 的部分,可以这样理解:在函数调用产生结果前,它本身应当能够被调用,函数调用的实参类型固定不变,同时形参类型要求更宽松时,依然可以被调用,而形参类型要求更严格时可能无法被调用——例如给定上述代码中的定义 g(U2()) 可以被换为 f(U2()),正是因为实参类型 U2 的要求更严格于形参类型 U1。
永远成立的子类型关系
仓颉语言中,有些预设的子类型关系是永远成立的:
- 一个类型
T永远是自身的子类型,即T <: T。 Nothing类型永远是其他任意类型T的子类型,即Nothing <: T。- 任意类型
T都是Any类型的子类型,即T <: Any。 - 任意
class定义的类型都是Object的子类型,即如果有class C {},则C <: Object。
传递性带来的子类型关系
子类型关系具有传递性。如下代码中,虽然只描述了 I2 <: I1、C <: I2 以及 Bool <: I2,但根据子类型的传递性,也隐式存在 C <: I1 以及 Bool <: I1 这两个子类型关系。
interface I1 { }
interface I2 <: I1 { }
class C <: I2 { }
extend Bool <: I2 { }
泛型类型的子类型关系
泛型类型间也有子类型关系,详见泛型类型的子类型关系。
类型转换
仓颉不支持不同类型之间的隐式转换(子类型天然是父类型,所以子类型到父类型的转换不是隐式类型转换),类型转换必须显式地进行。下面将依次介绍数值类型之间的转换,Rune 到 UInt32 和整数类型到 Rune 的转换,以及 is 和 as 操作符。
数值类型之间的转换
对于数值类型(包括:Int8,Int16,Int32,Int64,IntNative,UInt8,UInt16,UInt32,UInt64,UIntNative,Float16,Float32,Float64),仓颉支持使用 T(e) 的方式得到一个值等于 e,类型为 T 的值。其中,表达式 e 的类型和 T 可以是上述任意数值类型。
下面的例子展示了数值类型之间的类型转换:
main() {
let a: Int8 = 10
let b: Int16 = 20
let r1 = Int16(a)
println("The type of r1 is 'Int16', and r1 = ${r1}")
let r2 = Int8(b)
println("The type of r2 is 'Int8', and r2 = ${r2}")
let c: Float32 = 1.0
let d: Float64 = 1.123456789
let r3 = Float64(c)
println("The type of r3 is 'Float64', and r3 = ${r3}")
let r4 = Float32(d)
println("The type of r4 is 'Float32', and r4 = ${r4}")
let e: Int64 = 1024
let f: Float64 = 1024.1024
let r5 = Float64(e)
println("The type of r5 is 'Float64', and r5 = ${r5}")
let r6 = Int64(f)
println("The type of r6 is 'Int64', and r6 = ${r6}")
}
上述代码的执行结果为:
The type of r1 is 'Int16', and r1 = 10
The type of r2 is 'Int8', and r2 = 20
The type of r3 is 'Float64', and r3 = 1.000000
The type of r4 is 'Float32', and r4 = 1.123457
The type of r5 is 'Float64', and r5 = 1024.000000
The type of r6 is 'Int64', and r6 = 1024
注意:
类型转换时可能发生溢出,若溢出可提前在编译器检测出来,则编译器会直接给出报错,否则根据默认的溢出策略将抛出异常。
Rune 到 UInt32 和整数类型到 Rune 的转换
Rune 到 UInt32 的转换使用 UInt32(e) 的方式,其中 e 是一个 Rune 类型的表达式,UInt32(e) 的结果是 e 的 Unicode scalar value 对应的 UInt32 类型的整数值。
整数类型到 Rune 的转换使用 Rune(num) 的方式,其中 num 的类型可以是任意的整数类型,且仅当 num 的值落在 [0x0000, 0xD7FF] 或 [0xE000, 0x10FFFF] (即 Unicode scalar value)中时,返回对应的 Unicode scalar value 表示的字符,否则,编译报错(编译时可确定 num 的值)或运行时抛异常。
下面的例子展示了 Rune 和 UInt32 之间的类型转换:
main() {
let x: Rune = 'a'
let y: UInt32 = 65
let r1 = UInt32(x)
let r2 = Rune(y)
println("The type of r1 is 'UInt32', and r1 = ${r1}")
println("The type of r2 is 'Rune', and r2 = ${r2}")
}
上述代码的执行结果为:
The type of r1 is 'UInt32', and r1 = 97
The type of r2 is 'Rune', and r2 = A
is 和 as 操作符
仓颉支持使用 is 操作符来判断某个表达式的类型是否是指定的类型(或其子类型)。具体而言,对于表达式 e is T(e 可以是任意表达式,T 可以是任何类型),当 e 的运行时类型是 T 的子类型时,e is T 的值为 true,否则 e is T 的值为 false。
下面的例子展示了 is 操作符的使用:
open class Base {
var name: String = "Alice"
}
class Derived <: Base {
var age: UInt8 = 18
}
main() {
let a = 1 is Int64
println("Is the type of 1 'Int64'? ${a}")
let b = 1 is String
println("Is the type of 1 'String'? ${b}")
let b1: Base = Base()
let b2: Base = Derived()
var x = b1 is Base
println("Is the type of b1 'Base'? ${x}")
x = b1 is Derived
println("Is the type of b1 'Derived'? ${x}")
x = b2 is Base
println("Is the type of b2 'Base'? ${x}")
x = b2 is Derived
println("Is the type of b2 'Derived'? ${x}")
}
上述代码的执行结果为:
Is the type of 1 'Int64'? true
Is the type of 1 'String'? false
Is the type of b1 'Base'? true
Is the type of b1 'Derived'? false
Is the type of b2 'Base'? true
Is the type of b2 'Derived'? true
as 操作符可以用于将某个表达式的类型转换为指定的类型。因为类型转换有可能会失败,所以 as 操作返回的是一个 Option 类型。具体而言,对于表达式 e as T(e 可以是任意表达式,T 可以是任何类型),当 e 的运行时类型是 T 的子类型时,e as T 的值为 Option<T>.Some(e),否则 e as T 的值为 Option<T>.None。
下面的例子展示了 as 操作符的使用(注释中标明了 as 操作的结果):
open class Base {
var name: String = "Alice"
}
class Derived <: Base {
var age: UInt8 = 18
}
let a = 1 as Int64 // a = Option<Int64>.Some(1)
let b = 1 as String // b = Option<String>.None
let b1: Base = Base()
let b2: Base = Derived()
let d: Derived = Derived()
let r1 = b1 as Base // r1 = Option<Base>.Some(b1)
let r2 = b1 as Derived // r2 = Option<Derived>.None
let r3 = b2 as Base // r3 = Option<Base>.Some(b2)
let r4 = b2 as Derived // r4 = Option<Derived>.Some(b2)
let r5 = d as Base // r5 = Option<Base>.Some(d)
let r6 = d as Derived // r6 = Option<Derived>.Some(d)
泛型概述
在仓颉编程语言中,泛型指的是参数化类型,参数化类型是一个在声明时未知并且需要在使用时指定的类型。类型声明与函数声明可以是泛型的。最为常见的例子就是 Array<T>、Set<T> 等容器类型。
在仓颉中,function、class、interface、struct 与 enum 的声明都可以声明类型形参,也就是说它们都可以是泛型的。
为了方便讨论,定义如下几个常用的术语:
- 类型形参:一个类型或者函数声明可能有一个或者多个需要在使用处被指定的类型,这些类型就被称为类型形参。在声明形参时,需要给定一个标识符,以便在声明体中引用。
- 类型变元:在声明类型形参后,当通过标识符来引用这些类型时,这些标识符被称为类型变元。
- 类型实参:当在使用泛型声明的类型或函数时指定了泛型参数,这些参数被称为类型实参。
- 类型构造器:一个需要零个、一个或者多个类型作为实参的类型称为类型构造器。
类型形参在声明时一般在类型名称的声明或者函数名称的声明后,使用尖括号 <...> 括起来。例如一个泛型的列表可声明为:
class List<T> {
var elem: Option<T> = None
var tail: Option<List<T>> = None
}
func sumInt(a: List<Int64>) { }
其中 List<T> 中的 T 被称为类型形参。对于 elem: Option<T> 中对 T 的引用称为类型变元,同理 tail: Option<List<T>> 中的 T 也称为类型变元。函数 sumInt 的参数中 List<Int64> 的 Int64 被称为 List 的类型实参。 List 就是类型构造器,List<Int64> 通过 Int64 类型实参构造出了一个类型 Int64 的列表类型。
泛型函数
如果一个函数声明了一个或多个类型形参,则将其称为泛型函数。语法上,类型形参紧跟在函数名后,并用 <> 括起,如果有多个类型形参,则用 , 分离。
全局泛型函数
在声明全局泛型函数时,只需要在函数名后使用尖括号声明类型形参,然后就可以在函数形参、返回类型及函数体中对这一类型形参进行引用。例如 id 函数定义为:
func id<T>(a: T): T {
return a
}
其中 (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
}
这里,复合两个 (Int64) -> Int64 的函数,将 9 先乘以 2,再加 10,结果会是 28。
28
局部泛型函数
局部函数也可以是泛型函数。例如泛型函数 id 可以嵌套定义在其他函数中:
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
}
这里由于 id 的单位元性质,函数 id<Int64> ~> double 和 double ~> id<Int64> 是等价的,结果是 true。
true
泛型成员函数
class、struct、enum 与 interface 的成员函数可以是泛型的。例如:
class A {
func foo<T>(a: T): Unit where T <: ToString {
println("${a}")
}
}
struct B {
func bar<T>(a: T): Unit where T <: ToString {
println("${a}")
}
}
enum C {
| X | Y
func coo<T>(a: T): Unit where T <: ToString {
println("${a}")
}
}
interface I {
func doo<T>(a: T): Unit where T <: ToString
}
class D <: I {
public func doo<T>(a: T): Unit where T <: ToString {
println("${a}")
}
}
abstract class E {
public func eoo1<T>(a: T): Unit where T <: ToString
public open func eoo2<T>(a: T): Unit where T <: ToString
}
class F <: E {
public func eoo1<T>(a: T): Unit where T <: ToString {
println("${a}")
}
public func eoo2<T>(a: T): Unit where T <: ToString {
println("${a}")
}
}
main() {
var a = A()
var b = B()
var c = C.X
var d = D()
var f = F()
a.foo<Int64>(10)
b.bar<String>("abc")
c.coo<Bool>(false)
d.doo<String>("doo")
f.eoo1<String>("eoo1")
f.eoo2<String>("eoo2")
return 0
}
程序输出的结果为:
10
abc
false
doo
eoo1
eoo2
在为类型使用 extend 声明进行扩展时,扩展中的函数也可以是泛型的,例如可以为 Int64 类型增加一个泛型成员函数:
extend Int64 {
func printIntAndArg<T>(a: T) where T <: ToString {
println(this)
println("${a}")
}
}
main() {
var a: Int64 = 12
a.printIntAndArg<String>("twelve")
}
程序输出的结果将为:
12
twelve
静态泛型函数
interface、class、struct、enum 与 extend 中可以定义静态泛型函数,例如下例 ToPair class 中从 ArrayList 中返回一个元组:
import std.collection.*
class ToPair {
public static func fromArray<T>(l: ArrayList<T>): (T, T) {
return (l[0], l[1])
}
}
main() {
var res: ArrayList<Int64> = ArrayList([1,2,3,4])
var a: (Int64, Int64) = ToPair.fromArray<Int64>(res)
return 0
}
泛型接口
泛型可以用来定义泛型接口,以标准库中定义的 Iterable 为例,它的成员函数 iterator 需要返回一个 Iterator 类型,这一类型是一个容器的遍历器。 Iterator 是一个泛型接口,Iterator 内部有一个从容器类型中返回下一个元素的 next 成员函数,next 成员函数返回的类型是一个需要在使用时指定的类型,所以 Iterator 需要声明泛型参数。
public interface Iterable<E> {
func iterator(): Iterator<E>
}
public interface Iterator<E> <: Iterable<E> {
func next(): Option<E>
}
public interface Collection<T> <: Iterable<T> {
prop size: Int64
func isEmpty(): Bool
}
泛型类
泛型接口中介绍了泛型接口的定义和使用,本节介绍泛型类的定义和使用。如 Map 的键值对就是使用泛型类来定义的。
Map 类型中的键值对 Node 类型就可以使用泛型类来定义:
public open class Node<K, V> where K <: Hashable & Equatable<K> {
public var key: Option<K> = Option<K>.None
public var value: Option<V> = Option<V>.None
public init() {}
public init(key: K, value: V) {
this.key = Option<K>.Some(key)
this.value = Option<V>.Some(value)
}
}
由于键与值的类型有可能不相同,且可以为任意满足条件的类型,所以 Node 需要两个类型形参 K 与 V ,K <: Hashable, K <: Equatable<K> 是对于键类型的约束,意为 K 要实现 Hashable 与 Equatable<K> 接口,也就是 K 需要满足的条件。对于泛型约束,详见泛型约束章节。
由于泛型类的静态成员变量的内存是共享的,因此,静态成员变量或属性的类型声明和表达式中不能引用类型参数或包含未实例化泛型类型表达式。另外,静态变量或属性初始化表达式中不能调用泛型类的静态成员函数或属性。
class A<T> {}
class B<T> {
static func foo() {1}
static var err1: A<T> = A<T>() // Error, static member cannot depend on generic parameter 'Generics-T'
static prop err2: A<T> { // Error, static member cannot depend on generic parameter 'Generics-T'
get() {
A<T>() // Error, static member cannot depend on generic parameter 'Generics-T'
}
}
static var vfoo = foo() // Error, it's equal to 'static var vfoo = B<T>.foo()', implicit reference to generic 'T'.
static var ok: Int64 = 1
}
main() {
B<Int32>.ok = 2
println(B<Int64>.ok) // 2
}
泛型结构体
struct 类型的泛型与 class 是类似的,下面可以使用 struct 定义一个类似于二元元组的类型:
struct Pair<T, U> {
let x: T
let y: U
public init(a: T, b: U) {
x = a
y = b
}
public func first(): T {
return x
}
public func second(): U {
return y
}
}
main() {
var a: Pair<String, Int64> = Pair<String, Int64>("hello", 0)
println(a.first())
println(a.second())
}
程序输出的结果为:
hello
0
在 Pair 中提供了 first 与 second 两个函数来取得元组的第一个与第二个元素。
泛型枚举
在仓颉编程语言的泛型 enum 类型设计中,Option 类型是一个典型的示例,关于 Option 详细描述请参见 Option 类型章节。 Option 类型用于表示在某一类型上的值可能是个空的值。这样,Option 就可以用来表示在某种类型上计算的失败。这里是何种类型上的失败是不确定的,所以很明显,Option 是一个泛型类型,需要声明类型形参。
package std.core // `Option` is defined in std.core.
public enum Option<T> {
Some(T)
| None
public func getOrThrow(): T {
match (this) {
case Some(v) => v
case None => throw NoneValueException()
}
}
...
}
可以看到,Option<T> 分成两种情况,一种是 Some(T),用来表示一个有值的返回结果,另一种是 None 用来表示一个空的结果。其中的 getOrThrow 函数会是将 Some(T) 内部的值返回出来的函数,返回的结果就是 T 类型,而如果参数是 None,那么直接抛出异常。
例如:如果想定义一个安全的除法,因为在除法上的计算是可能失败的。如果除数为 0,那么返回 None ,否则返回一个用 Some 包装过的结果:
func safeDiv(a: Int64, b: Int64): Option<Int64> {
var res: Option<Int64> = match (b) {
case 0 => None
case _ => Some(a/b)
}
return res
}
这样,在除数为 0 时,程序运行的过程中不会因除以 0 而抛出算术运算异常。
泛型类型的子类型关系
实例化后的泛型类型间也有子类型关系。例如:
interface I<X, Y> { }
class C<Z> <: I<Z, Z> { }
根据 class C<Z> <: I<Z, Z> { },便知 C<Bool> <: I<Bool, Bool> 以及 C<D> <: I<D, D> 等。可以解读为“于所有的(不含类型变元的) Z 类型,都有 C<Z> <: I<Z, Z> 成立”。
但是对于下列代码:
open class C { }
class D <: C { }
interface I<X> { }
I<D> <: I<C> 是不成立的(即使 D <: C 成立),这是因为在仓颉语言中,用户定义的类型构造器在其类型参数处是不型变的。
型变的具体定义为:如果 A 和 B 是(实例化后的)类型,T 是类型构造器,设有一个类型参数 X(例如 interface T<X>),那么
- 如果
T(A) <: T(B)当且仅当A = B,则T是不型变的。 - 如果
T(A) <: T(B)当且仅当A <: B,则T在X处是协变的。 - 如果
T(A) <: T(B)当且仅当B <: A,则T在X处是逆变的。
因为现阶段的仓颉中,所有用户自定义的泛型类型在其所有的类型变元处都是不变的,所以给定 interface I<X> 和类型 A、B,只有 A = B,才能得到 I<A> <: I<B>;反过来,如果知道了 I<A> <: I<B>,也可推出 A = B(内建类型除外:内建的元组类型对其每个元素类型来说,都是协变的;内建的函数类型在其入参类型处是逆变的,在其返回类型处是协变的。)
注意:
class以外的类型实现接口,该类型和该接口之间的子类型关系不能作为协变和逆变的依据。
不型变限制了一些语言的表达能力,但也避免了一些安全问题,例如“协变数组运行时抛异常”的问题。
类型别名
当某个类型的名字比较复杂或者在特定场景中不够直观时,可以选择使用类型别名的方式为此类型设置一个别名。
type I64 = Int64
类型别名的定义以关键字 type 开头,接着是类型的别名(如上例中的 I64),然后是等号 =,最后是原类型(即被取别名的类型,如上例中的 Int64)。
只能在源文件顶层定义类型别名,并且原类型必须在别名定义处可见。例如,下例中 Int64 的别名定义在 main 中将报错,LongNameClassB 类型在为其定义别名时不可见,同样报错。
main() {
type I64 = Int64 // Error, type aliases can only be defined at the top level of the source file
}
class LongNameClassA { }
type B = LongNameClassB // Error, type 'LongNameClassB' is not defined
一个(或多个)类型别名定义中禁止出现(直接或间接的)循环引用。
type A = (Int64, A) // Error, 'A' refered itself
type B = (Int64, C) // Error, 'B' and 'C' are circularly refered
type C = (B, Int64)
类型别名并不会定义一个新的类型,它仅仅是为原类型定义了另外一个名字,它有如下几种使用场景:
-
作为类型使用,例如:
type A = B class B {} var a: A = B() // Use typealias A as type B -
当类型别名实际指向的类型为 class、struct 时,可以作为构造器名称使用:
type A = B class B {} func foo() { A() } // Use type alias A as constructor of B -
当类型别名实际指向的类型为 class、interface、struct 时,可以作为访问内部静态成员变量或函数的类型名:
type A = B class B { static var b : Int32 = 0; static func foo() {} } func foo() { A.foo() // Use A to access static method in class B A.b } -
当类型别名实际指向的类型为 enum 时,可以作为 enum 声明的构造器的类型名:
enum TimeUnit { Day | Month | Year } type Time = TimeUnit var a = Time.Day var b = Time.Month // Use type alias Time to access constructors in TimeUnit
需要注意的是,当前用户自定义的类型别名暂不支持在类型转换表达式中使用,参考如下示例:
type MyInt = Int32
MyInt(0) // Error, no matching function for operator '()' function call
泛型别名
类型别名也是可以声明类型形参的,但是不能对其形参使用 where 声明约束,对于泛型变元的约束会在后面给出解释。
当一个泛型类型的名称过长时,可以使用类型别名来为其声明一个更短的别名。例如,有一个类型为 RecordData ,可以把他用类型别名简写为 RD :
struct RecordData<T> {
var a: T
public init(x: T){
a = x
}
}
type RD<T> = RecordData<T>
main(): Int64 {
var struct1: RD<Int32> = RecordData<Int32>(2)
return 1
}
在使用时就可以用 RD<Int32> 来代指 RecordData<Int32> 类型。
泛型约束
泛型约束的作用是在 function、class、interface、struct、enum 声明时明确泛型形参所具备的操作与能力。只有声明了这些约束才能调用相应的成员函数。在很多场景下泛型形参是需要加以约束的。以 id 函数为例:
func id<T>(a: T) {
return a
}
开发者唯一能做的事情就是将函数形参 a 这个值返回,而不能进行 a + 1,println("${a}") 等操作,因为它可能是一个任意的类型,比如 (Bool) -> Bool,这样就无法与整数相加,同样因为是函数类型,也不能通过 println 函数来输出在命令行上。而如果这一泛型形参上有了约束,那么就可以做更多操作了。
约束大致分为接口约束与 class 类型约束。语法为在函数、类型的声明体之前使用 where 关键字来声明,对于声明的泛型形参 T1, T2,可以使用 where T1 <: Interface, T2 <: Class 这样的方式来声明泛型约束,同一个类型变元的多个约束可以使用 & 连接。例如:where T1 <: Interface1 & Interface2。
仓颉中的 println 函数能接受类型为字符串的参数。如果需要把一个泛型类型的变量转为字符串后打印在命令行上,可以对这个泛型类型变元加以约束,这个约束是 core 中定义的 ToString 接口,显然它是一个接口约束:
package std.core // `ToString` is defined in core.
public interface ToString {
func toString(): String
}
这样就可以利用这个约束,定义一个名为 genericPrint 的函数:
func genericPrint<T>(a: T) where T <: ToString {
println(a)
}
main() {
genericPrint<Int64>(10)
return 0
}
结果为:
10
如果 genericPrint 函数的类型实参没有实现 ToString 接口,那么编译器会报错。例如传入一个函数做为参数时:
func genericPrint<T>(a: T) where T <: ToString {
println(a)
}
main() {
genericPrint<(Int64) -> Int64>({ i => 0 })
return 0
}
如果对上面的文件进行编译,那么编译器会抛出泛型类型参数不满足约束的错误。因为 genericPrint 函数的泛型的类型实参不满足约束 (Int64) -> Int64 <: ToString。
除了上述通过接口来表示约束,还可以使用 class 类型来约束一个泛型类型变元。例如:当要声明一个动物园类型 Zoo<T>,但是需要这里声明的类型形参 T 受到约束,这个约束就是 T 需要是动物类型 Animal 的子类型, Animal 类型中声明了 run 成员函数。这里声明两个子类型 Dog 与 Fox 都实现了 run 成员函数,这样在 Zoo<T> 的类型中,就可以对于 animals 数组列表中存放的动物实例调用 run 成员函数:
import std.collection.*
abstract class Animal {
public func run(): String
}
class Dog <: Animal {
public func run(): String {
return "dog run"
}
}
class Fox <: Animal {
public func run(): String {
return "fox run"
}
}
class Zoo<T> where T <: Animal {
var animals: ArrayList<Animal> = ArrayList<Animal>()
public func addAnimal(a: T) {
animals.add(a)
}
public func allAnimalRuns() {
for(a in animals) {
println(a.run())
}
}
}
main() {
var zoo: Zoo<Animal> = Zoo<Animal>()
zoo.addAnimal(Dog())
zoo.addAnimal(Fox())
zoo.allAnimalRuns()
return 0
}
程序的输出为:
dog run
fox run
注意:
泛型变元的约束只能是具体的 class 类型或 interface,且变元如果存在多个 class 类型的上界时,它们必须在同一继承链路上。
扩展概述
扩展可以为在当前 package 中可见的类型(除函数、元组、接口)添加新功能。
当不能破坏被扩展类型的封装性,但希望添加额外的功能时,可以使用扩展。
可以添加的功能包括:
- 添加成员函数
- 添加操作符重载函数
- 添加成员属性
- 实现接口
扩展虽然可以添加额外的功能,但不能变更被扩展类型的封装性,因此扩展不支持以下功能:
- 扩展不能增加成员变量。
- 扩展的函数和属性必须拥有实现。
- 扩展的函数和属性不能使用
open、override、redef修饰。 - 扩展不能访问被扩展类型中
private修饰的成员。
根据扩展有没有实现新的接口,扩展可以分为 直接扩展 和 接口扩展 两种用法。直接扩展即不包含额外接口的扩展;接口扩展即包含接口的扩展,接口扩展可以用来为现有的类型添加新功能并实现接口,增强抽象灵活性。
直接扩展
一个简单的扩展语法结构示例如下:
extend String {
public func printSize() {
println("the size is ${this.size}")
}
}
如上例所示,扩展使用 extend 关键字声明,其后跟着被扩展的类型 String 和扩展的功能。
当为 String 扩展了 printSize 函数之后,就能在当前 package 内对 String 的实例访问该函数,就像是 String 本身具备该函数。
main() {
let a = "123"
a.printSize() // the size is 3
}
编译执行上述代码,输出结果为:
the size is 3
被扩展类型是泛型类型时,有两种扩展语法可以对泛型类型扩展功能。
一种是针对特定泛型实例化类型进行扩展,关键字 extend 后允许带一个任意实例化完全的泛型类型。为这些类型增加的功能只有在类型完全匹配时才能使用,且泛型类型的类型实参必须符合泛型类型定义处的约束要求。
例如下面所示的 Foo<T>。
class Foo<T> where T <: ToString {}
extend Foo<Int64> {} // Ok
class Bar {}
extend Foo<Bar> {} // Error
另一种是在 extend 后面引入泛型形参的泛型扩展。泛型扩展可以用来扩展未实例化或未完全实例化的泛型类型。在 extend 后声明的泛型形参必须被直接或间接使用在被扩展的泛型类型上。为这些类型增加的功能只有在类型和约束完全匹配时才能使用。
例如下面所示的 MyList<T>。
class MyList<T> {
public let data: Array<T> = Array<T>()
}
extend<T> MyList<T> {} // OK
extend<R> MyList<R> {} // OK
extend<T, R> MyList<(T, R)> {} // OK
extend MyList {} // Error
extend<T, R> MyList<T> {} // Error
extend<T, R> MyList<T, R> {} // Error
对于泛型类型的扩展,可以在其中声明额外的泛型约束,来实现一些有限情况下才能使用的函数。
例如可以定义一个叫 Pair 的类型,这个类型可以方便地存储两个元素(类似于 Tuple)。
希望 Pair 类型可以容纳任何类型,因此两个泛型变元不应该有任何约束,这样才能保证 Pair 能容纳所有类型。
但同时又希望当两个元素可以判等的时候,让 Pair 也可以判等,这时就可以用扩展来实现这个功能。
如下面的代码所示,使用扩展语法,约束了 T1 和 T2 在支持 equals 的情况下,Pair 也可以实现 equals 函数。
class Pair<T1, T2> {
var first: T1
var second: T2
public init(a: T1, b: T2) {
first = a
second = b
}
}
interface Eq<T> {
func equals(other: T): Bool
}
extend<T1, T2> Pair<T1, T2> where T1 <: Eq<T1>, T2 <: Eq<T2> {
public func equals(other: Pair<T1, T2>) {
first.equals(other.first) && second.equals(other.second)
}
}
class Foo <: Eq<Foo> {
public func equals(other: Foo): Bool {
true
}
}
main() {
let a = Pair(Foo(), Foo())
let b = Pair(Foo(), Foo())
println(a.equals(b)) // true
}
编译执行上述代码,输出结果为:
true
接口扩展
例如下面的例子,类型 Array 本身没有实现接口 PrintSizeable,但可以通过扩展的方式为 Array 增加额外的成员函数 printSize,并实现 PrintSizeable。
interface PrintSizeable {
func printSize(): Unit
}
extend<T> Array<T> <: PrintSizeable {
public func printSize() {
println("The size is ${this.size}")
}
}
当使用扩展为 Array 实现 PrintSizeable 之后,就相当于在 Array 定义时实现接口 PrintSizeable。
因此可以将 Array 作为 PrintSizeable 的实现类型来使用,代码如下所示。
main() {
let a: PrintSizeable = Array<Int64>()
a.printSize() // 0
}
编译执行上述代码,输出结果为:
The size is 0
可以在同一个扩展内同时实现多个接口,多个接口之间使用 & 分开,接口的顺序没有先后关系。
如下面代码所示,可以在扩展中为 Foo 同时实现 I1、I2、I3。
interface I1 {
func f1(): Unit
}
interface I2 {
func f2(): Unit
}
interface I3 {
func f3(): Unit
}
class Foo {}
extend Foo <: I1 & I2 & I3 {
public func f1(): Unit {}
public func f2(): Unit {}
public func f3(): Unit {}
}
也可以在接口扩展中声明额外的泛型约束,来实现一些特定约束下才能满足的接口。
例如可以让上面的 Pair 类型实现 Eq 接口,这样 Pair 自己也能成为一个符合 Eq 约束的类型,如下代码所示。
class Pair<T1, T2> {
var first: T1
var second: T2
public init(a: T1, b: T2) {
first = a
second = b
}
}
interface Eq<T> {
func equals(other: T): Bool
}
extend<T1, T2> Pair<T1, T2> <: Eq<Pair<T1, T2>> where T1 <: Eq<T1>, T2 <: Eq<T2> {
public func equals(other: Pair<T1, T2>) {
first.equals(other.first) && second.equals(other.second)
}
}
class Foo <: Eq<Foo> {
public func equals(other: Foo): Bool {
true
}
}
main() {
let a = Pair(Foo(), Foo())
let b = Pair(Foo(), Foo())
println(a.equals(b)) // true
}
编译执行上述代码,输出结果为:
true
如果被扩展的类型已经包含接口要求的函数或属性,那么在扩展中不需要并且也不能重新实现这些函数或属性。
例如下面的例子,定义了一个新接口 Sizeable,目的是获取某个类型的 size,而已经知道 Array 中包含了这个函数,因此就可以通过扩展让 Array 实现 Sizeable,而不需要添加额外的函数。
interface Sizeable {
prop size: Int64
}
extend<T> Array<T> <: Sizeable {}
main() {
let a: Sizeable = Array<Int64>()
println(a.size)
}
编译执行上述代码,输出结果为:
0
当多个接口扩展实现的接口存在继承关系时,扩展将按照“先检查实现父接口的扩展,再检查子接口的扩展”的顺序进行检查。
例如,接口 I1 存在一个子接口 I2,且 I1 中包含一个默认实现,类型 A 的两个扩展分别实现了父子接口,根据以上检查顺序,实现 I1 的扩展将会优先检查,然后再检查实现 I2 的扩展。
interface I1 {
func foo(): Unit { println("I1 foo") }
}
interface I2 <: I1 {
func foo(): Unit { println("I2 foo") }
}
class A {}
extend A <: I1 {} // first check
extend A <: I2 {} // second check
main() {
A().foo()
}
编译执行上述代码,输出结果为:
I2 foo
以上例子中,当检查实现 I1 的扩展时,会从 I1 中继承 foo 函数。在检查实现 I2 的扩展时,由于 A 中已存在一个继承的,且签名相同的默认实现 foo ,此时 foo 将被覆盖。因此,调用 A 的 foo 函数时,最终指向 I2(子接口)中的实现。
如果同一类型的两个接口扩展实现的接口存在继承冲突,导致无法确定检查顺序时,将会报错。
interface I1 {}
interface I2 <: I1 {}
interface I3 {}
interface I4 <: I3 {}
class A {}
extend A <: I1 & I4 {} // error: unable to decide which extension happens first
extend A <: I2 & I3 {} // error: unable to decide which extension happens first
如果同一类型的两个接口扩展实现的接口不存在继承关系,将会被同时检查。
interface I1 {
func foo() {}
}
interface I2 {
func foo() {}
}
class A {}
extend A <: I1 {} // Error, multiple default implementations, need to re-implement 'foo' in 'A'
extend A <: I2 {} // Error, multiple default implementations, need to re-implement 'foo' in 'A'
注意:
当类 A 有个泛型基类
B<T1,...,Tn>,B<T1,...,Tn>扩展了一个接口I<R1,...,Rn>,I<R1,...,Rn>带有默认实现的实例或者静态函数(比如 foo),该函数没有在B<T1,...,Tn>及其扩展中被重写,且类 A 没有直接实现接口I<R1,...,Rn>时,通过类 A 的实例调用函数 foo 时会产生非预期行为。计划在后续版本修复该问题。
interface I<N> {
func foo(n: N): N {n}
}
open class B<T> {}
extend<T> B<T> <: I<T> {}
class A <: B<Int64>{}
main() {
A().foo(0) // this call triggers unexpected behaviour
}
访问规则
扩展的修饰符
扩展本身不能使用修饰符修饰。
例如,下面的例子中对 A 的直接扩展前使用了 public 修饰,将编译报错。
public class A {}
public extend A {} // Error, expected no modifier before extend
扩展成员可使用的修饰符有:static、public、protected、internal、private、mut。
- 使用
private修饰的成员只能在本扩展内使用,外部不可见。 - 使用
internal修饰的成员可以在当前包及子包(包括子包的子包)内使用,这是默认行为。 - 使用
protected修饰的成员在本模块内可以被访问(受导出规则限制)。当被扩展类型是 class 时,该 class 的子类定义体也能访问。 - 使用
static修饰的成员,只能通过类型名访问,不能通过实例对象访问。 - 对
struct类型的扩展可以定义mut函数。
package p1
public open class A {}
extend A {
public func f1() {}
protected func f2() {}
private func f3() {}
static func f4() {}
}
main() {
A.f4()
var a = A()
a.f1()
a.f2()
}
扩展内的成员定义不支持使用 open、override、redef 修饰。
class Foo {
public open func f() {}
static func h() {}
}
extend Foo {
public override func f() {} // Error
public open func g() {} // Error
redef static func h() {} // Error
}
扩展的孤儿规则
为一个其他 package 的类型实现另一个 package 的接口,可能造成理解上的困扰。
为了防止一个类型被意外实现不合适的接口,仓颉不允许定义孤儿扩展,即既不与接口(包含接口继承链上的所有接口)定义在同一个包中,也不与被扩展类型定义在同一个包中的接口扩展。
如下代码所示,不能在 package c 中,为 package a 里的 Foo 实现 package b 里的 Bar。
只能在 package a 或者在 package b 中为 Foo 实现 Bar。
// package a
public class Foo {}
// package b
public interface Bar {}
// package c
import a.Foo
import b.Bar
extend Foo <: Bar {} // Error
扩展的访问和遮盖
扩展的实例成员与类型定义处一样可以使用 this,this 的功能保持一致。同样也可以省略 this 访问成员。扩展的实例成员不能使用 super。
class A {
var v = 0
}
extend A {
func f() {
print(this.v) // Ok
print(v) // Ok
}
}
扩展不能访问被扩展类型中 private 修饰的成员。
class A {
private var v1 = 0
protected var v2 = 0
}
extend A {
func f() {
print(v1) // Error
print(v2) // Ok
}
}
扩展不能遮盖被扩展类型的任何成员。
class A {
func f() {}
}
extend A {
func f() {} // Error
}
扩展也不允许遮盖其他扩展增加的任何成员。
class A {}
extend A {
func f() {}
}
extend A {
func f() {} // Error
}
在同一个包内,对同一类型可以扩展多次,并且在扩展中可以直接调用被扩展类型的其他扩展中非 private 修饰的函数。
class Foo {}
extend Foo { // OK
private func f() {}
func g() {}
}
extend Foo { // OK
func h() {
g() // OK
f() // Error
}
}
扩展泛型类型时,可以使用额外的泛型约束。泛型类型的任意两个扩展之间的可见性规则如下:
- 如果两个扩展的约束相同,则两个扩展相互可见,即两个扩展内可以直接使用对方内的函数或属性;
- 如果两个扩展的约束不同,且两个扩展的约束有包含关系,约束更宽松的扩展对约束更严格的扩展可见,反之,不可见;
- 当两个扩展的约束不同时,且两个约束不存在包含关系,则两个扩展均互相不可见。
示例:假设对同一个类型 E<X> 的两个扩展分别为扩展 1 和扩展 2 ,X 的约束在扩展 1 中比扩展 2 中更严格,那么扩展 1 中的函数和属性对扩展 2 均不可见,反之,扩展 2 中的函数和属性对扩展 1 可见。
open class A {}
class B <: A {}
class E<X> {}
interface I1 {
func f1(): Unit
}
interface I2 {
func f2(): Unit
}
extend<X> E<X> <: I1 where X <: B { // extension 1
public func f1(): Unit {
f2() // OK
}
}
extend<X> E<X> <: I2 where X <: A { // extension 2
public func f2(): Unit {
f1() // Error
}
}
扩展的导入导出
扩展也是可以被导入和导出的,但是扩展本身不能使用可见性修饰符修饰,扩展的导出有一套特殊的规则。
对于直接扩展,当扩展与被扩展的类型在同一个包中,扩展是否导出,由被扩展类型与泛型约束(如果有)的访问修饰符同时决定,当所有的泛型约束都是导出类型(修饰符与导出规则,详见顶层声明的可见性章节)时,该扩展将被导出。当扩展与被扩展类型不在同一个包中时,该扩展不会导出。
如以下代码所示,Foo 是导出的,f1 函数所在的扩展由于不导出泛型约束,故该扩展不会被导出;f2 和 f3 函数所在的扩展的泛型约束均被导出,故该扩展被导出;f4 函数所在的扩展包含多个泛型约束,且泛型约束中 I1 未被导出,故该扩展不会被导出;f5 函数所在的扩展包含多个泛型约束,所有的泛型约束均是导出的,故该扩展会被导出。
// package a.b
package a.b
private interface I1 {}
internal interface I2 {}
protected interface I3 {}
extend Int64 <: I1 & I2 & I3 {}
public class Foo<T> {}
// The extension will not be exported
extend<T> Foo<T> where T <: I1 {
public func f1() {}
}
// The extension will be exported, and only packages that import both Foo and I2 will be able to access it.
extend<T> Foo<T> where T <: I2 {
public func f2() {}
}
// The extension will be exported, and only packages that import both Foo and I3 will be able to access it.
extend<T> Foo<T> where T <: I3 {
public func f3() {}
}
// The extension will not be exported. The I1 with the lowest access level determines the export.
extend<T> Foo<T> where T <: I1 & I2 & I3 {
public func f4() {}
}
// The extension is exported. Only the package that imports Foo, I2, and I3 can access the extension.
extend<T> Foo<T> where T <: I2 & I3 {
public func f5() {}
}
// package a.c
package a.c
import a.b.*
main() {
Foo<Int64>().f1() // Cannot access.
Foo<Int64>().f2() // Cannot access. Visible only for sub-pkg.
Foo<Int64>().f3() // Ok.
Foo<Int64>().f4() // Cannot access.
Foo<Int64>().f5() // Cannot access. Visible only for sub-pkg.
}
// package a.b.d
package a.b.d
import a.b.*
main() {
Foo<Int64>().f1() // Cannot access.
Foo<Int64>().f2() // Ok.
Foo<Int64>().f3() // Ok.
Foo<Int64>().f4() // Cannot access.
Foo<Int64>().f5() // Ok.
}
对于接口扩展则分为两种情况:
- 当接口扩展与被扩展类型在相同的
package时,扩展会与被扩展类型以及泛型约束(如果有)一起被导出,不受接口类型的访问级别影响,包外不需要导入接口类型也能访问该扩展的成员。 - 当接口扩展与被扩展类型在不同的
package时,接口扩展是否导出由接口类型以及泛型约束(如果有)里用到的类型中最小的访问级别决定。其他package必须导入被扩展类型、相应的接口以及约束用到的类型(如果有),才能访问对应接口包含的扩展成员。
如下代码所示,在包 a 中,虽然接口访问修饰符为 private,但 Foo 的扩展仍然会被导出。
// package a
package a
private interface I0 {}
public class Foo<T> {}
// The extension is exported.
extend<T> Foo<T> <: I0 {}
当在其他包中为 Foo 类型扩展时,扩展是否导出由实现接口和泛型约束的访问修饰符决定。实现接口至少存在一个导出的接口,且所有的泛型约束均可导出时,该扩展将被导出。
// package b
package b
import a.Foo
private interface I1 {}
internal interface I2 {}
protected interface I3 {}
public interface I4 {}
// The extension will not be exported because I1 is not visible outside the file.
extend<T> Foo<T> <: I1 {}
// The extension is exported.
extend<T> Foo<T> <: I2 {}
// The extension is exported.
extend<T> Foo<T> <: I3 {}
// The extension is exported
extend<T> Foo<T> <: I1 & I2 & I3 {}
// The extension will not be exported. The I1 with the lowest access level determines the export.
extend<T> Foo<T> <: I4 where T <: I1 & I2 & I3 {}
// The extension is exported.
extend<T> Foo<T> <: I4 where T <: I2 & I3 {}
// The extension is exported.
extend<T> Foo<T> <: I4 & I3 where T <: I2 {}
特别的,接口扩展导出的成员仅限于接口中包含的成员。
// package a
package a
public class Foo {}
// package b
package b
import a.Foo
public interface I1 {
func f1(): Unit
}
public interface I2 {
func f2(): Unit
}
extend Foo <: I1 & I2 {
public func f1(): Unit {}
public func f2(): Unit {}
public func f3(): Unit {} // f3 will not be exported
}
// package c
package c
import a.Foo
import b.I1
main() {
let x: Foo = Foo()
x.f1() // OK, because f1 is a member of I1.
x.f2() // error, I2 is not imported
x.f3() // error, f3 not found
}
与扩展的导出类似,扩展的导入也不需要显式地用 import 导入,扩展的导入只需要导入被扩展的类型、接口和泛型约束,就可以导入可访问的所有扩展。
如下面的代码所示,在 package b 中,只需要导入 Foo 就可以使用 Foo 对应的扩展中的函数 f。
而对于接口扩展,需要同时导入被扩展的类型、扩展的接口和泛型约束(如果有)才能使用。因此在 package c 中,需要同时导入 Foo 和 I 才能使用对应扩展中的函数 g。
// package a
package a
public class Foo {}
extend Foo {
public func f() {}
}
// package b
package b
import a.Foo
public interface I {
func g(): Unit
}
extend Foo <: I {
public func g() {
this.f() // OK
}
}
// package c
package c
import a.Foo
import b.I
func test() {
let a = Foo()
a.f() // OK
a.g() // OK
}
基础 Collection 类型概述
本章介绍仓颉语言中常用的几种基础 Collection 类型,包括 Array、ArrayList、HashSet 和 HashMap。
可以在不同的场景中选择适合对应业务的类型:
- Array:不需要增加和删除元素,但需要修改元素
- ArrayList:需要频繁对元素增删查改
- HashSet:希望每个元素都是唯一的
- HashMap:希望存储一系列的映射关系
下表是这些类型的基础特性:
| 类型名称 | 元素可变 | 增删元素 | 元素唯一性 | 有序序列 |
|---|---|---|---|---|
Array<T> | Y | N | N | Y |
ArrayList<T> | Y | Y | N | Y |
HashSet<T> | N | Y | Y | N |
HashMap<K, V> | K: N, V: Y | Y | K: Y, V: N | N |
ArrayList
使用 ArrayList 类型需要导入 collection 包:
import std.collection.*
仓颉使用 ArrayList<T> 表示 ArrayList 类型,T 表示 ArrayList 的元素类型,T 可以是任意类型。
ArrayList 具备非常好的扩容能力,适合于需要频繁增加和删除元素的场景。
相比 Array,ArrayList 既可以原地修改元素,也可以原地增加和删除元素。
ArrayList 的可变性是一个非常有用的特征,可以让同一个 ArrayList 实例的所有引用都共享同样的元素,并且对它们统一进行修改。
var a: ArrayList<Int64> = ... // ArrayList whose element type is Int64
var b: ArrayList<String> = ... // ArrayList whose element type is String
元素类型不相同的 ArrayList 是不相同的类型,所以它们之间不可以互相赋值。
因此以下例子是不合法的。
b = a // Type mismatch
仓颉中可以使用构造函数的方式构造一个指定的 ArrayList。
let a = ArrayList<String>() // Created an empty ArrayList whose element type is String
let b = ArrayList<String>(100) // Created an ArrayList whose element type is String, and allocate a space of 100
let c = ArrayList<Int64>([0, 1, 2]) // Created an ArrayList whose element type is Int64, containing elements 0, 1, 2
let d = ArrayList<Int64>(c) // Use another Collection to initialize an ArrayList
let e = ArrayList<String>(2, {x: Int64 => x.toString()}) // Created an ArrayList whose element type is String and size is 2. All elements are initialized by specified rule function
访问 ArrayList 成员
当需要对 ArrayList 的所有元素进行访问时,可以使用 for-in 循环遍历 ArrayList 的所有元素。
import std.collection.*
main() {
let list = ArrayList<Int64>([0, 1, 2])
for (i in list) {
println("The element is ${i}")
}
}
编译并执行上面的代码,会输出:
The element is 0
The element is 1
The element is 2
当需要知道某个 ArrayList 包含的元素个数时,可以使用 size 属性获得对应信息。
import std.collection.*
main() {
let list = ArrayList<Int64>([0, 1, 2])
if (list.size == 0) {
println("This is an empty arraylist")
} else {
println("The size of arraylist is ${list.size}")
}
}
编译并执行上面的代码,会输出:
The size of arraylist is 3
当想访问单个指定位置的元素时,可以使用下标语法访问(下标的类型必须是 Int64)。非空 ArrayList 的第一个元素总是从位置 0 开始的。可以从 0 开始访问 ArrayList 的任意一个元素,直到最后一个位置(ArrayList 的 size - 1)。使用负数或大于等于 size 的索引会触发运行时异常。
let a = list[0] // a == 0
let b = list[1] // b == 1
let c = list[-1] // Runtime exceptions
ArrayList 也支持下标中使用 Range 的语法,详见 Array 章节。
修改 ArrayList
可以使用下标语法对某个位置的元素进行修改。
let list = ArrayList<Int64>([0, 1, 2])
list[0] = 3
ArrayList 是引用类型,ArrayList 在作为表达式使用时不会拷贝副本,同一个 ArrayList 实例的所有引用都会共享同样的数据。
因此对 ArrayList 元素的修改会影响到该实例的所有引用。
let list1 = ArrayList<Int64>([0, 1, 2])
let list2 = list1
list2[0] = 3
// list1 contains elements 3, 1, 2
// list2 contains elements 3, 1, 2
如果需要将单个元素添加到 ArrayList 的末尾,请使用 add 函数。如果希望同时添加多个元素到末尾,可以使用 add(all!: Collection<T>) 函数,这个函数可以接受其他相同元素类型的 Collection 类型(例如 Array)。
import std.collection.*
main() {
let list = ArrayList<Int64>()
list.add(0) // list contains element 0
list.add(1) // list contains elements 0, 1
let li = [2, 3]
list.add(all: li) // list contains elements 0, 1, 2, 3
}
可以通过 add(T, at!: Int64) 和 add(all!: Collection<T>, at!: Int64) 函数将指定的单个元素或相同元素类型的 Collection 值插入到指定索引的位置。该索引处的元素和后面的元素会被挪后以腾出空间。
let list = ArrayList<Int64>([0, 1, 2]) // list contains elements 0, 1, 2
list.add(4, at: 1) // list contains elements 0, 4, 1, 2
从 ArrayList 中删除元素,可以使用 remove 函数,需要指定删除的索引。该索引处后面的元素会前移以填充空间。
let list = ArrayList<String>(["a", "b", "c", "d"]) // list contains the elements "a", "b", "c", "d"
list.remove(at: 1) // Delete the element at subscript 1, now the list contains elements "a", "c", "d"
增加 ArrayList 的大小
每个 ArrayList 都需要特定数量的内存来保存其内容。当向 ArrayList 添加元素并且该 ArrayList 开始超出其保留容量时,该 ArrayList 会分配更大的内存区域并将其所有元素复制到新内存中。这种增长策略意味着触发重新分配内存的添加操作具有性能成本,但随着 ArrayList 的保留内存变大,它们发生的频率会越来越低。
如果知道大约需要添加多少个元素,可以在添加之前预备足够的内存以避免中间重新分配,这样可以提升性能表现。
import std.collection.*
main() {
let list = ArrayList<Int64>(100) // Allocate space at once
for (i in 0..100) {
list.add(i) // Does not trigger reallocation of space
}
list.reserve(100) // Prepare more space
for (i in 0..100) {
list.add(i) // Does not trigger reallocation of space
}
}
HashSet
使用 HashSet 类型需要导入 collection 包:
import std.collection.*
可以使用 HashSet 类型来构造只拥有不重复元素的 Collection。
仓颉使用 HashSet<T> 表示 HashSet 类型,T 表示 HashSet 的元素类型,T 必须是实现了 Hashable 和 Equatable<T> 接口的类型,例如数值或 String。
var a: HashSet<Int64> = ... // HashSet whose element type is Int64
var b: HashSet<String> = ... // HashSet whose element type is String
元素类型不相同的 HashSet 是不相同的类型,所以它们之间不可以互相赋值。
因此以下例子是不合法的。
b = a // Type mismatch
仓颉中可以使用构造函数的方式构造一个指定的 HashSet。
let a = HashSet<String>() // Created an empty HashSet whose element type is String
let b = HashSet<String>(100) // Created a HashSet whose capacity is 100
let c = HashSet<Int64>([0, 1, 2]) // Created a HashSet whose element type is Int64, containing elements 0, 1, 2
let d = HashSet<Int64>(c) // Use another Collection to initialize a HashSet
let e = HashSet<Int64>(10, {x: Int64 => (x * x)}) // Created a HashSet whose element type is Int64 and size is 10. All elements are initialized by specified rule function
访问 HashSet 成员
当需要对 HashSet 的所有元素进行访问时,可以使用 for-in 循环遍历 HashSet 的所有元素。
需要注意的是,HashSet 并不保证按插入元素的顺序排列,因此遍历的顺序和插入的顺序可能不同。
import std.collection.*
main() {
let mySet = HashSet<Int64>([0, 1, 2])
for (i in mySet) {
println("The element is ${i}")
}
}
编译并执行上面的代码,有可能会输出:
The element is 0
The element is 1
The element is 2
当需要知道某个 HashSet 包含的元素个数时,可以使用 size 属性获得对应信息。
import std.collection.*
main() {
let mySet = HashSet<Int64>([0, 1, 2])
if (mySet.size == 0) {
println("This is an empty hashset")
} else {
println("The size of hashset is ${mySet.size}")
}
}
编译并执行上面的代码,会输出:
The size of hashset is 3
当想判断某个元素是否被包含在某个 HashSet 中时,可以使用 contains 函数。如果该元素存在会返回 true,否则返回 false。
let mySet = HashSet<Int64>([0, 1, 2])
let a = mySet.contains(0) // a == true
let b = mySet.contains(-1) // b == false
修改 HashSet
HashSet 是一种可变的引用类型,HashSet 类型提供了添加元素、删除元素的功能。
HashSet 的可变性是一个非常有用的特征,可以让同一个 HashSet 实例的所有引用都共享同样的元素,并且对它们统一进行修改。
如果需要将单个元素添加到 HashSet 里,请使用 add 函数。如果希望同时添加多个元素,可以使用 add(all!: Collection<T>) 函数,这个函数可以接受另一个相同元素类型的 Collection 类型(例如 Array)。当元素不存在时,add 函数会执行添加的操作,当 HashSet 中存在相同元素时,add 函数将不会有效果。
let mySet = HashSet<Int64>()
mySet.add(0) // mySet contains elements 0
mySet.add(0) // mySet contains elements 0
mySet.add(1) // mySet contains elements 0, 1
let li = [2, 3]
mySet.add(all: li) // mySet contains elements 0, 1, 2, 3
HashSet 是引用类型,HashSet 在作为表达式使用时不会拷贝副本,同一个 HashSet 实例的所有引用都会共享同样的数据。
因此对 HashSet 元素的修改会影响到该实例的所有引用。
let set1 = HashSet<Int64>([0, 1, 2])
let set2 = set1
set2.add(3)
// set1 contains elements 0, 1, 2, 3
// set2 contains elements 0, 1, 2, 3
从 HashSet 中删除元素,可以使用 remove 函数,需要指定删除的元素。
let mySet = HashSet<Int64>([0, 1, 2, 3])
mySet.remove(1) // mySet contains elements 0, 2, 3
HashMap
使用 HashMap 类型需要导入 collection 包:
import std.collection.*
可以使用 HashMap 类型来构造元素为键值对的 Collection。
HashMap 是一种哈希表,提供对其包含的元素的快速访问。表中的每个元素都使用其键作为标识,可以使用键来访问相应的值。
仓颉使用 HashMap<K, V> 表示 HashMap 类型,K 表示 HashMap 的键类型,K 必须是实现了 Hashable 和 Equatable<K> 接口的类型,例如数值或 String。V 表示 HashMap 的值类型,V 可以是任意类型。
var a: HashMap<Int64, Int64> = ... // HashMap whose key type is Int64 and value type is Int64
var b: HashMap<String, Int64> = ... // HashMap whose key type is String and value type is Int64
元素类型不相同的 HashMap 是不相同的类型,所以它们之间不可以互相赋值。
因此以下例子是不合法的。
b = a // Type mismatch
仓颉中可以使用构造函数的方式构造一个指定的 HashMap。
let a = HashMap<String, Int64>() // Created an empty HashMap whose key type is String and value type is Int64
let b = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)]) // whose key type is String and value type is Int64, containing elements ("a", 0), ("b", 1), ("c", 2)
let c = HashMap<String, Int64>(b) // Use another Collection to initialize a HashMap
let d = HashMap<String, Int64>(10) // Created a HashMap whose key type is String and value type is Int64 and capacity is 10
let e = HashMap<Int64, Int64>(10, {x: Int64 => (x, x * x)}) // Created a HashMap whose key and value type is Int64 and size is 10. All elements are initialized by specified rule function
访问 HashMap 成员
当需要对 HashMap 的所有元素进行访问时,可以使用 for-in 循环遍历 HashMap 的所有元素。
需要注意的是,HashMap 并不保证按插入元素的顺序排列,因此遍历的顺序和插入的顺序可能不同。
import std.collection.*
main() {
let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
for ((k, v) in map) {
println("The key is ${k}, the value is ${v}")
}
}
编译并执行上面的代码,有可能会输出:
The key is a, the value is 0
The key is b, the value is 1
The key is c, the value is 2
当需要知道某个 HashMap 包含的元素个数时,可以使用 size 属性获得对应信息。
import std.collection.*
main() {
let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
if (map.size == 0) {
println("This is an empty hashmap")
} else {
println("The size of hashmap is ${map.size}")
}
}
编译并执行上面的代码,会输出:
The size of hashmap is 3
当想判断 HashMap 中是否包含某个键时,可以使用 contains 函数。如果该键存在会返回 true,否则返回 false。
let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
let a = map.contains("a") // a == true
let b = map.contains("d") // b == false
当想访问指定键对应的元素时,可以使用下标语法访问(下标的类型必须是键类型)。使用不存在的键作为索引会触发运行时异常。
let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
let a = map["a"] // a == 0
let b = map["b"] // b == 1
let c = map["d"] // Runtime exceptions
修改 HashMap
HashMap 是一种可变的引用类型,HashMap 类型提供了修改元素、添加元素、删除元素的功能。
HashMap 的可变性是一个非常有用的特征,可以让同一个 HashMap 实例的所有引用都共享同样的元素,并且对它们统一进行修改。
可以使用下标语法对某个键对应的值进行修改。
let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
map["a"] = 3
HashMap 是引用类型,HashMap 在作为表达式使用时不会拷贝副本,同一个 HashMap 实例的所有引用都会共享同样的数据。
因此对 HashMap 元素的修改会影响到该实例的所有引用。
let map1 = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
let map2 = map1
map2["a"] = 3
// map1 contains the elements ("a", 3), ("b", 1), ("c", 2)
// map2 contains the elements ("a", 3), ("b", 1), ("c", 2)
如果需要将单个键值对添加到 HashMap 里,请使用 add 函数。如果希望同时添加多个键值对,可以使用 add(all!: Collection<(K, V)>) 函数。当键不存在时,add 函数会执行添加的操作,当键存在时,add 函数会将新的值覆盖旧的值。
let map = HashMap<String, Int64>()
map.add("a", 0) // map contains the element ("a", 0)
map.add("b", 1) // map contains the elements ("a", 0), ("b", 1)
let map2 = HashMap<String, Int64>([("c", 2), ("d", 3)])
map.add(all: map2) // map contains the elements ("a", 0), ("b", 1), ("c", 2), ("d", 3)
除了使用 add 函数以外,也可以使用赋值的方式直接将新的键值对添加到 HashMap。
let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
map["d"] = 3 // map contains the elements ("a", 0), ("b", 1), ("c", 2), ("d", 3)
从 HashMap 中删除元素,可以使用 remove 函数,需要指定删除的键。
let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2), ("d", 3)])
map.remove("d") // map contains the elements ("a", 0), ("b", 1), ("c", 2)
Iterable 和 Collections
前面已经了解过 Range、Array、ArrayList,它们都可以使用 for-in 进行遍历操作。对于开发者自定义的类型,也能实现类似的遍历操作。
Range、Array、ArrayList 都是通过 Iterable 来支持 for-in 语法的。
Iterable 是如下形式(只展示了核心代码)的一个内置 interface。
interface Iterable<T> {
func iterator(): Iterator<T>
...
}
iterator 函数要求返回的 Iterator 类型是如下形式(只展示了核心代码)的另一个内置 interface。
interface Iterator<T> <: Iterable<T> {
mut func next(): Option<T>
...
}
可以使用 for-in 语法来遍历任何一个实现了 Iterable 接口类型的实例。
假设有这样一段 for-in 代码,如下所示。
let list = [1, 2, 3]
for (i in list) {
println(i)
}
它等价于如下形式的 while 代码。
let list = [1, 2, 3]
var it = list.iterator()
while (true) {
match (it.next()) {
case Some(i) => println(i)
case None => break
}
}
另外一种常见的遍历 Iterable 类型的方法是在 while 表达式的条件中使用模式匹配,比如上面 while 代码的另一种等价写法是:
let list = [1, 2, 3]
var it = list.iterator()
while (let Some(i) <- it.next()) {
println(i)
}
Array、ArrayList、HashSet、HashMap 类型都实现了 Iterable,因此可以将其用在 for-in 或者 while 中。
包的概述
随着项目规模的不断扩大,仅在一个超大文件中管理源代码会变得十分困难。这时可以将源代码根据功能进行分组,并将不同功能的代码分开管理,每组独立管理的代码会生成一个输出文件。在使用时,通过导入对应的输出文件使用相应的功能,或者通过不同功能的交互与组合实现更加复杂的特性,使得项目管理更加高效。
在仓颉编程语言中,包是编译的最小单元,每个包可以单独输出 AST 文件、静态库文件、动态库文件等产物。每个包有自己的名字空间,在同一个包内不允许有同名的顶层定义或声明(函数重载除外)。一个包中可以包含多个源文件。
模块是若干包的集合,是第三方开发者发布的最小单元。一个模块的程序入口只能在其根目录下,它的顶层最多只能有一个作为程序入口的 main ,该 main 没有参数或参数类型为 Array<String>,返回类型为整数类型或 Unit 类型。
包和模块管理
在仓颉编程语言中,包由一个或多个源码文件组成,同一个包的源码文件必须在同一个目录,并且同一个目录里的源码文件只能属于同一个包。包可以定义子包从而构成树形结构。子包的目录是其父包目录的子目录。没有父包的包称为 root 包,root 包及其子包(包括子包的子包)构成的整棵树称为模块。
仓颉程序常见的组织结构如下:
demo
├── src
│ ├── main.cj
│ └── pkg0
│ ├── pkg0.cj
│ ├── aoo
│ │ └── aoo.cj
│ └── boo
│ └── boo.cj
└── cjpm.toml
cjpm.toml 是当前模块所在工作空间的配置文件,用于定义基础信息、依赖项、编译选项等内容。该文件由仓颉语言的官方包管理工具 cjpm 解析和执行。
注意:
对于同一个模块,如果需要为其配置一个有效的包,则该包所在目录必须直接包含至少一个仓颉代码文件,并且其上游目录都需要是有效包。
包的声明
在仓颉编程语言中,包声明以关键字 package 开头,后接 root 包至当前包由 . 分隔路径上所有包的包名。包名必须是合法的普通标识符(不含原始标识符)。例如:
package pkg1 // root 包 pkg1
package pkg1.sub1 // root 包 pkg1 的子包 sub1
注意:
当前 Windows 平台版本,包名暂不支持使用 Unicode 字符,包名必须是一个仅含 ASCII 字符的合法的普通标识符。
包声明必须在源文件的非空非注释的首行,且同一个包中的不同源文件的包声明必须保持一致。
// file 1
// Comments are accepted
package test
// declarations...
// file 2
let a = 1 // Error, package declaration must appear first in a file
package test
// declarations...
仓颉的包名需反映当前源文件相对于项目源码根目录 src 的路径,并将其中的路径分隔符替换为小数点。例如包的源代码位于 src/directory_0/directory_1 下,root 包名为 pkg 则其源代码中的包声明应为 package pkg.directory_0.directory_1。
需要注意的是:
- 包所在的文件夹名必须与包名一致。
- 源码根目录默认名为
src。 - 源码根目录下的包可以没有包声明,此时编译器将默认为其指定包名
default。
假设源代码目录结构如下:
// The directory structure is as follows:
src
`-- directory_0
|-- directory_1
| |-- a.cj
| `-- b.cj
`-- c.cj
`-- main.cj
则 a.cj、b.cj、c.cj、main.cj 中的包声明可以为:
// a.cj
// in file a.cj, the declared package name must correspond to relative path directory_0/directory_1.
package default.directory_0.directory_1
// b.cj
// in file b.cj, the declared package name must correspond to relative path directory_0/directory_1.
package default.directory_0.directory_1
// c.cj
// in file c.cj, the declared package name must correspond to relative path directory_0.
package default.directory_0
// main.cj
// file main.cj is in the module root directory and may omit package declaration.
main() {
return 0
}
另外,包声明不能引起命名冲突:子包不能和当前包的顶层声明同名。
以下是一些错误示例:
// a.cj
package a
public class B { // Error, 'B' is conflicted with sub-package 'a.B'
public static func f() {}
}
// b.cj
package a.B
public func f {}
// main.cj
import a.B // ambiguous use of 'a.B'
main() {
a.B.f()
return 0
}
顶层声明的可见性
仓颉编程语言中,可以使用访问修饰符来控制对类型、变量、函数等顶层声明的可见性。仓颉语言有 4 种访问修饰符:private、internal、protected、public,在修饰顶层元素时不同访问修饰符的语义如下:
private表示仅当前文件内可见。不同的文件无法访问这类成员。internal表示仅当前包及子包(包括子包的子包)内可见。同一个包内可以不导入就访问这类成员,当前包的子包(包括子包的子包)内可以通过导入来访问这类成员。protected表示仅当前模块内可见。同一个包的文件可以不导入就访问这类成员,不同包但是在同一个模块内的其他包可以通过导入访问这些成员,不同模块的包无法访问这些成员。public表示模块内外均可见。同一个包的文件可以不导入就访问这类成员,其他包可以通过导入访问这些成员。
| 修饰符 | 文件 | 包及子包 | 模块 | 所有包 |
|---|---|---|---|---|
private | Y | N | N | N |
internal | Y | Y | N | N |
protected | Y | Y | Y | N |
public | Y | Y | Y | Y |
不同顶层声明支持的访问修饰符和默认修饰符(默认修饰符是指在省略情况下的修饰符语义,这些默认修饰符也允许显式写出)规定如下:
package支持使用internal、protected、public,默认修饰符为public。import支持使用全部访问修饰符,默认修饰符为private。- 其他顶层声明支持使用全部访问修饰符,默认修饰符为
internal。
package a
private func f1() { 1 } // f1 仅在当前文件内可见
func f2() { 2 } // f2 仅当前包及子包内可见
protected func f3() { 3 } // f3 仅当前模块内可见
public func f4() { 4 } // f4 当前模块内外均可见
仓颉的访问级别排序为 public > protected > internal > private。一个声明的访问修饰符不得高于该声明中用到的类型的访问修饰符的级别,参考如下示例:
-
函数声明中的参数与返回值
// a.cj package a class C {} public func f1(a1: C) // Error, public declaration f1 cannot use internal type C. { return 0 } public func f2(a1: Int8): C // Error, public declaration f2 cannot use internal type C. { return C() } public func f3 (a1: Int8) // Error, public declaration f3 cannot use internal type C. { return C() } -
变量声明
// a.cj package a class C {} public let v1: C = C() // Error, public declaration v1 cannot use internal type C. public let v2 = C() // Error, public declaration v2 cannot use internal type C. -
泛型类型的类型实参
// a.cj package a public class C1<T> {} class C2 {} public let v1 = C1<C2>() // Error, public declaration v1 cannot use internal type C2. -
where约束中的类型上界// a.cj package a interface I {} public class B<T> where T <: I {} // Error, public declaration B cannot use internal type I.
值得注意的是:
-
public修饰的声明在其初始化表达式或者函数体里面可以使用本包可见的任意类型,包括被public修饰的类型和不被public修饰的类型。// a.cj package a class C1 {} func f1(a1: C1) { return 0 } public func f2(a1: Int8) // Ok. { var v1 = C1() return 0 } public let v1 = f1(C1()) // Ok. public class C2 // Ok. { var v2 = C1() } -
public修饰的顶层声明能使用匿名函数,或者任意顶层函数,包括被public修饰的类型和不被public修饰的顶层函数。public var t1: () -> Unit = { => } // Ok. func f1(): Unit {} public let t2 = f1 // Ok. public func f2() // Ok. { return f1 } -
内置类型诸如
Rune和Int64等默认的修饰符是public。var num = 5 public var t3 = num // Ok.
注意:
同一个包内,
private修饰的同名自定义类型(如struct、class、enum和interface等),在某些场景下不支持,不支持场景由编译器进行报错。
例如在以下程序中,example1.cj 与 example2.cj文件包名相同,在 example1.cj 文件中定义了 private 修饰的类 A, 在 example2.cj 文件中定义了 private 修饰的结构体 A。
// example1.cj
package test
private class A {}
public class D<T> {
private let a: A = A()
}
// example2.cj
package test
private struct A {}
public class C<T> {
private let a: A = A()
}
运行以上程序,将输出:
error: currently, it is not possible to export two private declarations with the same name
包的导入
使用 import 语句导入其他包中的声明或定义
在仓颉编程语言中,可以通过 import fullPackageName.itemName 的语法导入其他包中的一个顶层声明或定义,fullPackageName 为完整路径包名,itemName 为声明的名字。导入语句在源文件中的位置必须在包声明之后,其他声明或定义之前。例如:
package a
import std.math.*
import package1.foo
import {package1.foo, package2.bar}
如果要导入的多个 itemName 同属于一个 fullPackageName,可以使用 import fullPackageName.{itemName[, itemName]*} 语法,例如:
import package1.{foo, bar, fuzz}
这等价于:
import package1.foo
import package1.bar
import package1.fuzz
除了通过 import fullPackagename.itemName 语法导入一个特定的顶层声明或定义外,还可以使用 import packageName.* 语法将 packageName 包中所有可见的顶层声明或定义全部导入。例如:
import package1.*
import {package1.*, package2.*}
需要注意:
- 导入的成员的作用域级别低于当前包声明的成员。
- 当已导出的包的模块名或者包名被篡改,使其与导出时指定的模块名或包名不一致,在导入时会报错。
- 只允许导入当前文件可见的顶层声明或定义,导入不可见的声明或定义将会在导入处报错。
- 禁止通过
import导入当前源文件所在包的声明或定义。 - 禁止包间的循环依赖导入,如果包之间存在循环依赖,编译器会报错。
示例如下:
// pkga/a.cj
package pkga // Error, packages pkga pkgb are in circular dependencies.
import pkgb.*
class C {}
public struct R {}
// pkgb/b.cj
package pkgb
import pkga.*
// pkgc/c1.cj
package pkgc
import pkga.C // Error, 'C' is not accessible in package 'pkga'.
import pkga.R // OK, R is an external top-level declaration of package pkga.
import pkgc.f1 // Error, package 'pkgc' should not import itself.
public func f1() {}
// pkgc/c2.cj
package pkgc
func f2() {
/* OK, the imported declaration is visible to all source files of the same package
* and accessing import declaration by its name is supported.
*/
R()
// OK, accessing imported declaration by fully qualified name is supported.
pkga.R()
// OK, the declaration of current package can be accessed directly.
f1()
// OK, accessing declaration of current package by fully qualified name is supported.
pkgc.f1()
}
在仓颉编程语言中,导入的声明或定义如果和当前包中的顶层声明或定义重名且不构成函数重载,则导入的声明和定义会被遮盖;导入的声明或定义如果和当前包中的顶层声明或定义重名且构成函数重载,函数调用时将会根据函数重载的规则进行函数决议。
// pkga/a.cj
package pkga
public struct R {} // R1
public func f(a: Int32) {} // f1
public func f(a: Bool) {} // f2
// pkgb/b.cj
package pkgb
import pkga.*
func f(a: Int32) {} // f3
struct R {} // R2
func bar() {
R() // OK, R2 shadows R1.
f(1) // OK, invoke f3 in current package.
f(true) // OK, invoke f2 in the imported package
}
隐式导入 core 包
诸如 String、Range 等类型能直接使用,并不是因为这些类型是内置类型,而是因为编译器会自动为源码隐式的导入 core 包中所有的 public 修饰的声明。
使用 import as 对导入的名字重命名
不同包的名字空间是分隔的,因此在不同的包之间可能存在同名的顶层声明。在导入不同包的同名顶层声明时,支持使用 import packageName.name as newName 的方式进行重命名来避免冲突。没有名字冲突的情况下仍然可以通过 import as 来重命名导入的内容。import as 具有如下规则:
-
使用
import as对导入的声明进行重命名后,当前包只能使用重命名后的新名字,原名无法使用。 -
如果重命名后的名字与当前包顶层作用域的其他名字存在冲突,且这些名字对应的声明均为函数类型,则参与函数重载,否则报重定义的错误。
-
支持
import pkg as newPkgName的形式对包名进行重命名,以解决不同模块中同名包的命名冲突问题。// a.cj package p1 public func f1() {}// d.cj package p2 public func f3() {}// b.cj package p1 public func f2() {}// c.cj package pkgc public func f1() {}// main.cj import p1 as A import p1 as B import p2.f3 as f // OK import pkgc.f1 as a import pkgc.f1 as b // OK func f(a: Int32) {} main() { A.f1() // OK, package name conflict is resolved by renaming package name. B.f2() // OK, package name conflict is resolved by renaming package name. p1.f1() // Error, the original package name cannot be used. a() // Ok. b() // Ok. pkgc.f1() // Error, the original name cannot be used. } -
如果没有对导入的存在冲突的名字进行重命名,在
import语句处不报错;在使用处,会因为无法导入唯一的名字而报错。这种情况可以通过import as定义别名或者import fullPackageName导入包作为命名空间。// a.cj package p1 public class C {} // b.cj package p2 public class C {} // main1.cj package pkga import p1.C import p2.C main() { let _ = C() // Error } // main2.cj package pkgb import p1.C as C1 import p2.C as C2 main() { let _ = C1() // Ok let _ = C2() // Ok } // main3.cj package pkgc import p1 import p2 main() { let _ = p1.C() // Ok let _ = p2.C() // Ok }
重导出一个导入的名字
在功能繁多的大型项目的开发过程中,这样的场景是非常常见的:包 p2 大量地使用从包 p1 中导入的声明,当包 p3 导入包 p2 并使用其中的功能时,p1 中的声明同样需要对包 p3 可见。如果要求包 p3 自行导入 p2 中使用到的 p1 中的声明,这个过程将过于繁琐。因此希望能够在 p2 被导入时一并导入 p2 使用到的 p1 中的声明。
在仓颉编程语言中,import 可以被 private、internal、protected、public 访问修饰符修饰。其中,被 public、protected 或者 internal 修饰的 import 可以把导入的成员重导出(如果这些导入的成员没有因为名称冲突或者被遮盖导致在本包中不可用)。其他包可以根据可见性直接导入并使用本包中用重导出的内容,无需从原包中导入这些内容。
private import表示导入的内容仅当前文件内可访问,private是import的默认修饰符,不写访问修饰符的import等价于private import。internal import表示导入的内容在当前包及其子包(包括子包的子包)均可访问。非当前包访问需要显式import。protected import表示导入的内容在当前 module 内都可访问。非当前包访问需要显式import。public import表示导入的内容外部都可访问。非当前包访问需要显式import。
在下面的例子中,b 是 a 的子包,在 a 中通过 public import 重导出了 b 中定义的函数 f。
package a
public import a.b.f
public let x = 0
internal package a.b
public func f() { 0 }
import a.f // Ok
let _ = f() // Ok
需要注意的是,包不可以被重导出:如果被 import 导入的是包,那么该 import 不允许被 public、protected 或者 internal 修饰。
public import a.b // Error, cannot re-export package
程序入口
仓颉程序入口为 main,源文件根目录下的包的顶层最多只能有一个 main。
如果模块采用生成可执行文件的编译方式,编译器只在源文件根目录下的顶层查找 main。如果没有找到,编译器将会报错;如果找到 main,编译器会进一步对其参数和返回值类型进行检查。需要注意的是,main 不可被访问修饰符修饰,当一个包被导入时,包中定义的 main 不会被导入。
作为程序入口的 main 可以没有参数或参数类型为 Array<String>,返回值类型为 Unit 或整数类型。
没有参数的 main:
// main.cj
main(): Int64 { // Ok.
return 0
}
参数类型为 Array<String> 的 main:
// main.cj
main(args: Array<String>): Unit { // Ok.
for (arg in args) {
println(arg)
}
}
使用 cjc main.cj 编译完成后,通过命令行执行:./main Hello, World,将会得到如下输出:
Hello,
World
以下是一些错误示例:
// main.cj
main(): String { // Error, return type of 'main' is not 'Integer' or 'Unit'.
return ""
}
// main.cj
main(args: Array<Int8>): Int64 { // Error, 'main' cannot be defined with parameter whose type is not Array<String>.
return 0
}
// main.cj
// Error, multiple 'main's are found in source files.
main(args: Array<String>): Int32 {
return 0
}
main(): Int8 {
return 0
}
定义异常
异常是一类特殊的可以被程序员捕获并处理的错误,是程序执行时出现的一系列不正常行为的统称。例如,数组越界、除零错误、计算溢出、非法输入等。为了保证系统的正确性和健壮性,很多软件系统中都包含大量的代码用于错误检测和错误处理。
异常不属于程序的正常功能,一旦发生异常,要求程序必须立即处理,即将程序的控制权从正常功能的执行处转移至处理异常的部分。仓颉编程语言提供了异常处理机制,用于处理程序运行时可能出现的各种异常情况。
在仓颉语言中,异常类包括 Error 和 Exception:
Error类描述仓颉语言运行时,系统内部错误和资源耗尽错误。应用程序不应该抛出这种类型错误,如果出现内部错误,只能通知给用户,尽量安全终止程序。Exception类描述的是程序运行时的逻辑错误或者 IO 错误导致的异常,例如数组越界或者试图打开一个不存在的文件等,这类异常需要在程序中捕获处理。
开发者不可以通过继承仓颉语言内置的 Error 或其子类来自定义异常,但是可以继承内置的 Exception 或其子类来自定义异常,例如:
open class FatherException <: Exception {
public init() {
super("This is FatherException.")
}
public init(message: String) {
super(message)
}
public open override func getClassName(): String {
"FatherException"
}
}
class ChildException <: FatherException {
public init() {
super("This is ChildException.")
}
public open override func getClassName(): String {
"ChildException"
}
}
下表展示了 Exception 的主要函数及其说明:
| 函数种类 | 函数及说明 |
|---|---|
| 构造函数 | init() 默认构造函数。 |
| 构造函数 | init(message: String) 可以设置异常消息的构造函数。 |
| 成员属性 | open prop message: String 返回发生异常的详细信息。该消息在异常类构造函数中初始化,默认为空字符串。 |
| 成员函数 | open func toString(): String 返回异常类型名以及异常的详细信息,其中,异常的详细信息会默认调用 message。 |
| 成员函数 | func getClassName(): String 返回用户定义的类名,子类需要重写该方法以返回子类的名称。 |
| 成员函数 | func printStackTrace(): Unit 打印堆栈信息至标准错误流。 |
下表展示了 Error 的主要函数及其说明:
| 函数种类 | 函数及说明 |
|---|---|
| 成员属性 | open prop message: String 返回发生错误的详细信息。该消息在错误发生时,内部初始化,默认为空字符串。 |
| 成员函数 | open func toString(): String 返回错误类型名以及错误的详细信息,其中,错误的详细信息会默认调用 message。 |
| 成员函数 | func printStackTrace(): Unit 打印堆栈信息至标准错误流。 |
throw 和处理异常
上文介绍了如何自定义异常,接下来学习如何抛出和处理异常。
- 由于异常是
class类型,只需要按 class 对象的构建方式去创建异常即可。如表达式FatherException()即创建了一个类型为FatherException的异常。 - 仓颉语言提供
throw关键字,用于抛出异常。用throw来抛出异常时,throw之后的表达式必须是Exception的子类型(同为异常的Error不可以手动throw),如throw ArithmeticException("I am an Exception!")(被执行到时)会抛出一个算术运算异常。 throw关键字抛出的异常需要被捕获处理。若异常没有被捕获,则由系统调用默认的异常处理函数。
异常处理由 try 表达式完成,可分为:
- 不涉及资源自动管理的普通 try 表达式。
- 会进行资源自动管理 try-with-resources 表达式。
普通 try 表达式
普通 try 表达式包括三个部分:try 块,catch 块和 finally 块。
-
try 块,以关键字
try开始,后面紧跟一个由表达式与声明组成的块(用一对花括号括起来,定义了新的局部作用域,可以包含任意表达式和声明,后简称“块”),try 后面的块内可以抛出异常,并被紧随的 catch 块所捕获并处理(如果不存在 catch 块或未被捕获,则在执行完 finally 块后,该异常继续被抛出)。 -
catch 块,一个普通 try 表达式可以包含零个或多个 catch 块(当没有 catch 块时必须有 finally 块)。每个 catch 块以关键字
catch开头,后跟一条catchPattern和一个块,catchPattern通过模式匹配的方式匹配待捕获的异常。一旦匹配成功,则交由其后跟随的块进行处理,并且忽略它后面的其他 catch 块。当某个 catch 块可捕获的异常类型均可被定义在它前面的某个 catch 块所捕获时,会在此 catch 块处报“catch 块不可达”的 warning。 -
finally 块,以关键字
finally开始,后面紧跟一个块。原则上,finally 块中主要实现一些“善后”的工作,如释放资源等,且要尽量避免在 finally 块中再抛异常。并且无论异常是否发生(即无论 try 块中是否抛出异常),finally 块内的内容都会被执行(若异常未被处理,执行完 finally 块后,继续向外抛出异常)。一个 try 表达式在包含 catch 块时可以不包含 finally 块,否则必须包含 finally 块。
try 后面紧跟的块以及每个 catch 块的作用域互相独立。
注意:
当在 try 块中可能发生内存溢出错误时,应避免在 catch 或 finally 块中执行任何内存分配操作,以免再次触发溢出并导致未定义行为。一旦检测到内存溢出,建议在 catch 块中立即终止程序(例如调用
exit函数),以确保系统稳定性并防止进一步错误。
下面是一个只有 try 块和 catch 块的简单示例:
main() {
try {
throw NegativeArraySizeException("I am an Exception!")
} catch (e: NegativeArraySizeException) {
println(e)
println("NegativeArraySizeException is caught!")
}
println("This will also be printed!")
}
执行结果为:
NegativeArraySizeException: I am an Exception!
NegativeArraySizeException is caught!
This will also be printed!
catchPattern 中引入的变量作用域级别与 catch 后面的块中变量作用域级别相同,在 catch 块中再次引入相同名字会触发重定义错误。例如:
main() {
try {
throw NegativeArraySizeException("I am an Exception!")
} catch (e: NegativeArraySizeException) {
println(e)
let e = 0 // Error, redefinition
println(e)
println("NegativeArraySizeException is caught!")
}
println("This will also be printed!")
}
下面是带有 finally 块的 try 表达式的简单示例:
main() {
try {
throw NegativeArraySizeException("NegativeArraySizeException")
} catch (e: NegativeArraySizeException) {
println("Exception info: ${e}.")
} finally {
println("The finally block is executed.")
}
}
执行结果为:
Exception info: NegativeArraySizeException: NegativeArraySizeException.
The finally block is executed.
try 表达式可以出现在任何允许使用表达式的地方。try 表达式的类型的确定方式,与 if、match 表达式等多分支语法结构的类型的确定方式相似,为 finally 分支除外的所有分支的类型的最小公共父类型。例如下面代码中的 try 表达式和变量 x 的类型均为 E 和 D 的最小公共父类型 D;finally 分支中的 C() 并不参与公共父类型的计算(若参与,则最小公共父类型会变为 C)。
另外,当 try 表达式的值没有被使用时,其类型为 Unit,不要求各分支的类型有最小公共父类型。
open class C { }
open class D <: C { }
class E <: D { }
main () {
let x = try {
E()
} catch (e: Exception) {
D()
} finally {
C()
}
0
}
try-with-resources 表达式
try-with-resources 表达式主要是为了自动释放非内存资源。不同于普通 try 表达式,try-with-resources 表达式中的 catch 块和 finally 块均是可选的,并且 try 关键字其后的块之间可以插入一个或者多个 ResourceSpecification 用来申请一系列的资源(ResourceSpecification 并不会影响整个 try 表达式的类型)。这里所讲的资源对应到语言层面即指对象,因此 ResourceSpecification 其实就是实例化一系列的对象(多个实例化之间使用“,”分隔)。使用 try-with-resources 表达式的例子如下所示:
class Worker <: Resource {
var hasTools: Bool = false
let name: String
public init(name: String) {
this.name = name
}
public func getTools() {
println("${name} picks up tools from the warehouse.")
hasTools = true
}
public func work() {
if (hasTools) {
println("${name} does some work with tools.")
} else {
println("${name} doesn't have tools, does nothing.")
}
}
public func isClosed(): Bool {
if (hasTools) {
println("${name} hasn't returned the tool.")
false
} else {
println("${name} has no tools")
true
}
}
public func close(): Unit {
println("${name} returns the tools to the warehouse.")
hasTools = false
}
}
main() {
try (r = Worker("Tom")) {
r.getTools()
r.work()
}
try (r = Worker("Bob")) {
r.work()
}
try (r = Worker("Jack")) {
r.getTools()
throw Exception("Jack left, because of an emergency.")
}
}
程序输出结果为:
Tom picks up tools from the warehouse.
Tom does some work with tools.
Tom hasn't returned the tool.
Tom returns the tools to the warehouse.
Bob doesn't have tools, does nothing.
Bob has no tools
Jack picks up tools from the warehouse.
Jack hasn't returned the tool.
Jack returns the tools to the warehouse.
An exception has occurred:
Exception: Jack left, because of an emergency.
at test.main()(xxx/xx.cj:xx)
try 关键字和 {} 之间引入的名字,其作用域与 {} 中引入的变量作用域级别相同,在 {} 中再次引入相同名字会触发重定义错误。
class R <: Resource {
public func isClosed(): Bool {
true
}
public func close(): Unit {
print("R is closed")
}
}
main() {
try (r = R()) {
println("Get the resource")
let r = 0 // Error, redefinition
println(r)
}
}
try-with-resources 表达式中的 ResourceSpecification 的类型必须实现 Resource 接口:
interface Resource {
func isClosed(): Bool // 离开 try-with-resources 作用域时,判断是否需要调用 close 函数释放资源
func close(): Unit // 在 isClosed 返回 false 的场景下释放资源。
}
需要说明的是,try-with-resources 表达式中一般没有必要再包含 catch 块和 finally 块,也不建议开发者再手动释放资源(逻辑冗余)。但是,如果需要显式地捕获 try 块或资源申请和释放过程中可能抛出的异常并处理,仍可在 try-with-resources 表达式中包含 catch 块和 finally 块:
class R <: Resource {
public func isClosed(): Bool {
true
}
public func close(): Unit {
print("R is closed")
}
}
main() {
try (r = R()) {
println("Get the resource")
} catch (e: Exception) {
println("Exception happened when executing the try-with-resources expression")
} finally {
println("End of the try-with-resources expression")
}
}
程序输出结果如下:
Get the resource
End of the try-with-resources expression
try-with-resources 表达式的类型是 Unit。
CatchPattern 进阶介绍
大多数时候,只想捕获某一类型和其子类型的异常,这时候使用 CatchPattern 的类型模式来处理;但有时也需要所有异常做统一处理(如此处不该出现异常,出现了就统一报错),这时可以使用 CatchPattern 的通配符模式来处理。
类型模式在语法上有两种格式:
Identifier: ExceptionClass。此格式可以捕获类型为ExceptionClass及其子类的异常,并将捕获到的异常实例转换成ExceptionClass,然后与Identifier定义的变量进行绑定,接着就可以在 catch 块中通过 Identifier 定义的变量访问捕获到的异常实例。Identifier: ExceptionClass_1 | ExceptionClass_2 | ... | ExceptionClass_n。此格式可以通过连接符|将多个异常类进行拼接,连接符|表示“或”的关系:可以捕获类型为ExceptionClass_1及其子类的异常,或者捕获类型为ExceptionClass_2及其子类的异常,依次类推,或捕获类型为ExceptionClass_n及其子类的异常(假设 n 大于 1)。当待捕获异常的类型属于上述“或”关系中的任一类型或其子类型时,此异常将被捕获。但是由于无法静态地确定被捕获异常的类型,所以被捕获异常的类型会被转换成由|连接的所有类型的最小公共父类,并将异常实例与Identifier定义的变量进行绑定。因此在此类模式下,catch 块内只能通过Identifier定义的变量访问ExceptionClass_i(1 <= i <= n)的最小公共父类中的成员变量和成员函数。当然,也可以使用通配符代替类型模式中的Identifier,差别仅在于通配符不会进行绑定操作。
示例如下:
main(): Int64 {
try {
throw IllegalArgumentException("This is an Exception!")
} catch (e: OverflowException) {
println(e.message)
println("OverflowException is caught!")
} catch (e: IllegalArgumentException | NegativeArraySizeException) {
println(e.message)
println("IllegalArgumentException or NegativeArraySizeException is caught!")
} finally {
println("finally is executed!")
}
return 0
}
执行结果:
This is an Exception!
IllegalArgumentException or NegativeArraySizeException is caught!
finally is executed!
关于“被捕获异常的类型是由 | 连接的所有类型的最小公共父类”的示例:
open class Father <: Exception {
var father: Int32 = 0
}
class ChildOne <: Father {
var childOne: Int32 = 1
}
class ChildTwo <: Father {
var childTwo: Int32 = 2
}
main() {
try {
throw ChildOne()
} catch (e: ChildTwo | ChildOne) {
println("${e is Father}")
}
}
执行结果:
true
通配符模式的语法是 _,它可以捕获同级 try 块内抛出的任意类型的异常,等价于类型模式中的 e: Exception,即捕获 Exception 子类所定义的异常。示例如下:
// Catch with wildcardPattern.
try {
throw OverflowException()
} catch (_) {
println("catch an exception!")
}
常见运行时异常
在仓颉语言中内置了最常见的异常类,开发人员可以直接使用。
| 异常 | 描述 |
|---|---|
ConcurrentModificationException | 并发修改产生的异常 |
IllegalArgumentException | 传递不合法或不正确参数时抛出的异常 |
NegativeArraySizeException | 创建大小为负的数组时抛出的异常 |
NoneValueException | 值不存在时产生的异常,如 Map 中不存在要查找的 key |
OverflowException | 算术运算溢出异常 |
使用 Option
在 Option 类型中介绍了 Option 类型的定义,因为 Option 类型可以同时表示有值和无值两种状态,而无值在某些情况下也可以理解为一种错误,所以 Option 类型也可以用作错误处理。
例如,在下例中,如果函数 getOrThrow 的参数值等于 Some(v) 则将 v 的值返回,如果参数值等于 None 则抛出异常。
func getOrThrow(a: ?Int64) {
match (a) {
case Some(v) => v
case None => throw NoneValueException()
}
}
因为 Option 是一种非常常用的类型,所以仓颉为其提供了多种解构方式,以方便 Option 类型的使用,具体包括:模式匹配、getOrThrow 函数、coalescing 操作符(??),以及问号操作符(?)。下面将对这些方式逐一介绍。
-
模式匹配:因为 Option 类型是一种 enum 类型,所以可以使用上文提到的 enum 的模式匹配来实现对
Option值的解构。例如,下例中函数getString接受一个?Int64类型的参数,当参数是Some值时,返回其中数值的字符串表示,当参数是None值时,返回字符串"none"。func getString(p: ?Int64): String{ match (p) { case Some(x) => "${x}" case None => "none" } } main() { let a = Some(1) let b: ?Int64 = None let r1 = getString(a) let r2 = getString(b) println(r1) println(r2) }上述代码的执行结果为:
1 none -
coalescing操作符(??):对于?T类型的表达式e1,如果希望e1的值等于None时同样返回一个T类型的值e2,可以使用??操作符。对于表达式e1 ?? e2,当e1的值等于Some(v)时返回v的值,否则返回e2的值。举例如下:main() { let a = Some(1) let b: ?Int64 = None let r1: Int64 = a ?? 0 let r2: Int64 = b ?? 0 println(r1) println(r2) }上述代码的执行结果为:
1 0 -
问号操作符(
?):?需要和.或()或[]或{}(特指尾随 lambda 调用的场景)一起使用,用以实现Option类型对.,(),[]和{}的支持。以.为例((),[]和{}同理),对于?T1类型的表达式e,当e的值等于Some(v)时,e?.b的值等于Option<T2>.Some(v.b),否则e?.b的值等于Option<T2>.None,其中T2是v.b的类型。举例如下:struct R { public var a: Int64 public init(a: Int64) { this.a = a } } let r = R(100) let x = Some(r) let y = Option<R>.None let r1 = x?.a // r1 = Option<Int64>.Some(100) let r2 = y?.a // r2 = Option<Int64>.None class C { var item: Int64 = 100 } let c = C() let c1 = Option<C>.Some(c) let c2 = Option<C>.None func test1() { c1?.item = 200 // c.item = 200 c2?.item = 300 // no effect }问号操作符(
?)支持多层访问,以a?.b.c?.d为例((),[]和{}同理)。表达式a的类型需要是某个Option<T1>且T1包含实例成员b,b的类型中包含实例成员变量c且c的类型是某个Option<T2>,T2包含实例成员d;表达式a?.b.c?.d的类型为Option<T3>,其中T3是T2的实例成员d的类型;当a的值等于Some(va)且va.b.c的值等于Some(vc)时,a?.b.c?.d的值等于Option<T3>.Some(vc.d);当a的值等于Some(va)且va.b.c的值等于None时,a?.b.c?.d的值等于Option<T3>.None(d不会被求值);当a的值等于None时,a?.b.c?.d的值等于Option<T3>.None(b,c和d都不会被求值)。class A { public var b: B = B() } class B { public var c: Option<C> = C() public var c1: Option<C> = Option<C>.None } class C { public var d: Int64 = 100 } main(){ var a = Some(A()) let a1 = a?.b.c?.d // a1 = Option<Int64>.Some(100) let a2 = a?.b.c1?.d // a2 = Option<Int64>.None a?.b.c?.d = 200 // a.b.c.d = 200 a?.b.c1?.d = 200 // no effect } -
getOrThrow函数:对于?T类型的表达式e,可以通过调用getOrThrow函数实现解构。当e的值等于Some(v)时,getOrThrow()返回v的值,否则抛出异常。举例如下:main() { let a = Some(1) let b: ?Int64 = None let r1 = a.getOrThrow() println(r1) try { let r2 = b.getOrThrow() } catch (e: NoneValueException) { println("b is None") } }上述代码的执行结果为:
1 b is None
并发概述
并发编程是现代编程语言中不可或缺的特性,仓颉编程语言提供抢占式的线程模型作为并发编程机制。线程可以细分为两种不同概念,语言线程和 native 线程。
- 语言线程是编程语言中并发模型的基本执行单位。仓颉编程语言希望给开发者提供一个友好、高效、统一的并发编程界面,让开发者无需关心操作系统线程、用户态线程等差异,因此提供仓颉线程的概念。开发者在大多数情况下只需面向仓颉线程编写并发代码。
- native 线程指语言实现中所使用到的线程(一般是操作系统线程),它们作为语言线程的具体实现载体。不同编程语言会以不同的方式实现语言线程。例如,一些编程语言直接通过操作系统调用来创建线程,这意味着每个语言线程对应一个 native 线程,这种实现方案一般被称之为
1:1线程模型。此外,另有一些编程语言提供特殊的线程实现,它们允许多个语言线程在多个 native 线程上切换执行,这种也被称为M:N线程模型,即 M 个语言线程在 N 个 native 线程上调度执行,其中 M 和 N 不一定相等。当前,仓颉语言的实现同样采用M:N线程模型;因此,仓颉线程本质上是一种用户态的轻量级线程,支持抢占且相比操作系统线程更轻量化。
仓颉线程本质上是用户态的轻量级线程,每个仓颉线程都受到底层 native 线程的调度执行,并且多个仓颉线程可以由一个 native 线程执行。每个 native 线程会不断地选择一个就绪的仓颉线程完成执行,如果仓颉线程在执行过程中发生阻塞(例如等待互斥锁的释放),那么 native 线程会将当前的仓颉线程挂起,并继续选择下一个就绪的仓颉线程。发生阻塞的仓颉线程在重新就绪后会继续被 native 线程调度执行。
在大多数情况下,开发者只需要面向仓颉线程进行并发编程而不需要考虑这些细节。但在进行跨语言编程时,开发者需要谨慎调用可能发生阻塞的 foreign 函数,例如 IO 相关的操作系统调用等。例如,下列示例代码中的新线程会调用 foreign 函数 socket_read。在程序运行过程中,某一 native 线程将调度并执行该仓颉线程,在进入到 foreign 函数中后,系统调用会直接阻塞当前 native 线程直到函数执行完成。native 线程在阻塞期间将无法调度其他仓颉线程来执行,这会降低程序执行的吞吐量。
foreign socket_read(sock: Int64): CPointer<Int8>
let fut = spawn {
let sock: Int64 = ...
let ptr = socket_read(sock)
}
注意:
本文档在没有歧义的情况下将直接以线程简化对仓颉线程的指代。
创建线程
当开发者希望并发执行某一段代码时,只需创建一个仓颉线程即可。要创建一个新的仓颉线程,可以使用关键字 spawn 并传递一个无形参的 lambda 表达式,该 lambda 表达式即为在新线程中执行的代码。
下方示例代码中,主线程和新线程均会尝试打印一些文本:
main(): Int64 {
spawn { =>
println("New thread before sleeping")
sleep(100 * Duration.millisecond) // sleep for 100ms.
println("New thread after sleeping")
}
println("Main thread")
return 0
}
在上面的例子中,新线程会在主线程结束时一起停止,无论这个新线程是否已完成运行。上方示例的输出每次可能略有不同,有可能会输出类似如下的内容:
New thread before sleeping
Main thread
sleep() 函数会让当前线程睡眠指定的时长,之后再恢复执行,其时间由指定的 Duration 类型决定,详细介绍请参见线程睡眠指定时长章节。
访问线程
使用 Future<T> 等待线程结束并获取返回值
在上面的例子中,新创建的线程会由于主线程结束而提前结束,在缺乏顺序保证的情况下,甚至可能会出现新创建的线程还来不及得到执行就退出了。可以通过 spawn 表达式的返回值,来等待线程执行结束。
spawn 表达式的返回类型是 Future<T>,其中 T 是类型变元,其类型与 lambda 表达式的返回类型一致。当调用 Future<T> 的 get() 成员函数时,它将等待它的线程执行完成。
Future<T> 的原型声明如下:
public class Future<T> {
// Blocking the current thread, waiting for the result of the thread corresponding to the current Future object.
// If an exception occurs in the corresponding thread, the method will throw the exception.
public func get(): T
// Blocking the current thread, waiting for the result of the thread corresponding to the current Future object.
// If the corresponding thread has not completed execution within Duration, the method will throws TimeoutException.
// If `timeout` <= Duration.Zero, its behavior is the same as `get()`.
public func get(timeout: Duration): T
// Non-blocking method that immediately returns Option<T>.None if thread has not finished execution.
// Returns the computed result otherwise.
// If an exception occurs in the corresponding thread, the method will throw the exception.
public func tryGet(): Option<T>
}
下方示例代码演示了如何使用 Future<T> 在 main 中等待新创建的线程执行完成:
import std.sync.*
import std.time.*
main(): Int64 {
let fut: Future<Unit> = spawn { =>
println("New thread before sleeping")
sleep(100 * Duration.millisecond) // sleep for 100ms.
println("New thread after sleeping")
}
println("Main thread")
fut.get() // wait for the thread to finish.
return 0
}
调用 Future<T> 实例的 get() 会阻塞当前运行的线程,直到 Future<T> 实例所代表的线程运行结束。因此,上方示例有可能会输出类似如下内容:
New thread before sleeping
Main thread
New thread after sleeping
主线程在完成打印后会因为调用 get() 而等待新创建的线程执行结束。但主线程和新线程的打印顺序具有不确定性。
如果将 fut.get() 移动到主线程的打印之前,如下所示:
import std.sync.*
import std.time.*
main(): Int64 {
let fut: Future<Unit> = spawn { =>
println("New thread before sleeping")
sleep(100 * Duration.millisecond) // sleep for 100ms.
println("New thread after sleeping")
}
fut.get() // wait for the thread to finish.
println("Main thread")
return 0
}
主线程将等待新创建的线程执行完成,然后再执行打印,因此程序的输出将变得确定,如下所示:
New thread before sleeping
New thread after sleeping
Main thread
可见,get() 的调用位置会影响线程是否能同时运行。
Future<T> 除了可以用于阻塞等待线程执行结束以外,还可以获取线程执行的结果。如下是它提供的具体成员函数:
-
get(): T:阻塞等待线程执行结束,并返回执行结果,如果该线程已经结束,则直接返回执行结果。示例代码如下:
import std.sync.* import std.time.* main(): Int64 { let fut: Future<Int64> = spawn { sleep(Duration.second) // sleep for 1s. return 1 } try { // wait for the thread to finish, and get the result. let res: Int64 = fut.get() println("result = ${res}") } catch (_) { println("oops") } return 0 }输出结果如下:
result = 1 -
get(timeout: Duration): T:阻塞等待该Future<T>所代表的线程执行结束,并返回执行结果,当到达超时时间 timeout 时,如果该线程还没有执行结束,将会抛出异常 TimeoutException。如果timeout <= Duration.Zero, 其行为与get()相同。示例代码如下:
main(): Int64 { let fut = spawn { sleep(Duration.second) // sleep for 1s. return 1 } // wait for the thread to finish, but only for 1ms. try { let res = fut.get(Duration.millisecond * 1) println("result: ${res}") } catch (_: TimeoutException) { println("oops") } return 0 }输出结果如下:
oops
访问线程属性
每个 Future<T> 对象都有一个对应的仓颉线程,以 Thread 对象为表示。Thread 类主要被用于访问线程的属性信息,例如线程标识等。需要注意的是,Thread 无法直接被实例化构造对象,仅能从 Future<T> 的 thread 成员属性获取对应的 Thread 对象,或是通过 Thread 的静态成员属性 currentThread 得到当前正在执行线程对应的 Thread 对象。
Thread 类的部分方法定义如下(完整的方法描述可参考《仓颉编程语言库 API》)。
class Thread {
// Get the currently running thread
static prop currentThread: Thread
// Get the unique identifier (represented as an integer) of the thread object
prop id: Int64
// Check whether the thread has any cancellation request
prop hasPendingCancellation: Bool
}
下列示例代码在创建新线程后分别通过两种方式获取线程标识。由于主线程和新线程获取的是同一个 Thread 对象,所以他们能够打印出相同的线程标识。
main(): Unit {
let fut = spawn {
println("Current thread id: ${Thread.currentThread.id}")
}
println("New thread id: ${fut.thread.id}")
fut.get()
}
输出结果如下(其中线程 id 会变化,也可能为其他值):
New thread id: 1
Current thread id: 1
终止线程
可以通过 Future<T> 的 cancel() 方法向对应的线程发送终止请求,该方法不会停止线程执行。开发者需要使用 Thread 的 hasPendingCancellation 属性来检查线程是否存在终止请求。
一般而言,如果线程存在终止请求,那么开发者可以实施相应的线程终止逻辑。因此,如何终止线程都交由开发者自行处理,如果开发者忽略终止请求,那么线程继续执行直到正常结束。
示例代码如下:
import std.sync.SyncCounter
main(): Unit {
let syncCounter = SyncCounter(1)
let fut = spawn {
syncCounter.waitUntilZero() // block until the syncCounter becomes zero
if (Thread.currentThread.hasPendingCancellation) { // Check cancellation request
println("cancelled")
return
}
println("hello")
}
fut.cancel() // Send cancellation request
syncCounter.dec()
fut.get() // Join thread
}
输出结果如下:
cancelled
同步机制
在并发编程中,如果缺少同步机制来保护多个线程共享的变量,很容易会出现数据竞争问题(data race)。
仓颉编程语言提供三种常见的同步机制来确保数据的线程安全:原子操作、互斥锁和条件变量。
原子操作 Atomic
仓颉提供整数类型、Bool 类型和引用类型的原子操作。
其中整数类型包括: Int8、Int16、Int32、Int64、UInt8、UInt16、UInt32、UInt64。
整数类型的原子操作支持基本的读写、交换以及算术运算操作:
| 操作 | 功能 |
|---|---|
load | 读取 |
store | 写入 |
swap | 交换,返回交换前的值 |
compareAndSwap | 比较再交换,交换成功返回 true,否则返回 false |
fetchAdd | 加法,返回执行加操作之前的值 |
fetchSub | 减法,返回执行减操作之前的值 |
fetchAnd | 与,返回执行与操作之前的值 |
fetchOr | 或,返回执行或操作之前的值 |
fetchXor | 异或,返回执行异或操作之前的值 |
需要注意的是:
- 交换操作和算术操作的返回值是修改前的值。
- compareAndSwap 是判断当前原子变量的值是否等于 old 值,如果等于,则使用 new 值替换;否则不替换。
以 Int8 类型为例,对应的原子操作类型声明如下:
class AtomicInt8 {
public func load(): Int8
public func store(val: Int8): Unit
public func swap(val: Int8): Int8
public func compareAndSwap(old: Int8, new: Int8): Bool
public func fetchAdd(val: Int8): Int8
public func fetchSub(val: Int8): Int8
public func fetchAnd(val: Int8): Int8
public func fetchOr(val: Int8): Int8
public func fetchXor(val: Int8): Int8
}
上述每一种原子类型的方法都有一个对应的方法可以接收内存排序参数,目前内存排序参数仅支持顺序一致性。
类似的,其他整数类型对应的原子操作类型有:
class AtomicInt16 {...}
class AtomicInt32 {...}
class AtomicInt64 {...}
class AtomicUInt8 {...}
class AtomicUInt16 {...}
class AtomicUInt32 {...}
class AtomicUInt64 {...}
下方示例演示了如何在多线程程序中,使用原子操作实现计数:
import std.sync.*
import std.time.*
import std.collection.*
let count = AtomicInt64(0)
main(): Int64 {
let list = ArrayList<Future<Int64>>()
// create 1000 threads.
for (_ in 0..1000) {
let fut = spawn {
sleep(Duration.millisecond) // sleep for 1ms.
count.fetchAdd(1)
}
list.add(fut)
}
// Wait for all threads finished.
for (f in list) {
f.get()
}
let val = count.load()
println("count = ${val}")
return 0
}
输出结果应为:
count = 1000
以下是使用整数类型原子操作的一些其他正确示例:
var obj: AtomicInt32 = AtomicInt32(1)
var x = obj.load() // x: 1, the type is Int32
x = obj.swap(2) // x: 1
x = obj.load() // x: 2
var y = obj.compareAndSwap(2, 3) // y: true, the type is Bool.
y = obj.compareAndSwap(2, 3) // y: false, the value in obj is no longer 2 but 3. Therefore, the CAS operation fails.
x = obj.fetchAdd(1) // x: 3
x = obj.load() // x: 4
Bool 类型和引用类型的原子操作只提供读写和交换操作:
| 操作 | 功能 |
|---|---|
load | 读取 |
store | 写入 |
swap | 交换,返回交换前的值 |
compareAndSwap | 比较再交换,交换成功返回 true,否则返回 false |
注意:
引用类型原子操作只对引用类型有效。
原子引用类型是 AtomicReference,以下是使用 Bool 类型、引用类型原子操作的一些正确示例:
import std.sync.*
class A {}
main() {
var obj = AtomicBool(true)
var x1 = obj.load() // x1: true, the type is Bool
println(x1)
var t1 = A()
var obj2 = AtomicReference(t1)
var x2 = obj2.load() // x2 and t1 are the same object
var y1 = obj2.compareAndSwap(x2, t1) // x2 and t1 are the same object, y1: true
println(y1)
var t2 = A()
var y2 = obj2.compareAndSwap(t2, A()) // x and t1 are not the same object, CAS fails, y2: false
println(y2)
y2 = obj2.compareAndSwap(t1, A()) // CAS successes, y2: true
println(y2)
}
编译执行上述代码,输出结果为:
true
true
false
true
可重入互斥锁 Mutex
可重入互斥锁的作用是对临界区加以保护,使得任意时刻最多只有一个线程能够执行临界区的代码。当一个线程试图获取一个已被其他线程持有的锁时,该线程会被阻塞,直到锁被释放,该线程才会被唤醒,可重入是指线程获取该锁后可再次获得该锁。
使用可重入互斥锁时,必须牢记两条规则:
- 在访问共享数据之前,必须尝试获取锁;
- 处理完共享数据后,必须释放锁,以便其他线程可以获得锁。
Mutex 提供的主要成员函数如下:
public class Mutex <: UniqueLock {
// Create a Mutex.
public init()
// Locks the mutex, blocks if the mutex is not available.
public func lock(): Unit
// Unlocks the mutex. If there are other threads blocking on this
// lock, then wake up one of them.
public func unlock(): Unit
// Tries to lock the mutex, returns false if the mutex is not
// available, otherwise returns true.
public func tryLock(): Bool
// Generate a Condition instance for the mutex.
public func condition(): Condition
}
下方示例演示了如何使用 Mutex 来保护对全局共享变量 count 的访问,对 count 的操作即属于临界区:
import std.sync.*
import std.time.*
import std.collection.*
var count: Int64 = 0
let mtx = Mutex()
main(): Int64 {
let list = ArrayList<Future<Unit>>()
// create 1000 threads.
for (i in 0..1000) {
let fut = spawn {
sleep(Duration.millisecond) // sleep for 1ms.
mtx.lock()
count++
mtx.unlock()
}
list.add(fut)
}
// Wait for all threads finished.
for (f in list) {
f.get()
}
println("count = ${count}")
return 0
}
输出结果应为:
count = 1000
下方示例演示了如何使用 tryLock:
import std.sync.*
import std.time.*
main(): Int64 {
let mtx: Mutex = Mutex()
var future: Future<Unit> = spawn {
mtx.lock()
println("get the lock, do something")
sleep(Duration.millisecond * 10)
mtx.unlock()
}
try {
future.get(Duration.millisecond * 10)
} catch (e: TimeoutException) {
if (mtx.tryLock()) {
println("tryLock success, do something")
mtx.unlock()
return 0
}
println("tryLock failed, do nothing")
return 0
}
return 0
}
一种可能的输出结果如下:
get the lock, do something
以下是互斥锁的一些错误示例:
错误示例 1:线程操作临界区后没有解锁,导致其他线程无法获得锁而阻塞。
import std.sync.*
var sum: Int64 = 0
let mutex = Mutex()
main() {
let foo = spawn { =>
mutex.lock()
sum = sum + 1
}
let bar = spawn { =>
mutex.lock()
sum = sum + 1
}
foo.get()
println("${sum}")
bar.get() // Because the thread is not unlocked, other threads waiting to obtain the current mutex will be blocked.
}
错误示例 2:在本线程没有持有锁的情况下调用 unlock 将会抛出异常。
import std.sync.*
var sum: Int64 = 0
let mutex = Mutex()
main() {
let foo = spawn { =>
sum = sum + 1
mutex.unlock() // Error, Unlock without obtaining the lock and throw an exception: IllegalSynchronizationStateException.
}
foo.get()
0
}
错误示例 3:tryLock() 并不保证获取到锁,可能会造成不在锁的保护下操作临界区和在没有持有锁的情况下调用 unlock 抛出异常等行为。
import std.sync.*
var sum: Int64 = 0
let mutex = Mutex()
main() {
for (i in 0..100) {
spawn { =>
mutex.tryLock() // Error, `tryLock()` just trying to acquire a lock, there is no guarantee that the lock will be acquired, and this can lead to abnormal behavior.
sum = sum + 1
mutex.unlock()
}
}
}
另外,Mutex 在设计上是一个可重入锁,也就是说:在某个线程已经持有一个 Mutex 锁的情况下,再次尝试获取同一个 Mutex 锁,永远可以立即获得该 Mutex 锁。
注意:
虽然
Mutex是一个可重入锁,但是调用unlock()的次数必须和调用lock()的次数相同,才能成功释放该锁。
下方示例代码演示了 Mutex 可重入的特性:
import std.sync.*
import std.time.*
var count: Int64 = 0
let mtx = Mutex()
func foo() {
mtx.lock()
count += 10
bar()
mtx.unlock()
}
func bar() {
mtx.lock()
count += 100
mtx.unlock()
}
main(): Int64 {
let fut = spawn {
sleep(Duration.millisecond) // sleep for 1ms.
foo()
}
foo()
fut.get()
println("count = ${count}")
return 0
}
输出结果应为:
count = 220
在上方示例中,无论是主线程还是新创建的线程,如果在 foo() 中已经获得了锁,那么继续调用 bar() 的话,在 bar() 函数中由于是对同一个 Mutex 进行加锁,因此也是能立即获得该锁的,不会出现死锁。
Condition
Condition 是与某个互斥锁绑定的条件变量(也就是等待队列),Condition 实例由互斥锁创建,一个互斥锁可以创建多个 Condition 实例。Condition 可以使线程阻塞并等待来自另一个线程的信号以恢复执行。这是一种利用共享变量进行线程同步的机制,主要提供如下方法:
public class Mutex <: UniqueLock {
// ...
// Generate a Condition instance for the mutex.
public func condition(): Condition
}
public interface Condition {
// Wait for a signal, blocking the current thread.
func wait(): Unit
func wait(timeout!: Duration): Bool
// Wait for a signal and predicate, blocking the current thread.
func waitUntil(predicate: ()->Bool): Unit
func waitUntil(predicate: ()->Bool, timeout!: Duration): Bool
// Wake up one thread of those waiting on the monitor, if any.
func notify(): Unit
// Wake up all threads waiting on the monitor, if any.
func notifyAll(): Unit
}
调用 Condition 接口的 wait、notify 或 notifyAll 方法前,需要确保当前线程已经持有绑定的锁。wait 方法包含如下动作:
- 添加当前线程到对应锁的等待队列中;
- 阻塞当前线程,同时完全释放该锁,并记录锁的重入次数;
- 等待某个其他线程使用同一个
Condition实例的notify或notifyAll方法向该线程发出信号; - 当前线程被唤醒后,会自动尝试重新获取锁,且持有锁的重入状态与第 2 步记录的重入次数相同;但是如果尝试获取锁失败,则当前线程会阻塞在该锁上。
wait 方法接受一个可选参数 timeout。需要注意的是,业界很多常用的常规操作系统不保证调度的实时性,因此无法保证一个线程会被阻塞“精确的 N 纳秒”——可能会观察到与系统相关的不精确情况。此外,当前语言规范明确允许实现产生虚假唤醒——在这种情况下,wait 返回值是由实现决定的——可能为 true 或 false。因此鼓励开发者始终将 wait 包在一个循环中:
synchronized (obj) {
while (<condition is not true>) {
obj.wait()
}
}
以下是使用 Condition 的一个正确示例:
import std.sync.*
import std.time.*
let mtx = Mutex()
let condition = synchronized(mtx) {
mtx.condition()
}
var flag: Bool = true
main(): Int64 {
let fut = spawn {
mtx.lock()
while (flag) {
println("New thread: before wait")
condition.wait()
println("New thread: after wait")
}
mtx.unlock()
}
// Sleep for 10ms, to make sure the new thread can be executed.
sleep(10 * Duration.millisecond)
mtx.lock()
println("Main thread: set flag")
flag = false
mtx.unlock()
mtx.lock()
println("Main thread: notify")
condition.notifyAll()
mtx.unlock()
// wait for the new thread finished.
fut.get()
return 0
}
输出结果应为:
New thread: before wait
Main thread: set flag
Main thread: notify
New thread: after wait
Condition 对象执行 wait 时,必须在锁的保护下进行,否则 wait 中释放锁的操作会抛出异常。
以下是使用条件变量的一些错误示例:
import std.sync.*
let m1 = Mutex()
let c1 = synchronized(m1) {
m1.condition()
}
let m2 = Mutex()
var flag: Bool = true
var count: Int64 = 0
func foo1() {
spawn {
m2.lock()
while (flag) {
c1.wait() // Error:The lock used together with the condition variable must be the same lock and in the locked state. Otherwise, the unlock operation in `wait` throws an exception.
}
count = count + 1
m2.unlock()
}
m1.lock()
flag = false
c1.notifyAll()
m1.unlock()
}
func foo2() {
spawn {
while (flag) {
c1.wait() // Error:The `wait` of a conditional variable must be called with a lock held.
}
count = count + 1
}
m1.lock()
flag = false
c1.notifyAll()
m1.unlock()
}
main() {
foo1()
foo2()
c1.wait()
return 0
}
有时在复杂的线程间同步的场景下需要对同一个锁对象生成多个 Condition 实例,以下示例实现了一个长度固定的有界 FIFO 队列。当队列为空,get() 会被阻塞;当队列已满,put() 会被阻塞。
import std.sync.*
class BoundedQueue {
// Create a Mutex, two Conditions.
let m: Mutex = Mutex()
var notFull: Condition
var notEmpty: Condition
var count: Int64 // Object count in buffer.
var head: Int64 // Write index.
var tail: Int64 // Read index.
// Queue's length is 100.
let items: Array<Object> = Array<Object>(100, {i => Object()})
init() {
count = 0
head = 0
tail = 0
synchronized(m) {
notFull = m.condition()
notEmpty = m.condition()
}
}
// Insert an object, if the queue is full, block the current thread.
public func put(x: Object) {
// Acquire the mutex.
synchronized(m) {
while (count == 100) {
// If the queue is full, wait for the "queue notFull" event.
notFull.wait()
}
items[head] = x
head++
if (head == 100) {
head = 0
}
count++
// An object has been inserted and the current queue is no longer
// empty, so wake up the thread previously blocked on get()
// because the queue was empty.
notEmpty.notify()
} // Release the mutex.
}
// Pop an object, if the queue is empty, block the current thread.
public func get(): Object {
// Acquire the mutex.
synchronized(m) {
while (count == 0) {
// If the queue is empty, wait for the "queue notEmpty" event.
notEmpty.wait()
}
let x: Object = items[tail]
tail++
if (tail == 100) {
tail = 0
}
count--
// An object has been popped and the current queue is no longer
// full, so wake up the thread previously blocked on put()
// because the queue was full.
notFull.notify()
return x
} // Release the mutex.
}
}
synchronized 关键字
Lock 提供了一种便利灵活的加锁的方式,同时因为它的灵活性,也可能引起忘记解锁,或者在持有锁的情况下抛出异常不能自动释放持有的锁的问题。因此,仓颉编程语言提供一个 synchronized 关键字,搭配 Lock 一起使用,可以在其后跟随的作用域内自动进行加锁解锁操作,用来解决类似的问题。
下方示例代码演示了如何使用 synchronized 关键字来保护共享数据:
import std.sync.*
import std.time.*
import std.collection.*
var count: Int64 = 0
let mtx = Mutex()
main(): Int64 {
let list = ArrayList<Future<Unit>>()
// create 1000 threads.
for (i in 0..1000) {
let fut = spawn {
sleep(Duration.millisecond) // sleep for 1ms.
// Use synchronized(mtx), instead of mtx.lock() and mtx.unlock().
synchronized(mtx) {
count++
}
}
list.add(fut)
}
// Wait for all threads finished.
for (f in list) {
f.get()
}
println("count = ${count}")
return 0
}
输出结果应为:
count = 1000
通过在 synchronized 后面加上一个 Lock 实例,对其后面修饰的代码块进行保护,可以使得任意时刻最多只有一个线程可以执行被保护的代码:
- 一个线程在进入
synchronized修饰的代码块之前,会自动获取Lock实例对应的锁,如果无法获取锁,则当前线程被阻塞; - 一个线程在退出
synchronized修饰的代码块之前,会自动释放该Lock实例的锁。
对于控制转移表达式(如 break、continue、return、throw),在导致程序的执行跳出 synchronized 代码块时,也符合上面第 2 条的说明,也就说也会自动释放 synchronized 表达式对应的锁。
下方示例演示了在 synchronized 代码块中出现 break 语句的情况:
import std.sync.*
import std.collection.*
var count: Int64 = 0
var mtx: Mutex = Mutex()
main(): Int64 {
let list = ArrayList<Future<Unit>>()
for (i in 0..10) {
let fut = spawn {
while (true) {
synchronized(mtx) {
count = count + 1
break
println("in thread")
}
}
}
list.add(fut)
}
// Wait for all threads finished.
for (f in list) {
f.get()
}
synchronized(mtx) {
println("in main, count = ${count}")
}
return 0
}
输出结果应为:
in main, count = 10
实际上 in thread 这行不会被打印,因为 break 语句实际上会让程序执行跳出 while 循环(在跳出 while 循环之前,先跳出 synchronized 代码块)。
线程局部变量 ThreadLocal
使用 core 包中的 ThreadLocal 可以创建并使用线程局部变量,每一个线程都有它独立的一个存储空间来保存这些线程局部变量。因此,在每个线程可以安全地访问他们各自的线程局部变量,而不受其他线程的影响。
public class ThreadLocal<T> {
/* 构造一个携带空值的仓颉线程局部变量 */
public init()
/* 获得仓颉线程局部变量的值 */
public func get(): Option<T> // 如果值不存在,则返回 Option<T>.None。返回值 Option<T> - 仓颉线程局部变量的值
/* 通过 value 设置仓颉线程局部变量的值 */
public func set(value: Option<T>): Unit // 如果传入 Option<T>.None,该局部变量的值将被删除,在线程后续操作中将无法获取。参数 value - 需要设置的局部变量的值。
}
下方示例代码演示了如何通过 ThreadLocal类来创建并使用各自线程的局部变量:
main(): Int64 {
let tl = ThreadLocal<Int64>()
let fut1 = spawn {
tl.set(123)
println("tl in spawn1 = ${tl.get().getOrThrow()}")
}
let fut2 = spawn {
tl.set(456)
println("tl in spawn2 = ${tl.get().getOrThrow()}")
}
fut1.get()
fut2.get()
0
}
可能的输出结果如下:
tl in spawn1 = 123
tl in spawn2 = 456
或者
tl in spawn2 = 456
tl in spawn1 = 123
线程睡眠指定时长 sleep
sleep 函数会阻塞当前运行的线程,该线程会主动睡眠一段时间,之后再恢复执行,其参数类型为 Duration 类型。函数原型为:
func sleep(dur: Duration): Unit // Sleep for at least `dur`.
注意:
如果
dur<= Duration.Zero, 那么当前线程只会让出执行资源,并不会进入睡眠。
以下是使用 sleep 的示例:
import std.sync.*
import std.time.*
main(): Int64 {
println("Hello")
sleep(Duration.second) // sleep for 1s.
println("World")
return 0
}
输出结果如下:
Hello
World
I/O 流概述
本章介绍基本的 I/O 概念和文件操作。
仓颉编程语言将与应用程序外部载体交互的操作称为 I/O 操作。I 对应输入(Input),O 对应输出(Output)。
仓颉编程语言所有的 I/O 机制都是基于数据流进行输入输出,这些数据流表示了字节数据的序列。数据流是一串连续的数据集合,它就像承载数据的管道,在管道的一端输入数据,在管道的另一端就可以输出数据。
仓颉编程语言将输入输出抽象为流(Stream)。
- 将数据从外存中读取到内存中的称为输入流(InputStream),输入端可以一段一段地向管道中写入数据,这些数据段会按先后顺序形成一个长的数据流。
- 将数据从内存写入外存中的称为输出流(OutputStream),输出端也可以一段一段地从管道中读出数据,每次可以读取其中的任意长度的数据(不需要跟输入端匹配),但只能读取先输入的数据,再读取后输入的数据。
有了这一层抽象,仓颉编程语言就可以使用统一的接口来实现与外部数据的交互。
仓颉编程语言将标准输入输出、文件操作、网络数据流、字符串流、加密流、压缩流等等形式的操作,统一用 Stream 描述。
Stream 主要面向处理原始二进制数据,Stream 中最小的数据单元是 Byte。
仓颉编程语言将 Stream 定义成了 interface,它让不同的 Stream 可以用装饰器模式进行组合,极大地提升了可扩展性。
输入流
程序从输入流读取数据源(数据源包括外界的键盘、文件、网络等),即输入流是将数据源读入到程序的通信通道。
仓颉编程语言用 InputStream 接口类型来表示输入流,它提供了 read 函数,这个函数会将可读的数据写入到 buffer 中,返回值表示了该次读取的字节总数。
InputStream 接口定义:
interface InputStream {
func read(buffer: Array<Byte>): Int64
}
当拥有一个输入流的时候,就可以像下面的代码那样去读取字节数据,读取的数据会被写到 read 的入参数组中。
输入流读取示例:
import std.io.InputStream
main() {
let input: InputStream = ...
let buf = Array<Byte>(256, repeat: 0)
while (input.read(buf) > 0) {
println(buf)
}
}
输出流
程序向输出流写入数据。输出流是将程序中的数据输出到外界(显示器、打印机、文件、网络等)的通信通道。
仓颉编程语言用 OutputStream 接口类型来表示输出流,它提供了 write 函数,这个函数会将 buffer 中的数据写入到绑定的流中。
特别的,有一些输出流的 write 不会立即写到外存中,而是有一定的缓冲策略,只有当符合条件或主动调用 flush 时才会真实写入,目的是提高性能。
为了统一处理这些 flush 操作,在 OutputStream 中有一个 flush 的默认实现,它有助于抹平 API 调用的差异性。
OutputStream 接口定义:
interface OutputStream {
func write(buffer: Array<Byte>): Unit
func flush(): Unit {
// 空实现
}
}
当拥有一个输出流时,可以写入字节数据。
输出流写入示例:
import std.io.OutputStream
main() {
let output: OutputStream = ...
let buf = Array<Byte>(256, repeat: 111)
output.write(buf)
output.flush()
}
数据流分类
按照数据流职责上的差异,可以将 Stream 简单分成两类:
- 节点流:直接提供数据源,节点流的构造方式通常是依赖某种直接的外部资源(如文件、网络等)。
- 处理流:只能代理其他数据流进行处理,处理流的构造方式通常是依赖其他的流。
I/O 节点流
节点流是指直接提供数据源的流,节点流的构造方式通常是依赖某种直接的外部资源(如文件、网络等)。
仓颉编程语言中常见的节点流包含标准流(ConsoleReader、ConsoleWriter)、文件流(File)、网络流(Socket)等。
本章介绍标准流和文件流。
标准流
标准流包含标准输入流、标准输出流和标准错误输出流。
标准流是程序与外部数据交互的标准接口。程序运行的时候从输入流读取数据,作为程序的输入,程序运行过程中输出的信息被传送到输出流,类似的,错误信息被传送到错误流。
在仓颉编程语言中可以使用 getStdIn、getStdOut、getStdErr 全局函数来分别获取这三个标准流。
使用上面的函数需要导入 env 包:
导入 env 包示例:
import std.env.*
env 包内的 ConsoleReader 和 ConsoleWriter 类型对这三个标准流都进行了易用性封装(标准错误输出流也是输出流,所以一共是两个类型),提供了更方便的基于 String 的扩展操作,并且对于很多常见类型都提供了丰富的重载来优化性能。
其中最重要的是 ConsoleReader 和 ConsoleWriter 类型提供了并发安全的保证,可以在任意线程中安全地通过该类型提供的接口来读写内容。
默认情况下标准输入流来源于键盘输入的信息,例如在命令行界面中输入的文本。
当需要从标准输入流中获取数据时,可以通过 getStdIn 全局函数获取 ConsoleReader 类型,再通过该类型的 readln 函数获取命令行的输入。
标准输入流读取示例:
import std.env.*
main() {
let consoleReader = getStdIn()
let txt = consoleReader.readln()
println(txt ?? "")
}
运行上面的代码,在命令行上输入一些文字,然后换行结束,即可看到输入的内容。
输出流分为标准输出流和标准错误流,默认情况下,它们都会输出到屏幕,例如在命令行界面中看到的文本。
当需要往标准输出流中写入数据时,可以通过 getStdOut/getStdErr 全局函数获取 ConsoleWriter 来写入,例如通过 write 函数来向控制台打印内容。
使用 ConsoleWriter 和直接使用 print 函数的差别是,ConsoleWriter 是并发安全的,并且由于 ConsoleWriter 使用了缓存技术,在输入内容较多时拥有更好的性能表现。
需要注意的是,写完数据后需要对 ConsoleWriter 调用 flush 才能保证内容被完整写到标准流中。
标准输出流写入示例:
import std.env.*
main() {
let consoleWriter = getStdOut()
for (_ in 0..1000) {
consoleWriter.writeln("hello, world!")
}
consoleWriter.flush()
}
文件流
仓颉编程语言提供了 fs 包来支持通用文件系统任务。不同的操作系统对于文件系统提供的接口有所不同。仓颉编程语言抽象出以下一些共通的功能,通过统一的功能接口,屏蔽不同操作系统之间的差异,来简化使用。
常规操作任务包括:创建文件/目录、读写文件、重命名或移动文件/目录、删除文件/目录、复制文件/目录、获取文件/目录元数据、检查文件/目录是否存在。具体 API 可以查阅库文档。
使用文件系统相关的功能需要导入 fs 包:
导入 fs 包示例:
import std.fs.*
本章会着重介绍 File 相关的使用,对于 Path 和 Directory 的使用可以查阅对应的 API 文档。
File 类型在仓颉编程语言中同时提供了常规文件操作和文件流两类功能。
常规文件操作
对于常规的文件操作,可以使用一系列静态函数来完成快捷的操作。
例如如果要检查某个路径对应的文件是否存在,可以使用 exists 函数。当 exists 函数返回 true 时表示文件存在,反之不存在。
exists 函数使用示例:
import std.fs.*
main() {
let exist = exists("./tempFile.txt")
println("exist: ${exist}")
}
移动文件、拷贝文件和删除文件也非常简单,File 同样提供了对应的静态函数 move、copy、delete。
move、copy、delete 函数使用示例:
import std.fs.*
main() {
copy("./tempFile.txt", to: "./tempFile2.txt", overwrite: false)
rename("./tempFile2.txt", to: "./tempFile3.txt", overwrite: false)
remove("./tempFile3.txt")
}
如果需要直接将文件的所有数据读出来,或者一次性将数据写入文件里,可以使用 File 提供的 readFrom、writeTo 函数直接读写文件。在数据量较少的情况下它们既简单易用又能提供较好的性能表现,无需手动处理数据流。
readFrom、writeTo 函数使用示例:
import std.fs.*
main() {
let bytes = File.readFrom("./tempFile.txt") // 一次性读取了所有的数据
File.writeTo("./otherFile.txt", bytes) // 把数据一次性写入另一个文件中
}
文件流操作
除了上述的常规文件操作之外,File 类型也被设计为一种数据流类型,因此 File 类型本身实现了 IOStream 接口。当创建了一个 File 的实例,可以把这个实例当成数据流来使用。
File 类定义:
public class File <: Resource & IOStream & Seekable {
...
}
File 提供了两种构造方式,一种是通过方便的静态函数 create 直接创建新文件的实例,另一种是通过构造函数传入完整的打开文件模式来构造新实例。
其中 create 创建的文件是只写的,不能对实例进行读操作,否则会抛出运行时异常。
File 构造示例:
// 创建
internal import std.fs.*
internal import std.io.*
main() {
let file = File.create("./tempFile.txt")
file.write("hello, world!".toArray())
// 打开
let file2 = File("./tempFile.txt", Read)
let bytes = readToEnd(file2) // 读取所有数据
println(bytes)
}
当需要更精细的打开模式时,可以使用构造函数传入一个 OpenMode 值。OpenMode 是一个 enum 类型,它提供了丰富的文件打开模式,包含 Read、Write、Append 和 ReadWrite 模式。
File 打开模式使用示例:
// 使用指定选项打开模式
let file = File("./tempFile.txt", Write)
因为打开 File 的实例会占用宝贵的系统资源,所以使用完 File 的实例之后需要注意及时关闭 File,以释放系统资源。
File 实现了 Resource 接口,在大多数时候都可以使用 try-with-resource 语法来简化使用。
try-with-resource 语法使用示例:
try (file2 = File("./tempFile.txt", Read)) {
...
// 结束使用后自动释放文件
}
I/O 处理流
处理流是指代理其他数据流进行处理的流。
仓颉编程语言中常见的处理流包含 BufferedInputStream、BufferedOutputStream、StringReader、StringWriter、ChainedInputStream 等。
本章介绍缓冲流和字符串流。
缓冲流
由于涉及磁盘的 I/O 操作相比内存的 I/O 操作要慢很多,所以对于高频次且小数据量的读写操作来说,不带缓冲的数据流效率很低,每次读取和写入数据都会带来大量的 I/O 耗时。而带缓冲的数据流,可以多次读写数据,但不触发磁盘 I/O 操作,只是先放到内存里。等凑够了缓冲区大小的时候再一次性操作磁盘,这种方式可以显著减少磁盘操作次数,从而提升性能表现。
仓颉编程语言标准库提供了 BufferedInputStream 和 BufferedOutputStream 这两个类型用来提供缓冲功能。
使用 BufferedInputStream 和 BufferedOutputStream 类型需要导入 io 包。
导入 io 包示例:
import std.io.*
BufferedInputStream 的作用是为另一个输入流添加缓冲的功能。本质上 BufferedInputStream 是通过一个内部缓冲数组实现的。
当通过 BufferedInputStream 来读取流的数据时,BufferedInputStream 会一次性读取整个缓冲区大小的数据,再使用 read 函数就可以分多次读取更小规模的数据;当缓冲区中的数据被读完之后,输入流就会再次填充缓冲区;如此反复,直到读完数据流的所有数据。
如果构造一个 BufferedInputStream,只需要在构造函数中传入另一个输入流。如果需要指定缓冲区的大小,也可以额外传入 capacity 参数进行指定。
BufferedInputStream 构造示例:
import std.io.{ByteBuffer, BufferedInputStream}
main(): Unit {
let arr1 = "0123456789".toArray()
let byteBuffer = ByteBuffer()
byteBuffer.write(arr1)
let bufferedInputStream = BufferedInputStream(byteBuffer)
let arr2 = Array<Byte>(20, repeat: 0)
/* 读取流中数据,返回读取到的数据的长度 */
let readLen = bufferedInputStream.read(arr2)
println(String.fromUtf8(arr2[..readLen])) // 0123456789
}
BufferedOutputStream 的作用是为另一个输出流添加缓冲的功能。BufferedOutputStream 也是通过一个内部缓冲数组实现的。
当通过 BufferedOutputStream 来向输出流写入数据时,write 的数据会先写入内部缓冲数组中;当缓冲区中的数据被填满之后,BufferedOutputStream 会将缓冲区的数据一次性写入输出流中,然后清空缓冲区再次被写入;如此反复,直到写完所有的数据。
需要注意的是,由于没写够缓冲区时不会触发输出流的写入操作,所以当往 BufferedOutputStream 写完所有的数据后,需要额外调用 flush 函数来最终完成写入。
如果构造一个 BufferedOutputStream,只需要在构造函数中传入另一个输出流。如果需要指定缓冲区的大小,也可以额外传入 capacity 参数指定。
BufferedOutputStream 构造示例:
import std.io.*
main(): Unit {
let arr1 = "01234".toArray()
let byteBuffer = ByteBuffer()
byteBuffer.write(arr1)
let bufferedOutputStream = BufferedOutputStream(byteBuffer)
let arr2 = "56789".toArray()
/* 向流中写入数据,此时数据在外部流的缓冲区中 */
bufferedOutputStream.write(arr2)
/* 调用 flush 函数,真正将数据写入内部流中 */
bufferedOutputStream.flush()
println(String.fromUtf8(readToEnd(byteBuffer))) // 0123456789
}
字符串流
由于仓颉编程语言的输入流和输出流是基于字节数据来抽象的(拥有更好的性能),在部分以字符串为主的场景中使用起来不太友好,例如往文件里写入大量的文本内容时,需要将文本内容转换成字节数据,再写入文件。
为了提供友好的字符串操作能力,仓颉编程语言提供了 StringReader 和 StringWriter 来添加字符串处理能力。
使用 StringReader 和 StringWriter 类型需要导入 io 包:
导入 io 包示例:
import std.io.*
StringReader 提供了按行读、按筛选条件读的能力,相比将字节数据读出来再手动转换成字符串,具有更好的性能表现和易用性。
如果构造 StringReader,传入另一个输入流即可。
StringReader 使用示例:
import std.io.*
main(): Unit {
let arr1 = "012\n346789".toArray()
let byteBuffer = ByteBuffer()
byteBuffer.write(arr1)
let stringReader = StringReader(byteBuffer)
/* 读取一行数据 */
let line = stringReader.readln()
println(line ?? "error") // 012
}
StringWriter 提供了直接写字符串、按行直接写字符串的能力,相比将字节数据手动转换成字符串再写入,具有更好的性能表现和易用性。
如果构造 StringWriter,传入另一个输出流即可。
StringWriter 使用示例:
import std.io.*
main(): Unit {
let byteBuffer = ByteBuffer()
let stringWriter = StringWriter(byteBuffer)
/* 写入字符串 */
stringWriter.write("number")
/* 写入字符串并自动转行 */
stringWriter.writeln(" is:")
/* 写入数字 */
stringWriter.write(100.0f32)
stringWriter.flush()
println(String.fromUtf8(readToEnd(byteBuffer))) // number is:\n100.000000
}
网络编程概述
网络通信是两个设备通过计算机网络进行数据交换的过程。通过编写软件达成网络通信的行为即为网络编程。
仓颉为开发者提供了基础的网络编程功能,在仓颉标准库中,开发者可使用 std 模块下的 socket 包来实现传输层网络通信。
在传输层协议中,分为不可靠传输和可靠传输两种,仓颉将其抽象为 DatagramSocket 和 StreamSocket。其中不可靠传输协议常见的是 UDP,可靠传输协议常见的是 TCP,仓颉分别将其抽象为 UdpSocket 和 TcpSocket。另外,仓颉也实现了对传输层 Unix Domain 协议的支持,并支持其通过可靠和不可靠传输两种方式进行通信。
而在应用层协议中,较为常见的是 HTTP 协议,常用于开发 Web 应用程序等。当前 HTTP 协议已有多个版本,仓颉目前支持 HTTP/1.0、HTTP/1.1、HTTP/2.0。
另外,WebSocket 作为一种提升 Web 服务端与客户端间的通信效率的应用层协议,仓颉将其抽象为 WebSocket 对象,并支持从 HTTP 协议升级至 WebSocket 协议。
需要注意的是,仓颉的网络编程是阻塞式的。但被阻塞的是仓颉线程,阻塞中的仓颉线程会将系统线程让渡出去,因此并不会真正阻塞一个系统线程。
Socket 编程
仓颉的 Socket 编程指的是基于传输层协议实现网络传输数据包的功能。
在可靠传输场景下,仓颉分别启动客户端套接字和服务端套接字。客户端套接字必须指定将要连接的远端地址,可选择性地绑定本端地址,在连接成功后,才可以收发报文。而服务端套接字必须绑定本端地址,在绑定成功后,才可以收发报文。
在不可靠传输场景下,套接字无需区分客户端和服务端,仓颉分别启动两个套接字进行数据传输。套接字必须绑定本端地址,绑定成功后,才可以收发报文。并且,套接字也可选择性地指定远端连接地址,指定后将仅接受指定的远端地址的报文,同时在 send 时无需指定远端地址,报文将发送至成功连接的地址。
TCP 编程
TCP 作为一种常见的可靠传输协议,以 TCP 类型套接字举例,仓颉在可靠传输场景下的可参考的编程模型如下:
- 创建服务端套接字,并指定本端绑定地址。
- 执行绑定。
- 执行 accept 动作,将阻塞等待,直到获取到一个客户端套接字连接。
- 同步创建客户端套接字,并指定远端的待连接的地址。
- 执行连接。
- 连接成功后,服务端会在 accept 接口返回一个新的套接字,此时服务端可以通过此套接字进行读写操作,即收发报文。客户端则可以直接进行读写操作。
TCP 服务端和客户端程序示例如下:
import std.time.*
import std.sync.*
import std.net.*
var SERVER_PORT: UInt16 = 0
func runTcpServer() {
try (serverSocket = TcpServerSocket(bindAt: SERVER_PORT)) {
serverSocket.bind()
SERVER_PORT = (serverSocket.localAddress as IPSocketAddress)?.port ?? 0
try (client = serverSocket.accept()) {
let buf = Array<Byte>(10, repeat: 0)
let count = client.read(buf)
// 服务端读取到的数据为: [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]
println("Server read ${count} bytes: ${buf}")
}
}
}
main(): Int64 {
let future = spawn {
runTcpServer()
}
sleep(Duration.millisecond * 500)
try (socket = TcpSocket("127.0.0.1", SERVER_PORT)) {
socket.connect()
socket.write([1, 2, 3])
}
future.get()
return 0
}
编译执行上述代码,将打印:
Server read 3 bytes: [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]
UDP 编程
UDP 作为一种常见的不可靠传输协议,以 UDP 类型套接字举例,仓颉在不可靠传输场景下的可参考的编程模型如下:
- 创建套接字,并指定本端绑定地址。
- 执行绑定。
- 指定远端地址进行报文发送。
- 不连接远端地址场景下,可以收取来自不同远端地址的报文,并返回远端地址信息。
UDP 收发报文程序示例如下:
import std.time.*
import std.sync.*
import std.net.*
let SERVER_PORT: UInt16 = 8080
func runUpdServer() {
try (serverSocket = UdpSocket(bindAt: SERVER_PORT)) {
serverSocket.bind()
let buf = Array<Byte>(3, repeat: 0)
let (clientAddr, count) = serverSocket.receiveFrom(buf)
let sender = (clientAddr as IPSocketAddress)?.address.toString() ?? ""
// Server receive 3 bytes: [1, 2, 3] from 127.0.0.1
println("Server receive ${count} bytes: ${buf} from ${sender}")
}
}
main(): Int64 {
let future = spawn {
runUpdServer()
}
sleep(Duration.second)
try (udpSocket = UdpSocket(bindAt: 0)) {
udpSocket.sendTimeout = Duration.second * 2
udpSocket.bind()
udpSocket.sendTo(
IPSocketAddress("127.0.0.1", SERVER_PORT),
[1, 2, 3]
)
}
future.get()
return 0
}
编译执行上述代码,将打印:
Server receive 3 bytes: [1, 2, 3] from 127.0.0.1
HTTP 编程
HTTP 作为一种通用的应用层协议,通过请求-响应的机制实现数据传输,客户端发送请求,服务端返回响应。请求和响应的格式是固定的,由报文头和报文体组成。
常用的请求类型为 GET 和 POST,GET 请求只有报文头,用于向服务器请求应用层数据,POST 请求带有报文体,以一个空行与报文头进行分隔,用于向服务器提供应用层数据。
请求-响应的报文头字段内容较多,此处不再一一赘述,仓颉支持 HTTP 1.0/1.1/2.0 等协议版本,开发者可以基于协议 RFC 9110、9112、9113、9218、7541 以及仓颉所提供的 HttpRequestBuilder 和 HttpResponseBuilder 类构造请求及响应报文。
以下示例展示了如何使用仓颉进行客户端和服务端编程,实现的功能是客户端发送请求头为 GET /hello 的请求,服务端返回响应,响应体为 "Hello Cangjie!",代码如下:
说明:
net、log 等库已从仓颉 SDK 移到 stdx 模块,使用前需要下载软件包,并在 cjpm.toml 中配置。
import stdx.net.http.*
import std.time.*
import std.sync.*
import stdx.log.*
// 1. 构建 Server 实例
let server = ServerBuilder()
.addr("127.0.0.1")
.port(0)
.build()
func startServer(): Unit {
// 2. 注册请求处理逻辑
server.distributor.register("/hello", {httpContext =>
httpContext.responseBuilder.body("Hello Cangjie!")
})
server.logger.level = LogLevel.OFF
// 3. 启动服务
server.serve()
}
func startClient(): Unit {
// 1. 构建 client 实例
let client = ClientBuilder().build()
// 2. 发送 request
let response = client.get("http://127.0.0.1:${server.port}/hello")
// 3. 读取response body
let buffer = Array<Byte>(32, repeat: 0)
let length = response.body.read(buffer)
println(String.fromUtf8(buffer[..length]))
// 4. 关闭连接
client.close()
}
main () {
spawn {
startServer()
}
sleep(Duration.second)
startClient()
}
编译执行上述代码,将打印:
Hello Cangjie!
WebSocket 编程
在网络编程中,WebSocket 是一种常用的应用层协议。与 HTTP 一样,它也基于 TCP 协议之上,并且常用于 web 服务端应用开发。
不同于 HTTP 的是, WebSocket 只需要客户端和服务端进行一次握手,即可创建长久的连接,并且进行双向的数据传输。即基于 WebSocket 实现的服务端可以主动传输数据给客户端,从而实现实时通讯。
WebSocket 是一个独立的协议,它与 HTTP 的关联在于,它的握手被 HTTP 服务端解释为一个升级请求。因此,仓颉将 WebSocket 包含在 http 包中。
仓颉将 WebSocket 协议通信机制抽象为 WebSocket 类,提供方法将一个 http/1.1 或 http/2.0 服务端句柄升级到 WebSocket 协议实例,通过返回的 WebSocket 实例进行 WebSocket 通信,例如数据报文的读写。
在仓颉中,WebSocket 所传输的数据基本单元称为帧,帧分为两类,一类为传输控制信息的帧,即 Close Frame 用于关闭连接, Ping Frame 用于实现 Keep-Alive , Pong Frame 是 Ping Frame 的响应类型,另一类是传输应用数据的帧,应用数据帧支持分段传输。
仓颉的帧由三个属性构成,其中 fin 和 frameType 共同说明了帧是否分段和帧的类型,payload 为帧的载荷,除此之外开发者无需关心其他属性即可进行报文传输。
如下示例展示了 WebSocket 的握手以及消息收发过程:创建 HTTP 客户端和服务端,分别发起 WebSocket 升级(或握手),握手成功后开始帧的读写。
说明:
net、encoding、log 等库已从仓颉 SDK 移到 stdx 模块,使用前需要下载软件包,并在 cjpm.toml 中配置。
import stdx.net.http.*
import stdx.encoding.url.*
import std.time.*
import std.sync.*
import std.collection.*
import stdx.log.*
let server = ServerBuilder()
.addr("127.0.0.1")
.port(0)
.build()
// client:
main() {
// 1 启动服务器
spawn { startServer() }
sleep(Duration.millisecond * 200)
let client = ClientBuilder().build()
let u = URL.parse("ws://127.0.0.1:${server.port}/webSocket")
let subProtocol = ArrayList<String>(["foo1", "bar1"])
let headers = HttpHeaders()
headers.add("test", "echo")
// 2 完成 WebSocket 握手,获取 WebSocket 实例
let websocket: WebSocket
let respHeaders: HttpHeaders
(websocket, respHeaders) = WebSocket.upgradeFromClient(client, u, subProtocols: subProtocol, headers: headers)
client.close()
println("subProtocol: ${websocket.subProtocol}") // fool1
println(respHeaders.getFirst("rsp") ?? "") // echo
// 3 消息收发
// 发送 hello
websocket.write(TextWebFrame, "hello".toArray())
// 收
let data = ArrayList<UInt8>()
var frame = websocket.read()
while(true) {
match(frame.frameType) {
case ContinuationWebFrame =>
data.add(all: frame.payload)
if (frame.fin) {
break
}
case TextWebFrame | BinaryWebFrame =>
if (!data.isEmpty()) {
throw Exception("invalid frame")
}
data.add(all: frame.payload)
if (frame.fin) {
break
}
case CloseWebFrame =>
websocket.write(CloseWebFrame, frame.payload)
break
case PingWebFrame =>
websocket.writePongFrame(frame.payload)
case _ => ()
}
frame = websocket.read()
}
println("data size: ${data.size}") // 4097
println("last item: ${String.fromUtf8(data.toArray()[4096])}") // a
// 4 关闭 websocket,
// 收发 CloseFrame
websocket.writeCloseFrame(status: 1000)
let websocketFrame = websocket.read()
println("close frame type: ${websocketFrame.frameType}") // CloseWebFrame
println("close frame payload: ${websocketFrame.payload}") // 3, 232
// 关闭底层连接
websocket.closeConn()
server.close()
}
func startServer() {
// 1 注册 handler
server.distributor.register("/webSocket", handler1)
server.logger.level = LogLevel.OFF
server.serve()
}
// server:
func handler1(ctx: HttpContext): Unit {
// 2 完成 websocket 握手,获取 websocket 实例
let websocketServer = WebSocket.upgradeFromServer(ctx, subProtocols: ArrayList<String>(["foo", "bar", "foo1"]),
userFunc: {request: HttpRequest =>
let value = request.headers.getFirst("test") ?? ""
let headers = HttpHeaders()
headers.add("rsp", value)
headers
})
// 3 消息收发
// 收 hello
let data = ArrayList<UInt8>()
var frame = websocketServer.read()
while(true) {
match(frame.frameType) {
case ContinuationWebFrame =>
data.add(all: frame.payload)
if (frame.fin) {
break
}
case TextWebFrame | BinaryWebFrame =>
if (!data.isEmpty()) {
throw Exception("invalid frame")
}
data.add(all: frame.payload)
if (frame.fin) {
break
}
case CloseWebFrame =>
websocketServer.write(CloseWebFrame, frame.payload)
break
case PingWebFrame =>
websocketServer.writePongFrame(frame.payload)
case _ => ()
}
frame = websocketServer.read()
}
println("data: ${String.fromUtf8(data.toArray())}") // hello
// 发 4097 个 a
websocketServer.write(TextWebFrame, Array<UInt8>(4097, repeat: 97))
// 4 关闭 websocket,
// 收发 CloseFrame
let websocketFrame = websocketServer.read()
println("close frame type: ${websocketFrame.frameType}") // CloseWebFrame
println("close frame payload: ${websocketFrame.payload}") // 3, 232
websocketServer.write(CloseWebFrame, websocketFrame.payload)
// 关闭底层连接
websocketServer.closeConn()
}
该示例运行结果如下:
subProtocol: foo1
echo
data: hello
data size: 4097
last item: a
close frame type: CloseWebFrame
close frame payload: [3, 232]
close frame type: CloseWebFrame
close frame payload: [3, 232]
宏的简介
宏可以理解为一种特殊的函数。一般的函数在输入的值上进行计算,然后输出一个新的值,而宏的输入和输出都是程序本身。在输入一段程序后,输出一段新的程序,这段输出的程序随后用于编译和执行。为了把宏的调用和函数调用区分开来,在调用宏时需使用 @ 加上宏的名称。
如下示例代码希望实现在调试过程中打印某个表达式的值,同时打印出表达式本身。
let x = 3
let y = 2
@dprint(x) // 打印 "x = 3"
@dprint(x + y) // 打印 "x + y = 5"
显然,dprint 不能被写为常规的函数,因为函数只能获得输入表达式的值,不能获得输入表达式本身。但是,可以将 dprint 实现为一个宏来获取输入表达式的程序片段。一个基本的实现如下:
macro package define
import std.ast.*
public macro dprint(input: Tokens): Tokens {
let inputStr = input.toString()
let result = quote(
print($(inputStr) + " = ")
println($(input)))
return result
}
在解释每行代码之前,先测试这个宏可以达到预期的效果。首先,在当前目录下创建一个 define 文件夹,并在 define 文件夹中创建 dprint.cj 文件,将以上内容复制到 dprint.cj 文件中。另外在当前目录下创建 main.cj,包含以下测试代码:
import define.*
main() {
let x = 3
let y = 2
@dprint(x)
@dprint(x + y)
}
请注意,得到的目录结构如下:
// Directory layout.
src
|-- define
| `-- dprint.cj
`-- main.cj
在当前目录(src)下,运行编译命令:
cjc define/*.cj --compile-macro
cjc main.cj -o main
然后运行 ./main,可以看到如下输出:
x = 3
x + y = 5
依次查看代码的每个部分:
-
第 1 行:
macro package define宏必须声明在独立的包中(不能和其他 public 函数一起),含有宏的包使用
macro package来声明。这里声明了一个名为define的宏包。 -
第 2 行:
import std.ast.*实现宏需要的数据类型,例如
Tokens和后面会讲到的语法节点类型,位于仓颉标准库的ast包中,因此任何宏的实现都需要首先引入ast包。 -
第 3 行:
public macro dprint(input: Tokens): Tokens在这里声明一个名为
dprint的宏。由于这个宏是一个非属性宏(之后会解释这个概念),它接受一个类型为Tokens的参数。该输入代表传给宏的程序片段。宏的返回值也是一个程序片段。 -
第 4 行:
let inputStr = input.toString()在宏的实现中,首先将输入的程序片段转化为字符串。在前面的测试案例中,
inputStr成为"x"或"x + y" -
第 5-7 行:
let result = quote(...)这里
quote表达式是用于构造Tokens的一种表达式,它将括号内的程序片段转换为Tokens。在quote的输入中,可以使用插值$(...)来将括号内的表达式转换为Tokens,然后插入到quote构建的Tokens中。对于以上代码,$(inputStr)中插入了inputStr字符串的值(包含字符串两端的引号),$(input)中插入了input,即输入的程序片段。因此,如果输入的表达式是x + y,那么形成的Tokens为:print("x + y" + " = ") println(x + y) -
第 8 行:
return result最后,将构造出来的代码片段返回,这两行代码片段将被编译,运行时将输出
x + y = 5。
回顾 dprint 宏的定义,dprint 使用 Tokens 作为入参,并使用 quote 和插值构造了另一个 Tokens 作为返回值。为了使用宏,需要详细了解 Tokens、quote 和插值的概念,下面将分别介绍它们。
Tokens 相关类型和 quote 表达式
Token 类型
宏操作的基本类型是 Tokens,代表一个程序片段。Tokens 由若干个 Token 组成,每个 Token 可以理解为用户可操作的词法单元。一个 Token 可能是一个标识符(例如变量名等)、字面量(例如整数、浮点数、字符串)、关键字或运算符。每个 Token 包含它的类型、内容和位置信息。
Token 的类型取值为 enum TokenKind 中的元素。TokenKind 的可用值详见《仓颉编程语言库 API》文档。通过提供 TokenKind 和 Token 的值(TokenKind 对应的标识符或字面量),可以直接构造任何 Token。具体的构造函数如下:
Token(k: TokenKind)
Token(k: TokenKind, v: String)
下面给出一些Token构造的例子:
import std.ast.*
let tk1 = Token(TokenKind.ADD) // '+' 运算符
let tk2 = Token(TokenKind.FUNC) // func 关键字
let tk3 = Token(TokenKind.IDENTIFIER, "x") // x 标识符
let tk4 = Token(TokenKind.INTEGER_LITERAL, "3") // 整数字面量
let tk5 = Token(TokenKind.STRING_LITERAL, "xyz") // 字符串字面量
Tokens 类型
一个 Tokens 代表由多个 Token 组成的序列。可以通过 Token 数组直接构造 Tokens。下面是 3 种基本的构造 Tokens 实例的方式:
Tokens() // 构造空列表
Tokens(tks: Array<Token>)
Tokens(tks: ArrayList<Token>)
此外,Tokens 类型支持以下功能:
size:返回Tokens中包含Token的数量get(index: Int64):获取指定下标的Token元素[]:获取指定下标的Token元素+:拼接两个Tokens,或者直接拼接Tokens和Tokendump():打印包含的所有Token,供调试使用toString():打印Tokens对应的程序片段
在下面的案例中,使用构造函数直接构造 Token 和 Tokens,然后打印详细的调试信息:
import std.ast.*
let tks = Tokens([
Token(TokenKind.INTEGER_LITERAL, "1"),
Token(TokenKind.ADD),
Token(TokenKind.INTEGER_LITERAL, "2")
])
main() {
println(tks)
tks.dump()
}
预期输出如下(具体的位置信息可能不同):
1 + 2
description: integer_literal, token_id: 140, token_literal_value: 1, fileID: 1, line: 4, column: 5
description: add, token_id: 12, token_literal_value: +, fileID: 1, line: 5, column: 5
description: integer_literal, token_id: 140, token_literal_value: 2, fileID: 1, line: 6, column: 5
在 dump 信息中,包含了每个 Token 的类型(description)和值(token_literal_value),最后打印每个 Token 的位置信息。
quote 表达式和插值
在大多数情况下,直接构造和拼接 Tokens 会比较繁琐。因此,仓颉语言提供了 quote 表达式来从代码模板构造 Tokens。之所以说是代码模板,因为在 quote 中可以使用 $(...) 来插入上下文中的表达式。插入的表达式的类型需要支持被转换为 Tokens(具体来说,实现了 ToTokens 接口)。在标准库中,以下类型实现了 ToTokens 接口:
- 所有的节点类型(节点将在语法节点中讨论)
Token和Tokens类型- 所有基础数据类型:整数、浮点数、
Bool、Rune和String Array<T>和ArrayList<T>,这里对T的类型有限制,并根据T的类型不同,输出不同的分隔符,详细请见《仓颉编程语言库 API》文档。
下面的例子展示 Array 和基础数据类型的插值:
import std.ast.*
let intList: Array<Int64> = [1, 2, 3, 4, 5]
let float: Float64 = 1.0
let str: String = "Hello"
let tokens = quote(
arr = $(intList)
x = $(float)
s = $(str)
)
main() {
println(tokens)
}
输出结果是:
arr =[1, 2, 3, 4, 5]
x = 1.0
s = "Hello"
更多插值的用法可以参考 使用 quote 插值语法节点。
特别地,当 quote 表达式包含某些特殊 Token 时,需要进行转义:
quote表达式中不允许出现不匹配的小括号,但是通过\转义的小括号,不计入小括号的匹配规则。- 当
$表示一个普通Token,而非用于代码插值时,需要通过\进行转义。 - 除以上情况外,
quote表达式中出现\会编译报错。
注意:
#符号仅能用于构造多行原始字符串字面量,不支持单独使用。
下面是一些 quote 表达式内包含这些特殊 Token 的例子:
import std.ast.*
let tks1 = quote((x)) // ok
let tks2 = quote(\() // ok
let tks3 = quote( ( \) ) ) // ok
let tks4 = quote()) // error: unmatched delimiter: ')'
let tks5 = quote( ( \) ) // error: unclosed delimiter: '('
let tks6 = quote(\$(1)) // ok
let tks7 = quote(\x) // error: unknown start of token: \
let tks8 = quote(#) // error: expected '#' or '"' in raw string
语法节点
在仓颉语言的编译过程中,首先通过词法分析将代码转换成 Tokens,然后对 Tokens 进行语法解析,得到一个语法树。每个语法树的节点可能是一个表达式、声明、类型、模式等。仓颉标准库 std.ast 包提供了每种节点对应的类,它们之间具有适当的继承关系。其中,主要的抽象类如下:
Node:所有语法节点的父类TypeNode:所有类型节点的父类Expr:所有表达式节点的父类Decl:所有声明节点的父类Pattern:所有模式节点的父类
具体节点的类型众多,具体细节请参见《仓颉编程语言库 API》。在下面的案例中,主要使用以下节点:
BinaryExpr:二元运算表达式FuncDecl:函数的声明
节点的解析
通过标准库 std.ast 包,基本上每种节点都可以从 Tokens 解析。有两种解析 Tokens 并构造语法节点的方法。
使用解析函数来解析 Tokens
以下函数用于从 Tokens 解析并构造任意的语法节点:
parseExpr(input: Tokens): Expr:将输入的Tokens解析为表达式节点。parseExprFragment(input: Tokens, startFrom!: Int64 = 0): (Expr, Int64):将输入Tokens的一个片段解析为表达式节点,片段从startFrom索引开始,解析可能只消耗从索引startFrom开始的片段的一部分,并返回第一个未被消耗的Token的索引(如果消耗了整个片段,返回值为input.size)。parseDecl(input: Tokens, astKind!: String = ""):将输入的Tokens解析为声明节点,astKind为额外的设置,具体请参见《仓颉编程语言库 API》文档。parseDeclFragment(input: Tokens, startFrom!: Int64 = 0): (Decl, Int64):将输入Tokens的一个片段解析为声明节点,startFrom参数和返回索引的含义和parseExpr相同。parseType(input: Tokens): TypeNode:将输入的Tokens解析为类型节点。parseTypeFragment(input: Tokens, startFrom!: Int64 = 0): (TypeNode, Int64):将输入Tokens的一个片段解析为类型节点,startFrom参数和返回索引的含义和parseExpr相同。parsePattern(input: Tokens): Pattern:将输入的Tokens解析为模式节点。parsePatternFragment(input: Tokens, startFrom!: Int64 = 0): (Pattern, Int64):将输入Tokens的一个片段解析为模式节点,startFrom参数和返回索引的含义和parseExpr相同。
如果解析失败将抛出异常。这种解析方式适用于类型未知的代码片段,如果需要获取具体的子类型节点,需要将解析结果手动转换成具体的子类型。
这些函数的使用如下例所示:
let tks1 = quote(a + b)
let tks2 = quote(u + v, x + y)
let tks3 = quote(
func f1(x: Int64) { return x + 1 }
)
let tks4 = quote(
func f2(x: Int64) { return x + 2 }
func f3(x: Int64) { return x + 3 }
)
let binExpr1 = parseExpr(tks1)
let (binExpr2, mid) = parseExprFragment(tks2)
let (binExpr3, _) = parseExprFragment(tks2, startFrom: mid + 1) // 跳过逗号
println("binExpr1 = ${binExpr1.toTokens()}")
println("binExpr2 = ${binExpr2.toTokens()}, binExpr3 = ${binExpr3.toTokens()}")
let funcDecl1 = parseDecl(tks3)
let (funcDecl2, mid2) = parseDeclFragment(tks4)
let (funcDecl3, _) = parseDeclFragment(tks4, startFrom: mid2)
println("${funcDecl1.toTokens()}")
println("${funcDecl2.toTokens()}")
println("${funcDecl3.toTokens()}")
输出结果是:
binExpr1 = a + b
binExpr2 = u + v, binExpr3 = x + y
func f1(x: Int64) {
return x + 1
}
func f2(x: Int64) {
return x + 2
}
func f3(x: Int64) {
return x + 3
}
使用语法节点的构造函数来解析 Tokens
大多数语法节点都支持 init(input: Tokens) 构造函数,将输入的 Tokens 解析为相应类型的节点,例如:
import std.ast.*
let binExpr = BinaryExpr(quote(a + b))
let funcDecl = FuncDecl(quote(func f1(x: Int64) { return x + 1 }))
如果解析失败将抛出异常。这种解析方式适用于类型已知的代码片段,解析后不需要再手动转换成具体的子类型。
节点的组成部分
从 Tokens 解析出节点之后,可以查看节点的组成部分。作为例子,仅列出 BinaryExpr 和 FuncDecl 的组成部分,关于其他节点的更详细的解释请参见《仓颉编程语言库 API》文档。
BinaryExpr节点:leftExpr: Expr:运算符左侧的表达式op: Token:运算符rightExpr: Expr:运算符右侧的表达式
FuncDecl节点(部分):identifier: Token:函数名funcParams: ArrayList<FuncParam>:参数列表declType: TypeNode:返回值类型block: Block:函数体
FuncParam节点(部分):identifier: Token:参数名paramType: TypeNode:参数类型
Block节点(部分):nodes: ArrayList<Node>:块中的表达式和声明
每个组成部分都是 public mut prop,因此可以被查看和更新。通过一些例子展示更新的结果。
BinaryExpr 案例
let binExpr = BinaryExpr(quote(x * y))
binExpr.leftExpr = BinaryExpr(quote(a + b))
println(binExpr.toTokens())
binExpr.op = Token(TokenKind.ADD)
println(binExpr.toTokens())
输出结果是:
(a + b) * y
a + b + y
首先,通过解析,获得 binExpr 为节点 x * y,图示如下:
*
/ \
x y
第二步,将左侧的节点(即 x)替换为 a + b,因此,获得的语法树如下:
*
/ \
+ y
/ \
a b
当输出这个语法树的时候,必须在 a + b 周围添加括号,得到 (a + b) * y(如果输出a + b * y,含义为先做乘法,再做加法,与语法树的含义不同)。ast 库具备在输出语法树时自动添加括号的功能。
第三步,将语法树根部的运算符从 * 替换为 +,因此得到语法树如下:
+
/ \
+ y
/ \
a b
这个语法树可以输出为 a + b + y,因为加法本身就是左结合的,不需要在左侧添加括号。
FuncDecl 案例
let funcDecl = FuncDecl(quote(func f1(x: Int64) { x + 1 }))
funcDecl.identifier = Token(TokenKind.IDENTIFIER, "foo")
println("Number of parameters: ${funcDecl.funcParams.size}")
funcDecl.funcParams[0].identifier = Token(TokenKind.IDENTIFIER, "a")
println("Number of nodes in body: ${funcDecl.block.nodes.size}")
let binExpr = (funcDecl.block.nodes[0] as BinaryExpr).getOrThrow()
binExpr.leftExpr = parseExpr(quote(a))
println(funcDecl.toTokens())
在这个案例中,首先通过解析构造出了一个 FuncDecl 节点,然后分别修改了该节点的函数名、参数名,以及函数体中表达式的一部分。输出结果是:
Number of parameters: 1
Number of nodes in body: 1
func foo(a: Int64) {
a + 1
}
使用 quote 插值语法节点
任何语法节点都可以在 quote 语句中插值,部分语法节点的 ArrayList 列表也可以被插值(主要对应实际情况中会出现这类节点列表的情况)。插值直接通过 $(node) 表达即可,其中 node 是任意节点类型的实例。
下面,通过一些案例展示节点的插值。
var binExpr = BinaryExpr(quote(1 + 2))
let a = quote($(binExpr))
let b = quote($binExpr)
let c = quote($(binExpr.leftExpr))
let d = quote($binExpr.leftExpr)
println("a: ${a.toTokens()}")
println("b: ${b.toTokens()}")
println("c: ${c.toTokens()}")
println("d: ${d.toTokens()}")
输出结果是:
a: 1 + 2
b: 1 + 2
c: 1
d: 1 + 2.leftExpr
一般来说,插值运算符后面的表达式使用小括号限定作用域,例如 $(binExpr)。但是当后面只跟单个标识符的时候,小括号可省略,即可写为 $binExpr。因此,在案例中 a 和 b 都在 quote 中插入了 binExpr节点,结果为 1 + 2。然而,如果插值运算符后面的表达式更复杂,不加小括号可能造成作用域出错。例如,表达式 binExpr.leftExpr 求值为 1 + 2 的左表达式,即 1,因此 c 正确赋值为 1。但 d 中的插值被解释为 ($binExpr).leftExpr,因此结果是 1 + 2.leftExpr。为了明确插值的作用域,推荐在插值运算符中使用小括号。
下面的案例展示节点列表(ArrayList)的插值。
var incrs = ArrayList<Node>()
for (i in 1..=5) {
incrs.add(parseExpr(quote(x += $(i))))
}
var foo = quote(
func foo(n: Int64) {
let x = n
$(incrs)
x
})
println(foo)
输出结果是:
func foo(n: Int64) {
let x = n
x += 1
x += 2
x += 3
x += 4
x += 5
x
}
在这个案例中,创建了一个节点列表 incrs,包含表达式 x += 1,...,x += 5。对 incrs 的插值将节点依次列出,在每个节点后换行。这适用于插入需要依次执行的表达式和声明的情况。
下面的案例展示在某些情况下,需要在插值周围添加括号,以保证正确性。
var binExpr1 = BinaryExpr(quote(x + y))
var binExpr2 = BinaryExpr(quote($(binExpr1) * z)) // 错误:得到 x + y * z
println("binExpr2: ${binExpr2.toTokens()}")
println("binExpr2.leftExpr: ${binExpr2.leftExpr.toTokens()}")
println("binExpr2.rightExpr: ${binExpr2.rightExpr.toTokens()}")
var binExpr3 = BinaryExpr(quote(($(binExpr1)) * z)) // 正确:得到 (x + y) * z
println("binExpr3: ${binExpr3.toTokens()}")
输出结果是:
binExpr2: x + y * z
binExpr2.leftExpr: x
binExpr2.rightExpr: y * z
binExpr3: (x + y) * z
首先,构建表达式 x + y,然后将该表达式插入到模板 $(binExpr1) * z 中。这里的意图是得到一个先计算 x + y 再乘 z 的表达式,但是,插值的结果是 x + y * z,即先计算 y * z 再加 x。这是因为插值不会自动添加括号以保证被插入的表达式的原子性(这和前一节介绍的 leftExpr 的替换不同)。因此,需要在 $(binExpr1) 周围添加小括号,保证得到正确的结果。
宏的实现
本章节介绍仓颉宏的定义和使用,仓颉宏可以分为非属性宏和属性宏。同时本章节还会介绍宏出现嵌套时的行为。
注意:
在宏的定义中使用 I/O 操作,如文件操作,网络通信等,可能产生不可预期的行为,请谨慎使用。
非属性宏
非属性宏只接受被转换的代码,不接受其他参数(属性),其定义格式如下:
import std.ast.*
public macro MacroName(args: Tokens): Tokens {
... // Macro body
}
宏的调用格式如下:
@MacroName(...)
宏调用使用 () 括起来。括号里面可以是任意合法 Tokens,也可以是空。
当宏作用于声明时,一般可以省略括号。参考如下示例:
@MacroName func name() {} // Before a FuncDecl
@MacroName struct name {} // Before a StructDecl
@MacroName class name {} // Before a ClassDecl
@MacroName var a = 1 // Before a VarDecl
@MacroName enum e {} // Before a Enum
@MacroName interface i {} // Before a InterfaceDecl
@MacroName extend e <: i {} // Before a ExtendDecl
@MacroName mut prop i: Int64 {} // Before a PropDecl
@MacroName @AnotherMacro(input) // Before a macro call
对于括号里 Tokens 的合法性有以下特殊说明:
-
输入的内容必须是由合法的
Token组成的序列,类似 "#"、" ` "、"\" 等符号单独使用都不是合法的仓颉Token,不支持其作为输入值。 -
输入的内容中,若存在不匹配的小括号则必须使用转义符号 "\" 对其进行转义。
-
输入的内容中,若希望 "@" 作为输入的
Token则必须使用转义符号 "\" 对其进行转义。
对于输入的特殊说明,可以参考如下示例:
// Illegal input Tokens
@MacroName(#) // Not a whole Token
@MacroName(`) // Not a whole Token
@MacroName(() // ( and ) not match
@MacroName(\[) // Escape for unsupported symbol
// Legal input Tokens
@MacroName(#"abc"#)
@MacroName(`class`)
@MacroName([)
@MacroName([])
@MacroName(\()
@MacroName(\@)
宏展开过程作用于仓颉语法树,宏展开后,编译器会继续进行后续的编译过程。因此,需要注意以下规则:
- 宏展开后的代码依然是合法的仓颉代码,并且宏展开后的代码不允许出现包的声明与导入语句,否则可能引发编译问题。
- 当宏用于声明时,如果省略括号,宏的输入必须是语法合法的声明。
下面是几个宏应用的典型示例。
-
示例 1
宏定义文件
macro_definition.cjmacro package macro_definition import std.ast.* public macro testDef(input: Tokens): Tokens { println("I'm in macro body") return input }宏调用文件
macro_call.cjpackage macro_calling import macro_definition.* main(): Int64 { println("I'm in function body") let a: Int64 = @testDef(1 + 2) println("a = ${a}") return 0 }上述代码的编译过程可以参考宏的编译和使用。
在用例中添加了打印信息,其中宏定义中的
I'm in macro body将在编译macro_call.cj的期间输出。同时,宏调用点被展开,如编译如下代码:let a: Int64 = @testDef(1 + 2)编译器将宏返回的
Tokens更新到调用点的语法树上,得到如下代码:let a: Int64 = 1 + 2也就是说,可执行程序中的代码实际变为了:
main(): Int64 { println("I'm in function body") let a: Int64 = 1 + 2 println("a = ${a}") return 0 }a经过计算得到的值为 3,在打印a的值时插值为 3。至此,上述程序的运行结果为:I'm in function body a = 3
下面看一个更有意义的用宏处理函数的例子,这个宏 ModifyFunc 宏的作用是给 myFunc 增加 id 参数,并在 counter++ 前后插入一段代码。
-
示例 2
宏定义文件
macro_definition.cj// file macro_definition.cj macro package macro_definition import std.ast.* public macro ModifyFunc(input: Tokens): Tokens { println("I'm in macro body") let funcDecl = FuncDecl(input) return quote( func $(funcDecl.identifier)(id: Int64) { println("start ${id}") $(funcDecl.block.nodes) println("end") }) }宏调用文件
macro_call.cjpackage macro_calling import macro_definition.* var counter = 0 @ModifyFunc func myFunc() { counter++ } func exModifyFunc() { println("I'm in function body") myFunc(123) println("myFunc called: ${counter} times") return 0 } main(): Int64 { exModifyFunc() }同样的,上述两段代码分别位于不同文件中,先编译宏定义文件
macro_definition.cj,再编译宏调用macro_call.cj生成可执行文件。这个例子中,ModifyFunc 宏的输入是一个函数声明,因此可以省略括号:
@ModifyFunc func myFunc() { counter++ }经过宏展开后,得到如下代码:
func myFunc(id: Int64) { println("start ${id}") counter++ println("end") }myFunc 会在 main 中调用,它接受的实参也是在 main 中定义的,从而形成了一段合法的仓颉程序。运行时打印如下:
I'm in function body start 123 end myFunc called: 1 times
属性宏
和非属性宏相比,属性宏的定义会增加一个 Tokens 类型的输入,这个增加的入参可以让开发者输入额外的信息。比如开发者可能希望在不同的调用场景下使用不同的宏展开策略,则可以通过这个属性入参进行标记位设置。同时,这个属性入参也可以传入任意 Tokens,这些 Tokens 可以与被宏修饰的代码进行组合拼接等。下面是一个简单的例子:
// Macro definition with attribute
public macro Foo(attrTokens: Tokens, inputTokens: Tokens): Tokens {
return attrTokens + inputTokens // Concatenate attrTokens and inputTokens.
}
如上面的宏定义,属性宏的入参数量为 2,入参类型为 Tokens,在宏定义内,可以对 attrTokens 和 inputTokens 进行一系列的组合、拼接等变换操作,最后返回新的 Tokens。
带属性的宏与不带属性的宏的调用类似,属性宏调用时新增的入参 attrTokens 通过 [] 传入,其调用形式为:
// attribute macro with parentheses
var a: Int64 = @Foo[1+](2+3)
// attribute macro without parentheses
@Foo[public]
struct Data {
var count: Int64 = 100
}
-
宏 Foo 调用,当参数是
2+3时,与[]内的属性1+进行拼接,经过宏展开后,得到var a: Int64 = 1+2+3。 -
宏 Foo 调用,当参数是 struct Data 时,与
[]内的属性public进行拼接,经过宏展开后,得到public struct Data { var count: Int64 = 100 }
关于属性宏,需要注意以下几点:
-
带属性的宏,与不带属性的宏相比,能修饰的 AST 是相同的,可以理解为带属性的宏对可传入参数做了增强。
-
属性宏小括号内的参数合法性规则与非属性宏的参数合法性规则一致。
-
属性宏中括号内的参数(属性)的合法性规则有如下特殊说明:
-
输入的内容必须是由合法的
Token组成的序列,类似 "#"、" ` "、"\" 等符号单独使用都不是合法的仓颉Token,不支持其作为输入值。 -
输入的内容中,若存在不匹配的中括号则必须使用转义符号 "\" 对其进行转义。
-
输入的内容中,若希望 "@" 作为输入的
Token则必须使用转义符号 "\" 对其进行转义。
// Illegal attribute Tokens @MacroName[#]() // Not a whole Token @MacroName[`]() // Not a whole Token @MacroName[@]() // Not escape for @ @MacroName[[]() // [ and ] not match @MacroName[\(]() // Escape for unsupported symbol // Legal attribute Tokens @MacroName[#"abc"#]() @MacroName[`class`]() @MacroName[(]() @MacroName[()]() @MacroName[\[]() @MacroName[\@]() -
-
宏的定义和调用的类型要保持一致:如果宏定义有两个入参,即为属性宏定义,调用时必须加上
[],且内容可以为空;如果宏定义有一个入参,即为非属性宏定义,调用时不能使用[]。
嵌套宏
仓颉语言不支持宏定义的嵌套;有条件地支持在宏定义和宏调用中嵌套宏调用。
宏定义中嵌套宏调用
下面是一个宏定义中包含其他宏调用的例子。
宏包 pkg1 中定义 getIdent 宏:
macro package pkg1
import std.ast.*
public macro getIdent(attr:Tokens, input:Tokens):Tokens {
return quote(
let decl = (parseDecl(input) as VarDecl).getOrThrow()
let name = decl.identifier.value
let size = name.size - 1
let $(attr) = Token(TokenKind.IDENTIFIER, name[0..size])
)
}
宏包 pkg2 中定义 Prop 宏,其中嵌套了 getIdent 宏的调用:
macro package pkg2
import std.ast.*
import pkg1.*
public macro Prop(input:Tokens):Tokens {
let v = parseDecl(input)
@getIdent[ident](input)
return quote(
$(input)
public prop $(ident): $(decl.declType) {
get() {
this.$(v.identifier)
}
}
)
}
宏调用包 pkg3 中调用 Prop 宏:
package pkg3
import pkg2.*
class A {
@Prop
private let a_: Int64 = 1
}
main() {
let b = A()
println("${b.a}")
}
注意,按照宏定义必须比宏调用点先编译的约束,上述 3 个文件的编译顺序必须是:pkg1 -> pkg2 -> pkg3。pkg2 中的 Prop 宏定义:
public macro Prop(input:Tokens):Tokens {
let v = parseDecl(input)
@getIdent[ident](input)
return quote(
$(input)
public prop $(ident): $(decl.declType) {
get() {
this.$(v.identifier)
}
}
)
}
会先被展开成如下代码,再进行编译。
public macro Prop(input: Tokens): Tokens {
let v = parseDecl(input)
let decl = (parseDecl(input) as VarDecl).getOrThrow()
let name = decl.identifier.value
let size = name.size - 1
let ident = Token(TokenKind.IDENTIFIER, name[0 .. size])
return quote(
$(input)
public prop $(ident): $(decl.declType) {
get() {
this.$(v.identifier)
}
}
)
}
宏调用中嵌套宏调用
嵌套宏的常见场景,是宏修饰的代码块中,出现了宏调用。一个具体的例子如下:
pkg1 包中定义 Foo 和 Bar 宏:
macro package pkg1
import std.ast.*
public macro Foo(input: Tokens): Tokens {
return input
}
public macro Bar(input: Tokens): Tokens {
return input
}
pkg2 包中定义 addToMul 宏:
macro package pkg2
import std.ast.*
public macro addToMul(inputTokens: Tokens): Tokens {
var expr: BinaryExpr = match (parseExpr(inputTokens) as BinaryExpr) {
case Some(v) => v
case None => throw Exception()
}
var op0: Expr = expr.leftExpr
var op1: Expr = expr.rightExpr
return quote(($(op0)) * ($(op1)))
}
pkg3 包中使用上面定义的三个宏:
package pkg3
import pkg1.*
import pkg2.*
@Foo
struct Data {
let a = 2
let b = @addToMul(2+3)
@Bar
public func getA() {
return a
}
public func getB() {
return b
}
}
main(): Int64 {
let data = Data()
var a = data.getA() // a = 2
var b = data.getB() // b = 6
println("a: ${a}, b: ${b}")
return 0
}
如上代码所示,宏 Foo 修饰了 struct Data,而在 struct Data 内,出现了宏调用 addToMul 和 Bar。这种嵌套场景下,代码变换的规则是:将嵌套内层的宏(addToMul 和 Bar)展开后,再去展开外层的宏(Foo)。允许出现多层宏嵌套,代码变换的规则总是由内向外去依次展开宏。
嵌套宏可以出现在带括号和不带括号的宏调用中,二者可以组合,但开发者需要保证没有歧义,且明确宏的展开顺序:
var a = @foo(@foo1(2 * 3)+@foo2(1 + 3)) // foo1, foo2 have to be defined.
@Foo1 // Foo2 expands first, then Foo1 expands.
@Foo2[attr: struct] // Attribute macro can be used in nested macro.
struct Data{
@Foo3 @Foo4[123] var a = @bar1(@bar2(2 + 3) + 3) // bar2, bar1, Foo4, Foo3 expands in order.
public func getA() {
return @foo(a + 2)
}
}
嵌套宏之间的消息传递
这里指的是宏调用的嵌套。
内层宏可以调用库函数 assertParentContext 来保证内层宏调用一定嵌套在特定的外层宏调用中。如果内层宏调用这个函数时没有嵌套在给定的外层宏调用中,该函数将抛出一个错误。库函数 InsideParentContext 同样用于检查内层宏调用是否嵌套在特定的外层宏调用中,该函数返回一个布尔值。下面是一个简单的例子。
宏定义如下:
public macro Outer(input: Tokens): Tokens {
return input
}
public macro Inner(input: Tokens): Tokens {
assertParentContext("Outer")
return input
}
宏调用如下:
@Outer var a = 0
@Inner var b = 0 // Error, The macro call 'Inner' should with the surround code contains a call 'Outer'.
如上代码所示,Inner 宏在定义时使用了 assertParentContext 函数用于检查其在调用阶段是否位于 Outer 宏中,在代码示例的宏调用场景下,由于 Outer 和 Inner 在调用时不存在这样的嵌套关系,因此编译器将报告一个错误。
内层宏也可以通过发送键/值对的方式与外层宏通信。当内层宏执行时,通过调用标准库函数 setItem 向外层宏发送信息;随后,当外层宏执行时,调用标准库函数 getChildMessages 接收每一个内层宏发送的信息(一组键/值对映射)。下面是一个简单的例子。
宏定义如下:
macro package define
import std.ast.*
public macro Outer(input: Tokens): Tokens {
let messages = getChildMessages("Inner")
let getTotalFunc = quote(public func getCnt() {
)
for (m in messages) {
let identName = m.getString("identifierName")
// let value = m.getString("key") // 接收多组消息
getTotalFunc.append(Token(TokenKind.IDENTIFIER, identName))
getTotalFunc.append(quote(+))
}
getTotalFunc.append(quote(0))
getTotalFunc.append(quote(}))
let funcDecl = parseDecl(getTotalFunc)
let decl = (parseDecl(input) as ClassDecl).getOrThrow()
decl.body.decls.add(funcDecl)
return decl.toTokens()
}
public macro Inner(input: Tokens): Tokens {
assertParentContext("Outer")
let decl = parseDecl(input)
setItem("identifierName", decl.identifier.value)
// setItem("key", "value") // 可以通过不同的key值传递多组消息
return input
}
宏调用如下:
import define.*
@Outer
class Demo {
@Inner var state = 1
@Inner var cnt = 42
}
main(): Int64 {
let d = Demo()
println("${d.getCnt()}")
return 0
}
在上面的代码中,Outer 接收两个 Inner 宏发送来的变量名,自动为类添加如下内容:
public func getCnt() {
state + cnt + 0
}
具体流程为:内层宏 Inner 通过 setItem 向外层宏发送信息;Outer 宏通过 getChildMessages 函数接收到 Inner 发送的一组信息对象(Outer 中可以调用多次 Inner);最后通过该信息对象的 getString 函数接收对应的值。
编译、报错与调试
宏的编译和使用
当前编译器约束宏的定义与宏的调用不允许在同一包里。宏包必须首先被编译,然后再编译宏调用的包。在宏调用的包中,不允许出现宏的定义。由于宏需在包中导出给另一个包使用,因此编译器约束宏定义必须使用 public 修饰。
下面介绍一个简单的例子。
源码目录结构如下:
// Directory layout.
root_path
├── macros
│ └── m.cj
├── src
│ └── demo.cj
└─ target
宏定义放在 macros 子目录下:
// macros/m.cj
// In this file, we define the macro Inner, Outer.
macro package define
import std.ast.*
public macro Inner(input: Tokens) {
return input
}
public macro Outer(input: Tokens) {
return input
}
宏调用放在 src 子目录下:
// src/demo.cj
import define.*
@Outer
class Demo {
@Inner var state = 1
@Inner var cnt = 42
}
main() {
println("test macro")
0
}
当宏定义文件的编译产物和使用宏的文件不在同一目录下时,需要通过添加 --import-path 编译选项来指定宏定义文件编译产物的路径。以下为 Linux 平台的编译命令(具体编译选项会随着 cjc 更新而演进,以最新 cjc 的编译选项为准):
# 先编译宏定义文件在指定目录产生默认的动态库文件(允许指定动态库的路径,但不能指定动态库的名字)
cjc macros/m.cj --compile-macro --output-dir ./target
# 编译使用宏的文件,宏替换完成,产生可执行文件
cjc src/demo.cj -o demo --import-path ./target --output-dir ./target
# 运行可执行文件
./target/demo
在 Linux 平台上,将生成用于包管理的 macro_define.cjo 和实际的动态库文件。
若在 Windows 平台:
# 当前目录: src
# 先编译宏定义文件在指定目录产生默认的动态库文件(允许指定动态库的路径,但不能指定动态库的名字)
cjc macros/m.cj --compile-macro --output-dir ./target
# 编译使用宏的文件,宏替换完成,产生可执行文件
cjc src/demo.cj -o demo.exe --import-path ./target --output-dir ./target
如果宏包还依赖其他动态库,则需要保证宏包在运行态(宏展开依赖宏包内方法的执行)下能够找到这些依赖。在 Linux 下可以通过设置 LD_LIBRAYR_PATH(Windows 下设置 PATH)环境变量添加所依赖动态库的路径。
说明:
宏替换过程依赖仓颉 runtime ,宏替换过程中仓颉 runtime 的初始化配置采用宏提供的默认配置,配置参数支持使用仓颉 runtime 运维日志进行查询,其中 cjHeapSize 与 cjStackSize 支持用户修改,其余暂不支持,仓颉 runtime 初始化配置可参见runtime 初始化可选配置章节。
并行宏展开
可以在编译宏调用文件时添加 --parallel-macro-expansion 选项,启用并行宏展开的能力。编译器会自动分析宏调用之间的依赖关系,无依赖关系的宏调用可以并行执行,如上述例子中的两个 @Inner 就可以并行展开,如此可以缩短整体编译时间。
注意:
如果宏函数依赖一些全局变量,使用并行宏展开会存在风险。
macro package define
import std.ast.*
import std.collection.*
var Counts = HashMap<String, Int64>()
public macro Inner(input: Tokens) {
for (t in input) {
if (t.value.size == 0) {
continue
}
// 统计所有有效token value的出现次数
if (!Counts.contains(t.value)) {
Counts[t.value] = 0
}
Counts[t.value] = Counts[t.value] + 1
}
return input
}
public macro B(input: Tokens) {
return input
}
参考上述代码,如果 @Inner 的宏调用出现在多处,并且启用了并行宏展开选项,则访问全局变量 Counts 就可能存在冲突,导致最后获取的结果不正确。
建议不要在宏函数中使用全局变量,如果必须使用,要么关闭并行宏展开选项,或者可以通过仓颉线程锁对全局变量进行保护。
diagReport 报错机制
仓颉标准库 std.ast 包提供了自定义报错接口 diagReport。方便定义宏的用户,在解析传入 Tokens 时,对错误 Tokens 内容进行自定义报错。
自定义报错接口提供同原生编译器报错一样的输出格式,允许用户报 warning 和 error 两类错误提示信息。
diagReport 的函数原型如下:
public func diagReport(level: DiagReportLevel, tokens: Tokens, message: String, hint: String): Unit
其参数含义如下:
- level: 报错信息等级
- tokens: 报错信息中所引用源码内容对应的 Tokens
- message: 报错的主信息
- hint: 辅助提示信息
参考如下使用示例。
宏定义文件:
// macro_definition.cj
macro package macro_definition
import std.ast.*
public macro testDef(input: Tokens): Tokens {
for (i in 0..input.size) {
if (input[i].kind == IDENTIFIER) {
diagReport(DiagReportLevel.ERROR, input[i..(i + 1)],
"This expression is not allowed to contain identifier",
"Here is the illegal identifier")
}
}
return input
}
宏调用文件:
// macro_call.cj
package macro_calling
import std.ast.*
import macro_definition.*
main(): Int64 {
let a = @testDef(1)
let b = @testDef(a)
let c = @testDef(1 + a)
return 0
}
编译宏调用文件过程中,会出现如下报错信息:
error: This expression is not allowed to contain identifier
==> call.cj:9:22:
|
9 | let b = @testDef(a)
| ^ Here is the illegal identifier
|
error: This expression is not allowed to contain identifier
==> call.cj:10:26:
|
10 | let c = @testDef(1 + a)
| ^ Here is the illegal identifier
|
2 errors generated, 2 errors printed.
使用 --debug-macro 输出宏展开结果
借助宏在编译期做代码生成时,如果发生错误,处理起来十分棘手,这是开发者经常遇到但一般很难定位的问题。这是因为,开发者写的源码,经过宏的变换后变成了不同的代码片段。编译器抛出的错误信息是基于宏最终生成的代码进行提示的,但这些代码在开发者的源码中没有体现。
为了解决这个问题,仓颉宏提供 debug 模式,在这个模式下,开发者可以从编译器为宏生成的 debug 文件中看到完整的宏展开后的代码,如下所示。
宏定义文件:
macro package define
import std.ast.*
public macro Outer(input: Tokens): Tokens {
let messages = getChildMessages("Inner")
let getTotalFunc = quote(public func getCnt() {
)
for (m in messages) {
let identName = m.getString("identifierName")
getTotalFunc.append(Token(TokenKind.IDENTIFIER, identName))
getTotalFunc.append(quote(+))
}
getTotalFunc.append(quote(0))
getTotalFunc.append(quote(}))
let funcDecl = parseDecl(getTotalFunc)
let decl = (parseDecl(input) as ClassDecl).getOrThrow()
decl.body.decls.add(funcDecl)
return decl.toTokens()
}
public macro Inner(input: Tokens): Tokens {
assertParentContext("Outer")
let decl = parseDecl(input)
setItem("identifierName", decl.identifier.value)
return input
}
宏调用文件 demo.cj:
import define.*
@Outer
class Demo {
@Inner var state = 1
@Inner var cnt = 42
}
main(): Int64 {
let d = Demo()
println("${d.getCnt()}")
return 0
}
在编译使用宏的文件时,在选项中,增加 --debug-macro,即使用仓颉宏的 debug 模式。
cjc --debug-macro demo.cj --import-path ./target
注意:
如果使用仓颉的
CJPM包管理工具进行编译,可在配置文件cjpm.toml中添加--debug-macro的编译选项来使用宏的 debug 模式。compile-option = "--debug-macro"
在 debug 模式下,会生成临时文件 demo.cj.macrocall,对应宏展开的部分如下:
// demo.cj.macrocall
/* ===== Emitted by MacroCall @Outer in demo.cj:3:1 ===== */
/* 3.1 */class Demo {
/* 3.2 */ var state = 1
/* 3.3 */ var cnt = 42
/* 3.4 */ public func getCnt() {
/* 3.5 */ state + cnt + 0
/* 3.6 */ }
/* 3.7 */}
/* 3.8 */
/* ===== End of the Emit ===== */
如果宏展开后的代码有语义错误,则编译器的错误信息会溯源到宏展开后代码的具体行列号。如果在编译时开启了 debug 模式,那么编译器的错误信息中不会打印完整的宏展开代码,仅打印实际错误位置和临时文件路径,开发者可以通过临时文件路径跳转至对应的错误位置;非 debug 模式下,报错信息中会打印出完整的宏展开代码。仓颉宏的 debug 模式有以下注意事项:
-
宏的 debug 模式会重排源码的行列号信息,不适用于某些特殊的换行场景。例如:
// before expansion @M{} - 2 // macro M return 2 // after expansion // ===== Emmitted my Macro M at line 1 === 2 // ===== End of the Emit ===== - 2这些因换行符导致语义改变的情形,不应使用 debug 模式。
-
不支持宏调用在宏定义内的调试,会编译报错。
public macro M(input: Tokens) { let a = @M2(1+2) // M2 is in macro M, not suitable for debug mode. return input + quote($a) } -
不支持带括号宏的调试。
// main.cj main() { // For macro with parenthesis, newline introduced by debug will change the semantics // of the expression, so it is not suitable for debug mode. let t = @M(1+2) 0 }
宏包定义和导入
仓颉语言中宏的定义需要放在由 macro package 声明的包中,被 macro package 限定的包仅允许宏定义对外可见,其他声明包内可见。
说明:
重导出的声明也允许对外可见,关于包管理和重导出的相关概念,请参见包的导入章节。
// file define.cj
macro package define // 编译 define.cjo 携带 macro 属性
import std.ast.*
public func A() {} // Error, 宏包不允许定义外部可见的非宏定义,此处会报错
public macro M(input: Tokens): Tokens { // macro M 外部可见
return input
}
需要特殊说明的是,在宏包中,允许其他宏包和非宏包的声明被重导出。在非宏包中仅允许非宏包的声明被重导出。
参考如下示例:
-
在宏包 A 中定义宏
M1macro package A import std.ast.* public macro M1(input: Tokens): Tokens { return input }编译命令如下:
cjc A.cj --compile-macro -
在非宏包 B 中定义一个 public 函数
f1。注意在非macro package中无法重导出macro package的符号package B // public import A.* // Error, it is not allowed to re-export a macro package in a package. public func f1(input: Int64): Int64 { return input }编译命令如下,这里选择使用
--output-type选项将 B 包编译成动态库,关于 cjc 编译选项,详情请参见 "附录 > cjc 编译选项"。cjc B.cj --output-type=dylib -o libB.so -
在宏包 C 中定义宏
M2,依赖了 A 包和 B 包的内容。可以看到macro package中可以重导出macro package和非macro package的符号macro package C public import A.* // correct: macro package is allowed to re-export in a macro package. public import B.* // correct: non-macro package is also allowed to re-export in a macro package. import std.ast.* public macro M2(input: Tokens): Tokens { return @M1(input) + Token(TokenKind.NL) + quote(f1(1)) }编译命令如下,注意这里需要显式链接 B 包动态库:
cjc C.cj --compile-macro -L. -lB -
在
main.cj中使用M2宏import C.* main() { @M2(let a = 1) }编译命令如下:
cjc main.cj -o main -L. -lBmain.cj中M2宏展开后的结果如下:import C.* main() { let a = 1 f1(1) }
可以看到 main.cj 中出现了来自于 B 包的符号 f1。宏的编写者可以在 C 包中重导出 B 包里的符号,这样宏的使用者仅需导入宏包,就可以正确地编译宏展开后的代码。如果在 main.cj 中仅使用 import C.M2 导入宏符号,则会报 undeclared identifier 'f1' 的错误信息。
内置编译标记
仓颉语言提供了一些预定义的编译标记,可以通过这些编译标记控制仓颉编译器的编译行为。
源码位置
仓颉提供了几个内置编译标记,用于在编译时获取源码的位置。
@sourcePackage()展开后是一个String类型的字面量,内容为该标记所在的源码的包名。@sourceFile()展开后是一个String类型的字面量,内容为该标记所在的源码的文件名。@sourceLine()展开后是一个Int64类型的字面量,内容为该标记所在的源码的代码行。
这几个编译标记可以在任意表达式内部使用,只要能符合类型检查规则即可。示例如下:
func test1() {
let s: String = @sourceFile() // The value of `s` is the current source file name
}
func test2(n!: Int64 = @sourceLine()) { /* at line 5 */
// The default value of `n` is the source file line number of the definition of `test2`
println(n) // print 5
}
条件编译
条件编译使用 @When 标记,是一种在程序代码中根据特定条件选择性地编译不同代码段的技术。条件编译的作用主要体现在以下几个方面:
- 平台适应:支持根据当前的编译环境选择性地编译代码,用于实现跨平台的兼容性。
- 功能选择:支持根据不同的需求选择性地编译代码,用于实现功能的灵活配置。
- 调试支持:支持调试模式下编译相关代码,用于提高程序的性能和安全性。例如,在调试模式下编译调试信息或记录日志相关的代码,而在发布版本中将其排除。
- 性能优化:支持根据预定义的条件选择性地编译代码,用于提高程序的性能。
关于条件编译的具体内容,请参见条件编译章节,这里不再额外展开。
@FastNative
为了提升与 C 语言互操作的性能,仓颉提供 @FastNative 标记用于优化对 C 函数的调用。值得注意的是 @FastNative 只能用于 foreign 声明的函数。
使用示例如下:
@FastNative
foreign func strlen(str: CPointer<UInt8>): UIntNative
开发者在使用 @FastNative 修饰 foreign 函数时,应确保对应的 C 函数满足以下两点要求:
- 函数的整体执行时间不宜太长。例如:不允许函数内部存在很大的循环;不允许函数内部产生阻塞行为,例如:调用
sleep、wait等函数。 - 函数内部不能调用仓颉方法。
@Frozen
@Frozen 标记可用于修饰函数和属性。如果确定某个函数、属性在将来的版本更新中不会去修改它的内部实现,那么可以使用 @Frozen 对其进行标记,该标记代表开发者对该函数/属性在未来版本演进的一种承诺。被 @Frozen 修饰的函数和属性,在后续的升级版本中,签名和函数体都不能发生任何变化。这意味着,前后两个代码版本,在相同编译器、相同编译选项的情况下,该函数或属性的生成产物完全一致。
@Frozen 标记可被用于修饰:
- 全局函数
- 类、结构、接口、扩展、枚举中的函数
- 类、接口、扩展中的属性
@Frozen 标记不可被用于修饰:
- 除了函数和属性以外的其他类型声明
- 嵌套函数
- 表达式
使用示例如下:
@Frozen
public func test(): Unit {}
public class testClass {
@Frozen
public func testFunc(): Unit {}
@Frozen
public prop testProp: Unit {
get() {}
}
}
@Attribute
仓颉语言内部提供 @Attribute 标记,开发者通过内置的 @Attribute 来对某个声明设置属性值,从而达到标记声明的目的。属性值可以是 identifier 或者 string,下面是一个简单的例子,这段示例代码为变量 cnt 添加了一个 identifier 类型的属性 State,为变量 bcnt 添加了一个 string 类型的属性 "Binding"。
@Attribute[State] var cnt = 0 // identifier
@Attribute["Binding"] var bcnt = 0 // string
同时,标准库 std.ast 包提供了 getAttrs() 方法用于获取节点的属性,以及 hasAttr(attrs: String) 方法用于判断当前节点是否具有某个属性,下面是一个具体的例子。
宏定义如下:
public macro Component(input: Tokens): Tokens {
var varDecl = parseDecl(input)
if (varDecl.hasAttr("State")) { // 如果该节点被标记了属性且值为 “State” 返回 true, 否则返回 false
var attrs = varDecl.getAttrs() // 返回一组 Tokens
println(attrs[0].value)
}
return input
}
宏调用如下:
@Component(
@Attribute[State] var cnt = 0
)
@Deprecated
@Deprecated 表示此 API 已废弃,虽然暂时可用,但未来将被移除或更改,建议其他开发者不要调用此 API。例如:
@Deprecated["用boo代替", since: "1.3.4"]
func foo() {}
main() {
foo()
}
编译器编译时将提供告警信息:
warning: function 'foo' is deprecated since 1.3.4. 用boo代替
==> file.cj:5:5:
|
5 | foo()
| ^^^ deprecated
|
# note: this warning can be suppressed by setting the compiler option `-Woff deprecated`
1 warning generated, 1 warning printed.
@Deprecated 自定义宏可以应用于以下声明:
- 类、接口、结构体、枚举、枚举构造器
- 顶级(全局)函数或变量
- 静态或非静态的成员函数、成员变量、属性、属性设置器
- 运算符函数
- 扩展的成员函数、静态函数、属性或属性设置器
- foreign 函数或声明在 foreign 块内的函数
- 构造函数和主构造函数
- 抽象的函数和属性
- 类型别名(包括关联类型)
- 函数具有默认参数的命名参数
- const 变量和函数
- 宏定义
- 注解类
@Deprecated 参数
message: String- 描述声明为何废弃、如何迁移等。since!: ?String- 废弃版本。strict!: Bool- 默认值为false,在被该标记修饰的 API 的调用处会触发警告。如果设置为true,则会触发编译错误。
@Deprecated["Use Macro2", since: "1990", strict: true]
public macro Macro(input: Tokens): Tokens {
return input
}
实用案例
快速幂的计算
通过一个简单的例子展示使用宏进行编译期求值,生成优化代码的应用。在计算幂 n ^ e 时,如果 e 是一个(比较大的)整数,可以通过重复取平方(而不是迭代相乘)的方式加速计算。这个算法可以直接使用 while 循环实现,例如:
func power(n: Int64, e: Int64) {
var result = 1
var vn = n
var ve = e
while (ve > 0) {
if (ve % 2 == 1) {
result *= vn
}
ve /= 2
if (ve > 0) {
vn *= vn
}
}
result
}
然而,这个实现需要每次对 e 的值进行分析,在循环和条件判断中多次对 ve 进行判断和更新。此外,实现只支持 n 的类型为Int64的情况,如果要支持其他类型的 n,还要处理如何表达 result = 1 的问题。如果预先知道 e 的具体值,可以将这个代码写的更简单。例如,如果知道 e 的值为 10,可以展开整个循环如下:
func power_10(n: Int64) {
var vn = n
vn *= vn // vn = n ^ 2
var result = vn // result = n ^ 2
vn *= vn // vn = n ^ 4
vn *= vn // vn = n ^ 8
result *= vn // result = n ^ 10
result
}
当然,手动编写这些代码非常繁琐,希望在给定 e 的值之后,自动将这些代码生成出来。宏可以做到这一点。使用案例如下:
public func power_10(n: Int64) {
@power[10](n)
}
这个宏展开的代码是(根据 .macrocall 文件):
public func power_10(n: Int64) {
/* ===== Emitted by MacroCall @power in main.cj:20:5 ===== */
/* 20.1 */var _power_vn = n
/* 20.2 */_power_vn *= _power_vn
/* 20.3 */var _power_result = _power_vn
/* 20.4 */_power_vn *= _power_vn
/* 20.5 */_power_vn *= _power_vn
/* 20.6 */_power_result *= _power_vn
/* 20.7 */_power_result
/* ===== End of the Emit ===== */
}
下面是宏 @power 的实现。
macro package define
import std.ast.*
import std.convert.*
public macro power(attrib: Tokens, input: Tokens) {
let attribExpr = parseExpr(attrib)
if (let Some(litExpr) <- (attribExpr as LitConstExpr)) {
let lit = litExpr.literal
if (lit.kind != TokenKind.INTEGER_LITERAL) {
diagReport(DiagReportLevel.ERROR, attrib,
"Attribute must be integer literal",
"Expected integer literal")
}
var n = Int64.parse(lit.value)
var result = quote(var _power_vn = $(input)
)
var flag = false
while (n > 0) {
if (n % 2 == 1) {
if (!flag) {
result += quote(var _power_result = _power_vn
)
flag = true
} else {
result += quote(_power_result *= _power_vn
)
}
}
n /= 2
if (n > 0) {
result += quote(_power_vn *= _power_vn
)
}
}
result += quote(_power_result)
return result
} else {
diagReport(DiagReportLevel.ERROR, attrib,
"Attribute must be integer literal",
"Expected integer literal")
}
return input
}
这段代码的解释如下:
- 首先,确认输入的属性
attrib是一个整数字面量,否则通过diagReport报错。将这个字面量解析为整数n。 - 设
result为当前积累的输出代码,首先添加var _power_vn的声明。这里为了避免变量名冲突,使用不易造成冲突的名字_power_vn。 - 下面进入 while 循环,布尔变量
flag表示var _power_result是否已经被初始化。其余的代码结构和之前展示的power函数的实现类似,但区别是使用 while 循环和 if 判断在编译时决定生成的代码是什么,而不是在运行时做这些判断。然后生成由_power_result *= _power_vn和_power_vn *= _power_vn适当组合的代码。 - 最后添加返回
_power_result的代码,并将这段代码作为宏的输出值返回。
将这段代码放到 macros/power.cj 文件中,并在 main.cj 添加如下测试:
import define.*
public func power_10(n: Int64) {
@power[10](n)
}
main() {
let a = 3
println(power_10(a))
}
输出结果为:
59049
Memoize 宏
Memoize(记忆化)是动态规划算法的常用手段。它将已经计算过的子问题的结果存储起来,当同一个子问题再次出现时,可以直接查询表来获取结果,从而避免重复的计算,提高算法的效率。
通常 Memoize 的使用需要开发者手动实现存储和提取的功能。通过宏,可以自动化这一过程。宏的效果如下:
@Memoize[true]
func fib(n: Int64): Int64 {
if (n == 0 || n == 1) {
return n
}
return fib(n - 1) + fib(n - 2)
}
main() {
let start = DateTime.now()
let f35 = fib(35)
let end = DateTime.now()
println("fib(35): ${f35}")
println("execution time: ${(end - start).toMicroseconds()} us")
}
在以上代码中,fib 函数采用简单的递归方式实现。如果没有 @Memoize[true] 标注,这个函数的运行时间将随着 n 指数增长。例如,如果在前面的代码中去掉 @Memoize[true] 这一行,或者把 true 改为 false,则 main 函数的运行结果为:
fib(35): 9227465
execution time: 199500 us
恢复 @Memoize[true],运行结果为:
fib(35): 9227465
execution time: 78 us
相同的答案和大幅缩短的计算时间表明,@Memoize 的使用确实实现了记忆化。
为了理解 @Memoize 的原理,展示对以上 fib 函数进行宏展开的结果(来自 .macrocall 文件,但是为了提高可读性整理了格式)。
import std.collection.*
var memoizeFibMap = HashMap<Int64, Int64>()
func fib(n: Int64): Int64 {
if (memoizeFibMap.contains(n)) {
return memoizeFibMap.get(n).getOrThrow()
}
let memoizeEvalResult = { =>
if (n == 0 || n == 1) {
return n
}
return fib(n - 1) + fib(n - 2)
}()
memoizeFibMap.add(n, memoizeEvalResult)
return memoizeEvalResult
}
上述代码的执行流程如下:
- 首先,定义
memoizeFibMap为一个从Int64到Int64的哈希表,这里第一个Int64对应fib的唯一参数的类型,第二个Int64对应fib返回值的类型。 - 其次,在函数体中,检查入参是否在
memoizeFibMap中,如果是则立即反馈哈希表中存储的值。否则,使用fib原来的函数体得到计算结果。这里使用了(不带参数的)匿名函数使fib的函数体不需要任何改变,并且能够处理任何从fib函数退出的方式(包括中间的 return,返回最后一个表达式等)。 - 最后,把计算结果存储到
memoizeFibMap中,然后将计算结果返回。
有了这样一个“模板”之后,下面宏的实现就不难理解了。完整的代码如下。
public macro Memoize(attrib: Tokens, input: Tokens) {
if (attrib.size != 1 || attrib[0].kind != TokenKind.BOOL_LITERAL) {
diagReport(DiagReportLevel.ERROR, attrib,
"Attribute must be a boolean literal (true or false)",
"Expected boolean literal (true or false) here")
}
let memoized = (attrib[0].value == "true")
if (!memoized) {
return input
}
let fd = FuncDecl(input)
if (fd.funcParams.size != 1) {
diagReport(DiagReportLevel.ERROR, fd.lParen + fd.funcParams.toTokens() + fd.rParen,
"Input function to memoize should take exactly one argument",
"Expect only one argument here")
}
let memoMap = Token(TokenKind.IDENTIFIER, "_memoize_" + fd.identifier.value + "_map")
let arg1 = fd.funcParams[0]
return quote(
var $(memoMap) = HashMap<$(arg1.paramType), $(fd.declType)>()
func $(fd.identifier)($(arg1)): $(fd.declType) {
if ($(memoMap).contains($(arg1.identifier))) {
return $(memoMap).get($(arg1.identifier)).getOrThrow()
}
let memoizeEvalResult = { => $(fd.block.nodes) }()
$(memoMap).add($(arg1.identifier), memoizeEvalResult)
return memoizeEvalResult
}
)
}
首先,对属性和输入做合法性检查。属性必须是布尔字面量,如果为 false 则直接返回输入。否则,检查输入必须能够解析为函数声明(FuncDecl),并且必须包含正好一个参数。下面,产生哈希表的变量,取不容易造成冲突的变量名。最后,通过 quote模板生成返回的代码,其中用到哈希表的变量名,以及唯一参数的名称、类型和输入函数的返回类型。
一个 dprint 宏的扩展
本节一开始使用了一个打印表达式的宏作为案例,但这个宏一次只能接受一个表达式。希望扩展这个宏,使其能够接受多个表达式,由逗号分开。下面展示如何使用 parseExprFragment 来实现这个功能。
宏的实现如下:
public macro dprint2(input: Tokens) {
let exprs = ArrayList<Expr>()
var index: Int64 = 0
while (true) {
let (expr, nextIndex) = parseExprFragment(input, startFrom: index)
exprs.add(expr)
if (nextIndex == input.size) {
break
}
if (input[nextIndex].kind != TokenKind.COMMA) {
diagReport(DiagReportLevel.ERROR, input[nextIndex..nextIndex+1],
"Input must be a comma-separated list of expressions",
"Expected comma")
}
index = nextIndex + 1 // 跳过逗号
}
let result = quote()
for (expr in exprs) {
result.append(quote(
print($(expr.toTokens().toString()) + " = ")
println($(expr))
))
}
return result
}
使用案例:
let x = 3
let y = 2
@dprint2(x, y, x + y)
输出结果为:
x = 3
y = 2
x + y = 5
在宏的实现中,使用 while 循环从索引 0 开始依次解析每个表达式。变量 index 保存当前解析的位置。每次调用 parseExprFragment 时,从当前位置开始,并返回解析后的位置(以及解析得到的表达式)。如果解析后的位置到达了输入的结尾,则退出循环。否则检查到达的位置是否是一个逗号,如果不是逗号,报错并退出,如果是逗号,跳过这个逗号并开始下一轮的解析。在得到表达式的列表后,依次输出每个表达式。
一个简单的 DSL
这个案例展示了如何使用宏实现一个简单的 DSL(Domain Specific Language,领域特定语言)。LINQ(Language Integrated Query,语言集成查询)是微软 .NET 框架的一个组成部分,它提供了一种统一的数据查询语法,允许开发者使用类似 SQL 的查询语句来操作各种数据源。在这里,仅展示一个最简单的 LINQ 语法的支持。
希望支持的语法为:
from <variable> in <list> where <condition> select <expression>
其中,variable 是一个标识符,list、condition 和 expression 都是表达式。因此,实现宏的策略是先后提取标识符和表达式,同时检查中间的关键字是正确的。最后,生成由提取部分组成的查询结果。
宏的实现如下:
public macro linq(input: Tokens) {
let syntaxMsg = "Syntax is \"from <attrib> in <table> where <cond> select <expr>\""
if (input.size == 0 || input[0].value != "from") {
diagReport(DiagReportLevel.ERROR, input[0..1], syntaxMsg,
"Expected keyword \"from\" here.")
}
if (input.size <= 1 || input[1].kind != TokenKind.IDENTIFIER) {
diagReport(DiagReportLevel.ERROR, input[1..2], syntaxMsg,
"Expected identifier here.")
}
let attribute = input[1]
if (input.size <= 2 || input[2].value != "in") {
diagReport(DiagReportLevel.ERROR, input[2..3], syntaxMsg,
"Expected keyword \"in\" here.")
}
var index: Int64 = 3
let (table, nextIndex) = parseExprFragment(input, startFrom: index)
if (nextIndex == input.size || input[nextIndex].value != "where") {
diagReport(DiagReportLevel.ERROR, input[nextIndex..nextIndex+1], syntaxMsg,
"Expected keyword \"where\" here.")
}
index = nextIndex + 1 // 跳过where
let (cond, nextIndex2) = parseExprFragment(input, startFrom: index)
if (nextIndex2 == input.size || input[nextIndex2].value != "select") {
diagReport(DiagReportLevel.ERROR, input[nextIndex2..nextIndex2+1], syntaxMsg,
"Expected keyword \"select\" here.")
}
index = nextIndex2 + 1 // 跳过select
let (expr, nextIndex3) = parseExprFragment(input, startFrom: index)
return quote(
for ($(attribute) in $(table)) {
if ($(cond)) {
println($(expr))
}
}
)
}
使用案例:
@linq(from x in 1..=10 where x % 2 == 1 select x * x)
这个例子从 1, 2, ... 10 列表中筛选出奇数,然后返回所有奇数的平方。输出结果为:
1
9
25
49
81
可以看到,宏的实现的很大部分用于解析并校验输入的 Tokens,这对宏的可用性至关重要。实际的 LINQ 语言(以及大多数 DSL)的语法更加复杂,需要一整套解析的机制,通过识别不同的关键字或连接符来决定下一步解析的内容。
动态特性
本章介绍 Cangjie 的动态特性,应用动态特性开发者能够更为优雅的实现一些功能。仓颉的动态特性主要包含反射。
仓颉反射基本介绍
反射指程序可以访问、检测和修改它本身状态或行为的一种机制。
反射这一动态特性有以下的优点:
-
提高了程序的灵活性和扩展性。
-
程序能够在运行时获悉各种对象的类型,对其成员进行枚举、调用等操作。
-
允许在运行时创建新类型,无需提前硬编码。
但使用反射调用,其性能通常低于直接调用,因此反射机制主要应用于对灵活性和拓展性要求很高的系统框架上。
如何获得 TypeInfo
对于仓颉的反射特性,需要知道 TypeInfo 这一类型,这个核心类型中记录任意类型的类型信息,并且定义了方法用于获取类型信息、设置值等。当然为了便于用户操作仓颉还提供了 ClassTypeInfo、PrimitiveTypeInfo、ParameterInfo 等一系列的信息类型。
可以使用三种静态的 of 方法来生成 TypeInfo 信息类。
public class TypeInfo {
public static func of(a: Any): TypeInfo
public static func of(a: Object): ClassTypeInfo
public static func of<T>(): TypeInfo
}
当采用入参为 Any 和 Object 类型的 of 函数,输出为该实例的运行时类型信息,采用泛型参数的 of 函数则会返回传入参数的静态类型信息。两种方法产生的信息完全相同,但不保证一定对应同一对象。
例如可以用反射来获取一个自定义类型的类型信息。
import std.reflect.*
class Foo {}
main() {
let a: Foo = Foo()
let info: TypeInfo = TypeInfo.of(a)
let info2: TypeInfo = TypeInfo.of<Foo>()
println(info)
println(info2)
}
编译并执行上面的代码,会输出:
default.Foo
default.Foo
此外 TypeInfo 还提供了静态函数 get,该接口可通过传入的类型名称获取 TypeInfo。
public class TypeInfo {
public static func get(qualifiedName: String): TypeInfo
}
请注意,传入参数需要符合 module.package.type 的完全限定模式规则。对于编译器预导入的类型,包含 core 包中的类型和编译器内置类型,例如 primitive type、Option、Iterable 等,查找的字符串需要直接使用其类型名,不能带包名和模块名前缀。当运行时无法查询到对应类型的实例,则会抛出 InfoNotFoundException。
let t1: TypeInfo = TypeInfo.get("Int64")
let t1: TypeInfo = TypeInfo.get("default.Foo")
let t2: TypeInfo = TypeInfo.get("std.socket.TcpSocket")
let t3: TypeInfo = TypeInfo.get("net.http.ServerBuilder")
采用这种方式时无法获取一个未实例化的泛型类型。
import std.collection.*
import std.reflect.*
class A<T> {
A(public let t: T) {}
}
class B<T> {
B(public let t: T) {}
}
main() {
let aInfo: TypeInfo = TypeInfo.get("default.A<Int64>")// Error,`default.A<Int64>` is not instantiated,will throw InfoNotFoundException
let b: B<Int64> = B<Int64>(1)
let bInfo: TypeInfo = TypeInfo.get("default.B<Int64>")// Ok `default.B<Int64>` has been instantiated.
}
如何使用反射访问成员
在获取到对应的类型信息类即 TypeInfo 后,便可以通过其相应接口访问对应类的实例成员以及静态成员。此外 TypeInfo 的子类 ClassTypeInfo 还提供了接口用于访问类公开的构造函数以及它的成员变量、属性、函数。仓颉的反射被设计为只能访问到类型内 public 的成员,意味着 private 和 protected 修饰的成员在反射中是不可见的。
例如当想要在运行时对类的某一实例成员变量进行获取与修改。
import std.reflect.*
public class Foo {
public static var param1 = 20
public var param2 = 10
}
main(): Unit{
let obj = Foo()
let info = TypeInfo.of(obj)
let staticVarInfo = info.getStaticVariable("param1")
let instanceVarInfo = info.getInstanceVariable("param2")
println("成员变量初始值")
print("Foo 的静态成员变量 ${staticVarInfo} = ")
println((staticVarInfo.getValue() as Int64).getOrThrow())
print("obj 的实例成员变量 ${instanceVarInfo} = ")
println((instanceVarInfo.getValue(obj) as Int64).getOrThrow())
println("更改成员变量")
staticVarInfo.setValue(8)
instanceVarInfo.setValue(obj, 25)
print("Foo 的静态成员变量 ${staticVarInfo} = ")
println((staticVarInfo.getValue() as Int64).getOrThrow())
print("obj 的实例成员变量 ${instanceVarInfo} = ")
println((instanceVarInfo.getValue(obj) as Int64).getOrThrow())
return
}
编译并执行上面的代码,会输出:
成员变量初始值
Foo 的静态成员变量 static param1: Int64 = 20
obj 的实例成员变量 param2: Int64 = 10
更改成员变量
Foo 的静态成员变量 static param1: Int64 = 8
obj 的实例成员变量 param2: Int64 = 25
同时也可以通过反射对属性进行检查以及修改。
import std.reflect.*
public class Foo {
public let _p1: Int64 = 1
public prop p1: Int64 {
get() { _p1 }
}
public var _p2: Int64 = 2
public mut prop p2: Int64 {
get() { _p2 }
set(v) { _p2 = v }
}
}
main(): Unit{
let obj = Foo()
let info = TypeInfo.of(obj)
let instanceProps = info.instanceProperties.toArray()
println("obj的实例成员属性包含${instanceProps}")
let PropInfo1 = info.getInstanceProperty("p1")
let PropInfo2 = info.getInstanceProperty("p2")
println((PropInfo1.getValue(obj) as Int64).getOrThrow())
println((PropInfo2.getValue(obj) as Int64).getOrThrow())
if (PropInfo1.isMutable()) {
PropInfo1.setValue(obj, 10)
}
if (PropInfo2.isMutable()) {
PropInfo2.setValue(obj, 20)
}
println((PropInfo1.getValue(obj) as Int64).getOrThrow())
println((PropInfo2.getValue(obj) as Int64).getOrThrow())
return
}
编译并执行上面的代码,会输出:
obj 的实例成员属性包含[prop p1: Int64, mut prop p2: Int64]
1
2
1
20
还可以通过反射机制进行函数调用。
import std.reflect.*
public class Foo {
public static func f1(v0: Int64, v1: Int64): Int64 {
return v0 + v1
}
}
main(): Unit {
var num = 0
let intInfo = TypeInfo.of<Int64>()
let funcInfo = TypeInfo.of<Foo>().getStaticFunction("f1", intInfo, intInfo)
num = (funcInfo.apply(TypeInfo.of<Foo>(), [1, 1]) as Int64).getOrThrow()
println(num)
}
编译并执行上面的代码,会输出:
2
注解
仓颉中提供了一些内置编译标记用来支持一些特殊情况的处理。
确保正确使用整数运算溢出策略的内置编译标记
仓颉中提供三种内置编译标记来控制整数溢出的处理策略,即 @OverflowThrowing,@OverflowWrapping 和 @OverflowSaturating ,这些编译标记当前只能标记于函数声明之上,作用于函数内的整数运算和整型转换。它们分别对应以下三种溢出处理策略:
-
抛出异常(throwing):当整数运算溢出时,抛出异常。
@OverflowThrowing func add(a: Int8, b: Int8){ return a + b } main() { add(100,29) /* 100 + 29 在数学上等于 129, * 在 Int8 的表示范围上发生了上溢出, * 程序抛出异常 */ 0 }需要注意的是,对于整数溢出行为是 throwing 的场景,若整数溢出可提前在编译期检测出来,则编译器会直接给出报错。
@OverflowThrowing main() { let res: Int8 = Int8(100) + Int8(29) // Error, arithmetic operation '+' overflow // 100 + 29 在数学上等于 129,在 Int8 的表示范围上发生了上溢出,编译器检测出来并报错 let con: UInt8 = UInt8(-132) // Error, integer type conversion overflow /* -132 在 UInt8 的表示范围上发生了下溢出, * 程序抛出异常 */ 0 } -
高位截断(wrapping):当整数运算的结果超出用于接收它的内存空间所能表示的数据范围时,则截断超出该内存空间的部分。
@OverflowWrapping main() { let res: Int8 = Int8(105) * Int8(4) /* 105 * 4 在数学上等于 420, * 对应的二进制为 1 1010 0100, * 超过了用于接收该结果的 8 位内存空间, * 截断后的结果在二进制上表示为 1010 0100, * 对应为有符号整数 -92 */ let temp: Int16 = Int16(-132) let con: UInt8 = UInt8(temp) /* -132 对应的二进制为 1111 1111 0111 1100, * 超过了用于接收该结果的 8 位内存空间, * 截断后的结果在二进制上表示为 0111 1100 * 对应为有符号整数 124 */ 0 } -
饱和(saturating):当整数运算溢出时,选择对应固定精度的极值作为结果。
@OverflowSaturating main() { let res: Int8 = Int8(-100) - Int8(45) /* -100 - 45 在数学上等于 -145, * 在 Int8 的表示范围上发生了下溢出, * 选择 Int8 的最小值 -128 作为结果 */ let con: Int8 = Int8(1024) /* 1024 在 Int8 的表示范围上发生了上溢出, * 选择 Int8 的最大值 127 作为结果 */ 0 }
默认情况下(即未标注该类内置编译标记时),采取抛出异常(@OverflowThrowing)的处理策略。
实际情况下需要根据业务场景的需求正确选择溢出策略。例如要在 Int32 上实现某种安全运算,使得计算结果和计算过程在数学上相等,就需要使用抛出异常的策略。
【反例】
// 计算结果被高位截断
@OverflowWrapping
func operation(a: Int32, b: Int32): Int32 {
a + b // No exception will be thrown when overflow occurs
}
该错误例子使用了高位截断的溢出策略,比如当传入的参数 a 和 b 较大导致结果溢出时,会产生高位截断的情况,导致函数返回结果和计算表达式 a + b 在数学上不是相等关系。
【正例】
// 安全
@OverflowThrowing
func operation(a: Int32, b: Int32): Int32 {
a + b
}
main() {
try {
operation(Int32.Max, 1)
} catch (e: ArithmeticException) {
println(e.message)
//Handle error
}
0
}
该正确例子使用了抛出异常的溢出策略,当传入的参数 a 和 b 较大导致整数溢出时,operation 函数会抛出异常。
下面总结了可能造成整数溢出的数学操作符。
| 操作符 | 溢出 | 操作符 | 溢出 | 操作符 | 溢出 | 操作符 | 溢出 |
|---|---|---|---|---|---|---|---|
+ | Y | -= | Y | << | N | < | N |
- | Y | *= | Y | >> | N | > | N |
* | Y | /= | Y | & | N | >= | N |
/ | Y | %= | N | | | N | <= | N |
% | N | <<= | N | ^ | N | == | N |
++ | Y | >>= | N | **= | Y | ||
-- | Y | &= | N | ! | N | ||
= | N | |= | N | != | N | ||
+= | Y | ^= | N | ** | Y |
测试框架内置编译标记
在测试中使用 mock 时,当 mock 的是与静态和顶级声明相关内容时,需要通过测试框架内置编译标记来指示编译器做一些准备工作,才能正常使用 mock。
测试框架内置编译标记 @EnsurePreparedToMock 只能在 lambda 表达式上使用,lambda 表达式调用静态和顶级声明作为其最后一个表达式,然后编译器将准备这个声明以供 mock。
例如:
package prod
public func test(a: String, b: String): String {
a + b
}
package test
import prod.*
import std.unittest.mock.*
@Test
public class TestA {
@TestCase
func case1(): Unit {
{ =>
let matcher0 = Matchers.eq("z")
let matcher1 = Matchers.eq("y")
let stubCall = @EnsurePreparedToMock { => return(test(matcher0.value(), matcher1.value())) }
ConfigureMock.stubFunction(stubCall,[matcher0.withDescription(#"eq("z")"#), matcher1.withDescription(#"eq("y")"#)], Option<String>.None, "test", #"test("z", "y")"#, 15)
}().returns("mocked value")
println(test("z", "y")) // prints "mocked value"
}
}
上述示例中,ConfigureMock.stubFunction 为函数 test 注册了一个桩,returns 为定义的桩设置返回值。
注意:
通常,标准库的 mock 接口可用于定义 mock 声明,并且在常规情况下不应直接使用此内置注释。相反,应该使用相应的标准库函数。这些标准库函数在内部使用
@EnsurePreparedToMock。
使用 @EnsurePreparedToMock 注解的约束:
- 仅当使用测试和 mock 相关编译选项进行编译时才允许使用(使用
--test/--test-only和--mock=on/--mock=runtime-error编译选项)。 - 只能应用于具有合适的最后一个表达式的 lambda。
- lambda 的最后一个表达式应该是调用、成员访问或引用表达式,要求是:
- 顶级函数或变量;
- 静态函数、属性或字段;
- foreign 声明;
- 不是局部函数或变量;
- 非私有声明;
- 不是 const 表达式或声明;
- 必须是来自通过 mock 模式构建的包的声明。
自定义注解
自定义注解机制用来让反射(详见反射章节)获取标注内容,目的是在类型元数据之外提供更多的有用信息,以支持更复杂的逻辑。
开发者可以通过自定义类型标注 @Annotation 方式创建自己的自定义注解。@Annotation 只能修饰 class,并且不能是 abstract 或 open 或 sealed 修饰的 class。当一个 class 声明它标注了 @Annotation,那么它必须要提供至少一个 const init 函数,否则编译器会报错。
开发者也可以使用 @!Annotation 的语法创建自定义注解。这是为后续功能预留的语法,当前版本下与 @Annotation 等效。
下面的例子定义了一个自定义注解 @Version,并用其修饰 A, B 和 C。在 main 中,通过反射获取到类上的 @Version 注解信息,并将其打印出来。
package pkg
import std.reflect.TypeInfo
@Annotation
public class Version {
let code: String
const init(code: String) {
this.code = code
}
}
@Version["1.0"]
class A {}
@Version["1.1"]
class B {}
main() {
let objects = [A(), B()]
for (obj in objects) {
let annOpt = TypeInfo.of(obj).findAnnotation<Version>()
if (let Some(ann) <- annOpt) {
println(ann.code)
}
}
}
编译并执行上述代码,输出结果为:
1.0
1.1
注解信息需要在编译时生成信息并绑定到类型上,自定义注解在使用时必须使用 const init 构建出合法的实例。注解声明语法与声明宏语法一致,后面的 [] 括号中需要按顺序或命名参数规则传入参数,且参数必须是 const 表达式(详见常量求值章节)。对于拥有无参构造函数的注解类型,声明时允许省略括号。
下面的例子中定义了一个拥有无参 const init 的自定义注解 @Marked,使用时 @Marked 和 @Marked[] 这两种写法均可。
package pkg
import std.reflect.TypeInfo
@Annotation
public class Marked {
const init() {}
}
@Marked
class A {}
@Marked[]
class B {}
main() {
if (TypeInfo.of(A()).findAnnotation<Marked>().isSome()) {
println("A is Marked")
}
if (TypeInfo.of(B()).findAnnotation<Marked>().isSome()) {
println("B is Marked")
}
}
编译并执行上述代码,输出结果为:
A is Marked
B is Marked
对于同一个注解目标,同一个注解类不允许声明多次,即不可重复。
@Marked
@Marked // Error
class A {}
Annotation 不会被继承,因此一个类型的注解元数据只会来自它定义时声明的注解。如果需要父类型的注解元数据信息,需要开发者自己用反射接口查询。
下面的例子中,A 被 @Marked 注解修饰,B 继承 A,但是 B 没有 A 的注解。
package pkg
import std.reflect.TypeInfo
@Annotation
public class Marked {
const init() {}
}
@Marked
open class A {}
class B <: A {}
main() {
if (TypeInfo.of(A()).findAnnotation<Marked>().isSome()) {
println("A is Marked")
}
if (TypeInfo.of(B()).findAnnotation<Marked>().isSome()) {
println("B is Marked")
}
}
编译并执行上述代码,输出结果为:
A is Marked
自定义注解可以用在类型声明(class、struct、enum、interface)、成员函数/构造函数中的参数、构造函数声明、成员函数声明、成员变量声明、成员属性声明。也可以限制自己可以使用的位置,这样可以减少开发者的误用,这类注解需要在声明 @Annotation 时标注 target 参数,参数类型为 Array<AnnotationKind>。其中,AnnotationKind 是标准库中定义的 enum。当没有限定 target 的时候,该自定义注解可以用在以上全部位置。当限定 target 时,只能用在声明的列表中。
public enum AnnotationKind {
| Type
| Parameter
| Init
| MemberProperty
| MemberFunction
| MemberVariable
}
下面的例子中,自定义注解通过 target 限定只能用在成员函数上,用在其他位置会编译报错。
@Annotation[target: [MemberFunction]]
public class Marked {
const init() {}
}
class A {
@Marked // Ok, member funciton
func marked() {}
}
@Marked // Error, type
class B {}
main() {}
仓颉-C 互操作
为了兼容已有的生态,仓颉支持调用 C 语言的函数,也支持 C 语言调用仓颉的函数。
仓颉调用 C 的函数
在仓颉中要调用 C 的函数,需要在仓颉语言中用 @C 和 foreign 关键字声明这个函数,但 @C 在修饰 foreign 声明的时候,可以省略。
举个例子,假设要调用 C 的 rand 和 printf 函数,它的函数签名如下:
// stdlib.h
int rand();
// stdio.h
int printf (const char *fmt, ...);
那么在仓颉中调用这两个函数的方式如下:
// declare the function by `foreign` keyword, and omit `@C`
foreign func rand(): Int32
foreign func printf(fmt: CString, ...): Int32
main() {
// call this function by `unsafe` block
let r = unsafe { rand() }
println("random number ${r}")
unsafe {
var fmt = LibC.mallocCString("Hello, No.%d\n")
printf(fmt, 1)
LibC.free(fmt)
}
}
需要注意的是:
foreign修饰函数声明,代表该函数为外部函数。被foreign修饰的函数只能有函数声明,不能有函数实现。foreign声明的函数,参数和返回类型必须符合 C 和仓颉数据类型之间的映射关系(详情请参见类型映射)。- 由于 C 侧函数很可能产生不安全操作,所以调用
foreign修饰的函数需要被unsafe块包裹,否则会发生编译错误。 @C修饰的foreign关键字只能用来修饰函数声明,不可用来修饰其他声明,否则会发生编译错误。@C只支持修饰foreign函数、顶层作用域中的非泛型函数和struct类型。foreign函数不支持命名参数和参数默认值。foreign函数允许变长参数,使用...表达,只能用于参数列表的最后。变长参数均需要满足CType约束,但不必是同一类型。- 仓颉(CJNative 后端)虽然提供了栈扩容能力,但是由于 C 侧函数实际使用栈大小仓颉无法感知,所以 ffi 调用进入 C 函数后,仍然存在栈溢出的风险(可能导致程序运行时崩溃或者产生不可预期的行为),需要开发者根据实际情况,修改
cjStackSize的配置。
一些不合法的 foreign 声明的示例代码如下:
foreign func rand(): Int32 { // compiler error
return 0
}
@C
foreign var a: Int32 = 0 // compiler error
@C
foreign class A{} // compiler error
@C
foreign interface B{} // compiler error
CFunc
仓颉中的 CFunc 指可以被 C 语言代码调用的函数,共有以下三种形式:
@C修饰的foreign函数@C修饰的仓颉函数- 类型为
CFunc的lambda表达式,与普通的 lambda 表达式不同,CFunc lambda不能捕获变量。
// Case 1
foreign func free(ptr: CPointer<Int8>): Unit
// Case 2
@C
func callableInC(ptr: CPointer<Int8>) {
print("This function is defined in Cangjie.")
}
// Case 3
let f1: CFunc<(CPointer<Int8>) -> Unit> = { ptr =>
print("This function is defined with CFunc lambda.")
}
以上三种形式声明/定义的函数的类型均为 CFunc<(CPointer<Int8>) -> Unit>。CFunc 对应 C 语言的函数指针类型。这个类型为泛型类型,其泛型参数表示该 CFunc 入参和返回值类型,使用方式如下:
foreign func atexit(cb: CFunc<() -> Unit>): Int32
与 foreign 函数一样,其他形式的 CFunc 的参数和返回类型必须满足 CType 约束,且不支持命名参数和参数默认值。
CFunc 在仓颉代码中被调用时,需要处在 unsafe 上下文中。
仓颉语言支持将一个 CPointer<T> 类型的变量类型转换为一个具体的 CFunc,其中 CPointer 的泛型参数 T 可以是满足 CType 约束的任意类型,使用方式如下:
main() {
var ptr = CPointer<Int8>()
var f = CFunc<() -> Unit>(ptr)
unsafe { f() } // core dumped when running, because the pointer is nullptr.
}
注意:
将一个指针强制类型转换为
CFunc并进行函数调用是危险行为,需要用户保证指针指向的是一个切实可用的函数地址,否则将发生运行时错误。
inout 参数
在仓颉中调用 CFunc 时,其实参可以使用 inout 关键字修饰,组成引用传值表达式,此时,该参数按引用传递。引用传值表达式的类型为 CPointer<T>,其中 T 为 inout 修饰的表达式的类型。
引用传值表达式具有以下约束:
- 仅可用于对
CFunc的调用处。 - 其修饰对象的类型必须满足
CType约束,但不可以是CString。 - 其修饰对象不可以是用
let定义的,不可以是字面量、入参、其他表达式的值等临时变量。 - 通过仓颉侧引用传值表达式传递到 C 侧的指针,仅保证在函数调用期间有效,即此种场景下 C 侧不应该保存指针以留作后用。
inout 修饰的变量,可以是定义在顶层作用域中的变量、局部变量、struct 中的成员变量,但不能直接或间接来源于 class 的实例成员变量。
下面是一个例子:
foreign func foo1(ptr: CPointer<Int32>): Unit
@C
func foo2(ptr: CPointer<Int32>): Unit {
let n = unsafe { ptr.read() }
println("*ptr = ${n}")
}
let foo3: CFunc<(CPointer<Int32>) -> Unit> = { ptr =>
let n = unsafe { ptr.read() }
println("*ptr = ${n}")
}
struct Data {
var n: Int32 = 0
}
class A {
var data = Data()
}
main() {
var n: Int32 = 0
unsafe {
foo1(inout n) // OK
foo2(inout n) // OK
foo3(inout n) // OK
}
var data = Data()
var a = A()
unsafe {
foo1(inout data.n) // OK
foo1(inout a.data.n) // Error, n is derived indirectly from instance member variables of class A
}
}
注意:
使用宏扩展特性时,在宏的定义中,暂时不能使用
inout参数特性。
unsafe
在引入与 C 语言的互操作过程中,同时也引入了 C 的许多不安全因素,因此在仓颉中使用 unsafe 关键字,用于对跨 C 调用的不安全行为进行标识。
关于 unsafe 关键字,有以下几点说明:
unsafe可以修饰函数、表达式,也可以修饰一段作用域。- 被
@C修饰的函数,被调用处需要在unsafe上下文中。 - 在调用
CFunc时,使用处需要在unsafe上下文中。 foreign函数在仓颉中进行调用,被调用处需要在unsafe上下文中。- 当被调用函数被
unsafe修饰时,被调用处需要在unsafe上下文中。
使用方式如下:
foreign func rand(): Int32
@C
func foo(): Unit {
println("foo")
}
var foo1: CFunc<() -> Unit> = { =>
println("foo1")
}
main(): Int64 {
unsafe {
rand() // Call foreign func.
foo() // Call @C func.
foo1() // Call CFunc var.
}
0
}
需要注意的是,普通 lambda 无法传递 unsafe 属性,当 unsafe 的 lambda 逃逸后,可以不在 unsafe 上下文中直接调用而未产生任何编译错误。当需要在 lambda 中调用 unsafe 函数时,建议在 unsafe 块中进行调用,参考如下用例:
unsafe func A(){}
unsafe func B(){
var f = { =>
unsafe { A() } // Avoid calling A() directly without unsafe in a normal lambda.
}
return f
}
main() {
var f = unsafe{ B() }
f()
println("Hello World")
}
调用约定
函数调用约定描述调用者和被调用者双方如何进行函数调用(如参数如何传递、栈由谁清理等),函数调用和被调用双方必须使用相同的调用约定才能正常运行。仓颉编程语言通过 @CallingConv 来表示各种调用约定,支持的调用约定如下:
- CDECL:
CDECL表示 clang 的 C 编译器在不同平台上默认使用的调用约定。 - STDCALL:
STDCALL表示 Win32 API 使用的调用约定。
通过 C 语言互操作机制调用的 C 函数,未指定调用约定时将采用默认的 CDECL 调用约定。如下调用 C 标准库函数 rand 示例:
@CallingConv[CDECL] // Can be omitted in default.
foreign func rand(): Int32
main() {
println(unsafe { rand() })
}
@CallingConv 只能用于修饰 foreign 块、单个 foreign 函数和顶层作用域中的 CFunc 函数。当 @CallingConv 修饰 foreign 块时,会为 foreign 块中的每个函数分别加上相同的 @CallingConv 修饰。
使用说明
-
操作系统线程局部变量使用约束
仓颉和 C 语言互操作时,使用操作系统线程的局部变量存在风险,说明如下:
- 线程局部变量包括 C 语言提供的
thread_local定义的变量和使用pthread_key_create创建的变量。 - 仓颉具备仓颉线程调度能力,支持仓颉线程的切换和恢复,仓颉线程被调度到哪个操作系统线程是随机的,从而在仓颉线程上调用其他语言的线程局部变量是有风险的。
如下示例中,仓颉调用 C 语言的线程局部变量存在风险:
// C language logic using thread_local static thread_local int64_t count = 0; int64_t getCount() { count++; return count; }foreign func getCount(): Int64 // Cangjie invokes the preceding C language logic spawn { let r1 = unsafe { getCount() } // r1 equals 1 sleep(Duration.second * 10) let r2 = unsafe { getCount() } // r2 may not be equal to 2 } - 线程局部变量包括 C 语言提供的
-
线程绑定使用约束
仓颉调用 C 语言执行互操作逻辑时,仓颉线程调度到哪个操作系统线程是随机的,线程优先级和线程亲和性等与线程绑定的行为不建议使用。
-
同步原语使用说明
仓颉调用 C 语言执行互操作逻辑时,当前这个仓颉线程会等待互操作逻辑执行结束,不建议在其他语言中出现可能导致长时间等待的阻塞性行为。
-
对进程 fork 场景的支持说明
仓颉调用 C 语言执行互操作逻辑时,如果在 C 语言中以
fork()方式创建子进程,子进程中不支持执行仓颉逻辑。同一进程中其他操作系统线程不受影响。 -
进程退出时的说明
仓颉调用 C 语言执行互操作逻辑时,如果在 C 语言中退出进程,进程内共享的资源已经释放,可能导致非法访问等错误。
类型映射
基础类型
仓颉与 C 语言支持基本数据类型的映射,总体原则是:
- 仓颉的类型不包含指向托管内存的引用类型;
- 仓颉的类型和 C 的类型具有同样的内存布局。
比如说,一些基本的类型映射关系如下:
| Cangjie Type | C Type | Size (byte) |
|---|---|---|
Unit | void | 0 |
Bool | bool | 1 |
UInt8 | char | 1 |
Int8 | int8_t | 1 |
UInt8 | uint8_t | 1 |
Int16 | int16_t | 2 |
UInt16 | uint16_t | 2 |
Int32 | int32_t | 4 |
UInt32 | uint32_t | 4 |
Int64 | int64_t | 8 |
UInt64 | uint64_t | 8 |
IntNative | ssize_t | platform dependent |
UIntNative | size_t | platform dependent |
Float32 | float | 4 |
Float64 | double | 8 |
说明:
int类型、long类型等由于其在不同平台上的不确定性,需要程序员自行指定对应仓颉编程语言类型。在 C 互操作场景中,与 C 语言类似,Unit类型仅可作为CFunc中的返回类型和CPointer的泛型参数。
仓颉也支持与 C 语言的结构体和指针类型的映射。
结构体
对于结构体类型,仓颉用 @C 修饰的 struct 来对应。比如说 C 语言里面有这样的一个结构体:
typedef struct {
long long x;
long long y;
long long z;
} Point3D;
那么它对应的仓颉类型可以这样定义:
@C
struct Point3D {
var x: Int64 = 0
var y: Int64 = 0
var z: Int64 = 0
}
如果 C 语言里有这样的一个函数:
Point3D addPoint(Point3D p1, Point3D p2);
那么对应的,在仓颉里面可以这样声明这个函数:
foreign func addPoint(p1: Point3D, p2: Point3D): Point3D
用 @C 修饰的 struct 必须满足以下限制:
- 成员变量的类型必须满足
CType约束 - 不能实现或者扩展
interfaces - 不能作为
enum的关联值类型 - 不允许被闭包捕获
- 不能具有泛型参数
用 @C 修饰的 struct 自动满足 CType 约束。
指针
对于指针类型,仓颉提供 CPointer<T> 类型来对应 C 侧的指针类型,其泛型参数 T 需要满足 CType 约束。比如对于 malloc 函数,在 C 里面的签名为:
void* malloc(size_t size);
那么在仓颉中,它可以声明为:
foreign func malloc(size: UIntNative): CPointer<Unit>
CPointer 可以进行读写、偏移计算、判空以及转为指针的整型形式等,详细 API 可以参考《仓颉编程语言库 API》。其中读写和偏移计算为不安全行为,当不合法的指针调用这些函数时,可能发生未定义行为,这些 unsafe 函数需要在 unsafe 块中调用。
CPointer 的使用示例如下:
foreign func malloc(size: UIntNative): CPointer<Unit>
foreign func free(ptr: CPointer<Unit>): Unit
@C
struct Point3D {
var x: Int64
var y: Int64
var z: Int64
init(x: Int64, y: Int64, z: Int64) {
this.x = x
this.y = y
this.z = z
}
}
main() {
let p1 = CPointer<Point3D>() // create a CPointer with null value
if (p1.isNull()) { // check if the pointer is null
print("p1 is a null pointer")
}
let sizeofPoint3D: UIntNative = 24
var p2 = unsafe { malloc(sizeofPoint3D) } // malloc a Point3D in heap
var p3 = unsafe { CPointer<Point3D>(p2) } // pointer type cast
unsafe { p3.write(Point3D(1, 2, 3)) } // write data through pointer
let p4: Point3D = unsafe { p3.read() } // read data through pointer
let p5: CPointer<Point3D> = unsafe { p3 + 1 } // offset of pointer
unsafe { free(p2) }
}
仓颉语言支持 CPointer 之间的强制类型转换,转换前后的 CPointer 的泛型参数 T 均需要满足 CType 的约束,使用方式如下:
main() {
var pInt8 = CPointer<Int8>()
var pUInt8 = CPointer<UInt8>(pInt8) // CPointer<Int8> convert to CPointer<UInt8>
0
}
仓颉语言支持将一个 CFunc 类型的变量类型转换为一个具体的 CPointer,其中 CPointer 的泛型参数 T 可以是满足 CType 约束的任意类型,使用方式如下:
foreign func rand(): Int32
main() {
var ptr = CPointer<Int8>(rand)
0
}
注意:
将一个
CFunc强制类型转换为指针通常是安全的,但是不应该对转换后的指针执行任何的read,write操作,可能会导致运行时错误。
数组
仓颉使用 VArray 类型与 C 的数组类型映射,VArray 可以作为函数参数和 @C struct 成员。当 VArray<T, $N> 中的元素类型 T 满足 CType 约束时, VArray<T, $N> 类型也满足 CType 约束。
作为函数参数类型:
当 VArray 作为 CFunc 的参数时, CFunc 的函数签名仅可以是 CPointer<T> 类型或 VArray<T, $N> 类型。当函数签名中的参数类型为 VArray<T, $N> 时,传递的参数仍以 CPointer<T> 形式传递。
VArray 作为参数的使用示例如下:
foreign func cfoo1(a: CPointer<Int32>): Unit
foreign func cfoo2(a: VArray<Int32, $3>): Unit
对应的 C 侧函数定义可以是:
void cfoo1(int *a) { ... }
void cfoo2(int a[3]) { ... }
调用 CFunc 时,需要通过 inout 修饰 VArray 类型变量:
var a: VArray<Int32, $3> = [1, 2, 3]
unsafe {
cfoo1(inout a)
cfoo2(inout a)
}
VArray 不允许作为 CFunc 的返回值类型。
作为 @C struct 成员:
当 VArray 作为 @C struct 成员时,它的内存布局与 C 侧的结构体排布一致,需要保证仓颉侧声明长度与类型也与 C 完全一致:
struct S {
int a[2];
int b[0];
}
在仓颉中,可以声明为如下结构体与 C 代码对应:
@C
struct S {
var a = VArray<Int32, $2>(repeat: 0)
var b = VArray<Int32, $0>(repeat: 0)
}
注意:
C 语言中允许结构体的最后一个字段为未指明长度的数组类型,该数组被称为柔性数组(flexible array),仓颉不支持包含柔性数组的结构体的映射。
字符串
特别地,对于 C 语言中的字符串类型,仓颉中设计了一个 CString 类型来对应。为简化为 C 语言字符串的操作,CString 提供了以下成员函数:
init(p: CPointer<UInt8>)通过 CPointer 构造一个 CStringfunc getChars()获取字符串的地址,类型为CPointer<UInt8>func size(): Int64计算该字符串的长度func isEmpty(): Bool判断该字符串的长度是否为 0,如果字符串的指针为空返回 truefunc isNotEmpty(): Bool判断该字符串的长度是否不为 0,如果字符串的指针为空返回 falsefunc isNull(): Bool判断该字符串的指针是否为 nullfunc startsWith(str: CString): Bool判断该字符串是否以 str 开头func endsWith(str: CString): Bool判断该字符串是否以 str 结尾func equals(rhs: CString): Bool判断该字符串是否与 rhs 相等func equalsLower(rhs: CString): Bool判断该字符串是否与 rhs 相等,忽略大小写func subCString(start: UInt64): CString从 start 开始截取子串,返回的子串存储在新分配的空间中func subCString(start: UInt64, len: UInt64): CString从 start 开始截取长度为 len 的子串,返回的子串存储在新分配的空间中func compare(str: CString): Int32该字符串与 str 比较,返回结果与 C 语言的strcmp(this, str)一样func toString(): String用该字符串构造一个新的 String 对象func asResource(): CStringResource获取 CString 的 Resource 类型
另外,将 String 类型转换为 CString 类型,可以通过调用 LibC 中的 mallocCString 接口,使用完成后需要对 CString 进行释放。
CString 的使用示例如下:
foreign func strlen(s: CString): UIntNative
main() {
var s1 = unsafe { LibC.mallocCString("hello") }
var s2 = unsafe { LibC.mallocCString("world") }
let t1: Int64 = s1.size()
let t2: Bool = s2.isEmpty()
let t3: Bool = s1.equals(s2)
let t4: Bool = s1.startsWith(s2)
let t5: Int32 = s1.compare(s2)
let length = unsafe { strlen(s1) }
unsafe {
LibC.free(s1)
LibC.free(s2)
}
}
sizeOf/alignOf
仓颉还提供了 sizeOf 和 alignOf 两个函数,用于获取上述 C 互操作类型的内存占用和内存对齐数值(单位:字节),函数声明如下:
public func sizeOf<T>(): UIntNative where T <: CType
public func alignOf<T>(): UIntNative where T <: CType
使用示例:
@C
struct Data {
var a: Int64 = 0
var b: Float32 = 0.0
}
main() {
println(sizeOf<Data>())
println(alignOf<Data>())
}
在 64 位机器上运行,将输出:
16
8
CType
除类型映射一节提供的与 C 侧类型进行映射的类型外,仓颉还提供了一个 CType 接口,接口本身不包含任何方法,它可以作为所有 C 互操作支持的类型的父类型,便于在泛型约束中使用。
需要注意的是:
CType接口是仓颉中的一个接口类型,它本身不满足CType约束;CType接口不允许被继承、扩展;CType接口不会突破子类型的使用限制。
CType 的使用示例如下:
func foo<T>(x: T): Unit where T <: CType {
match (x) {
case i32: Int32 => println(i32)
case ptr: CPointer<Int8> => println(ptr.isNull())
case f: CFunc<() -> Unit> => unsafe { f() }
case _ => println("match failed")
}
}
main() {
var i32: Int32 = 1
var ptr = CPointer<Int8>()
var f: CFunc<() -> Unit> = { => println("Hello") }
var f64 = 1.0
foo(i32)
foo(ptr)
foo(f)
foo(f64)
}
执行结果如下:
1
true
Hello
match failed
C 调用仓颉的函数
仓颉提供 CFunc 类型来对应 C 侧的函数指针类型。C 侧的函数指针可以传递到仓颉,仓颉也可以构造出对应 C 的函数指针的变量传递到 C 侧。
假设一个 C 的库 API 如下:
typedef void (*callback)(int);
void set_callback(callback cb);
对应的,在仓颉里面这个函数可以声明为:
foreign func set_callback(cb: CFunc<(Int32) -> Unit>): Unit
CFunc 类型的变量可以从 C 侧传递过来,也可以在仓颉侧构造出来。在仓颉侧构造 CFunc 类型有两种办法,一个是用 @C 修饰的函数,另外一个是标记为 CFunc 类型的闭包。
@C 修饰的函数,表明它的函数签名是满足 C 的调用规则的,定义还是写在仓颉这边。foreign 修饰的函数定义是在 C 侧的。
注意:
foreign修饰的函数与@C修饰的函数,这两种CFunc的命名不建议使用CJ_(不区分大小写)作为前缀,否则可能与标准库及运行时等编译器内部符号出现冲突,导致未定义行为。
示例如下:
@C
func myCallback(s: Int32): Unit {
println("handle ${s} in callback")
}
main() {
// the argument is a function qualified by `@C`
unsafe { set_callback(myCallback) }
// the argument is a lambda with `CFunc` type
let f: CFunc<(Int32) -> Unit> = { i => println("handle ${i} in callback") }
unsafe { set_callback(f) }
}
假设 C 函数编译出来的库是 "libmyfunc.so",那么需要使用 cjc -L. -lmyfunc test.cj -o test.out 编译命令,使仓颉编译器去链接这个库。最终就能生成想要的可执行程序。
另外,在编译 C 代码时,请打开 -fstack-protector-all/-fstack-protector-strong 栈保护选项,仓颉侧代码默认拥有溢出检查与栈保护功能。在引入 C 代码后,需要同步保证 unsafe 块中的溢出的安全性。
编译选项
使用 C 互操作通常需要手动链接 C 的库,仓颉编译器提供了相应的编译选项。
-
--library-path <value>,-L <value>,-L<value>:指定要链接的库文件所在的目录。--library-path <value>指定的路径会被加入链接器的库文件搜索路径。另外环境变量LIBRARY_PATH中指定的路径也会被加入链接器的库文件搜索路径中,通过--library-path指定的路径会比LIBRARY_PATH中的路径拥有更高的优先级。 -
--library <value>,-l <value>,-l<value>:指定要链接的库文件。给定的库文件会被直接传给链接器,库文件名的格式应为
lib[arg].[extension]。
关于仓颉编译器支持的所有编译选项,详情请参见 "附录 > cjc 编译选项"。
示例
这里演示如何使用 C 互操作以及 write/read 接口对一个结构体进行赋值和读取值。
C 代码如下:
// draw.c
#include<stdio.h>
#include<stdint.h>
typedef struct {
int64_t x;
int64_t y;
} Point;
typedef struct {
float x;
float y;
float z;
} Cube;
int32_t drawPicture(Point* point, Cube* cube) {
point->x = 1;
point->y = 2;
printf("Draw Point finished.\n");
printf("Before draw cube\n");
printf("%f\n", cube->x);
printf("%f\n", cube->y);
printf("%f\n", cube->z);
cube->x = 4.4;
cube->y = 5.5;
cube->z = 6.6;
printf("Draw Cube finished.\n");
}
仓颉代码如下:
// main.cj
@C
struct Point {
var x: Int64 = 0
var y: Int64 = 0
}
@C
struct Cube {
var x: Float32 = 0.0
var y: Float32 = 0.0
var z: Float32 = 0.0
init(x: Float32, y: Float32, z: Float32) {
this.x = x
this.y = y
this.z = z
}
}
foreign func drawPicture(point: CPointer<Point>, cube: CPointer<Cube>): Int32
main() {
let pPoint = unsafe { LibC.malloc<Point>() }
let pCube = unsafe { LibC.malloc<Cube>() }
var cube = Cube(1.1, 2.2, 3.3)
unsafe {
pCube.write(cube)
drawPicture(pPoint, pCube) // in which x, y will be changed
println(pPoint.read().x)
println(pPoint.read().y)
println(pCube.read().x)
println(pCube.read().y)
println(pCube.read().z)
LibC.free(pPoint)
LibC.free(pCube)
}
}
编译仓颉代码的命令如下(以 CJNative 后端为例):
cjc -L . -l draw ./main.cj
其中编译命令中 -L . 表示链接库时从当前目录查找(假设 libdraw.so 存在于当前目录),-l draw 表示链接的库的名字,编译成功后默认生成二进制文件 main,执行二进制文件的命令如下:
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./main
运行结果如下:
Draw Point finished.
Before draw cube
1.100000
2.200000
3.300000
Draw Cube finished.
1
2
4.400000
5.500000
6.600000
cjc 使用
cjc是仓颉编程语言的编译命令,其提供了丰富的功能及对应的编译选项,本章将对基本使用方法进行介绍。
cjc-frontend (仓颉前端编译器)会随 cjc 一起通过 Cangjie SDK 提供,cjc-frontend 能够将仓颉源码编译至仓颉的中间表示 (LLVM IR)。 cjc-frontend 仅进行仓颉代码的前端编译,虽然 cjc-frontend 和 cjc 共享部分编译选项,但编译流程会在前端编译结束时中止。使用 cjc 时仓颉编译器会自动进行前端、后端的编译以及链接工作。cjc-frontend 仅作为前端编译器的实体体现提供,除编译器开发者外,仓颉代码的编译应优先使用 cjc 。
cjc 基本使用方法
本节介绍 cjc 的基本使用方法。关于编译选项详情,请查阅 cjc 编译选项章节。
cjc 的使用方式如下:
cjc [option] file...
假如有一个名为 hello.cj 的仓颉文件:
main() {
println("Hello, World!")
}
可以使用以下命令来编译此文件:
$ cjc hello.cj
此时工作目录下会新增可执行文件 main ,cjc 默认会将给定源代码文件编译成可执行文件,并将可执行文件命名为 main。
以上为不给任何编译选项时 cjc 的默认行为,可以通过使用编译选项来控制 cjc 的行为,例如让 cjc 进行整包编译,又或者是指定输出文件的名字。
cjpm 介绍
CJPM(Cangjie Package Manager) 是仓颉语言的官方包管理工具,用来管理、维护仓颉项目的模块系统,并提供更简易统一的编译入口,支持自定义编译命令。通过包管理器自动依赖管理实现对引入的多版本三方依赖软件进行分析合并,无需开发者担心多版本依赖冲突问题,大大减轻开发者负担;同时提供基于仓颉语言原生的自定义构建机制,允许开发者在构建的不同阶段增加预处理和后处理流程,实现构建流程可灵活定制,能够满足开发者不同业务场景下的编译构建诉求。
cjpm 基本使用方法
通过 cjpm -h 即可查看主界面,由几个板块组成,从上到下分别是: 当前命令说明、使用示例(Usage)、支持的可用命令(Available subcommands)、支持的配置项(Available options)、更多提示内容。
Cangjie Package Manager
Usage:
cjpm [subcommand] [option]
Available subcommands:
init Init a new cangjie module
check Check the dependencies
update Update cjpm.lock
tree Display the package dependencies in the source code
build Compile the current module
run Compile and run an executable product
test Unittest a local package or module
bench Run benchmarks in a local package or module
clean Clean up the target directory
install Install a cangjie binary
uninstall Uninstall a cangjie binary
Available options:
-h, --help help for cjpm
-v, --version version for cjpm
Use "cjpm [subcommand] --help" for more information about a command.
cjpm init 用来初始化一个新的仓颉模块或者工作空间。初始化模块时会默认在当前文件夹创建 cjpm.toml 文件,并且新建 src 源码文件夹,在 src 下生成默认的 main.cj 文件。自定义参数初始化功能支持可以通过 cjpm init -h 查看。
例如:
输入: cjpm init
输出: cjpm init success
cjpm build 用来构建当前仓颉项目,执行该命令前会先检查依赖项,检查通过后调用 cjc 进行构建。支持全量编译、增量编译、交叉编译、并行编译等,更多编译功能支持可以通过 cjpm build -h 查看。通过 cjpm build -V 命令可以打印所有的编译过程命令。
例如:
输入: cjpm build -V
输出:
compile package module1.package1: cjc --import-path target -p "src/package1" --output-type=staticlib -o target/release/module1/libmodule1.package1.a
compile package module1: cjc --import-path target -L target/release/module1 -lmodule1.package1 -p "src" --output-type=exe --output-dir target/release/bin -o main
cjpm build success
cjpm.toml 配置文件说明
配置文件 cjpm.toml 用来配置一些基础信息、依赖项、编译选项等内容,cjpm 主要通过这个文件进行解析执行。
配置文件代码如下所示:
[package] # 单模块配置字段,与 workspace 字段不能同时存在
cjc-version = "0.49.1" # 所需 `cjc` 的最低版本要求,必需
name = "demo" # 模块名及模块 root 包名,必需
description = "nothing here" # 描述信息,非必需
version = "1.0.0" # 模块版本信息,必需
compile-option = "" # 额外编译命令选项,非必需
override-compile-option = "" # 额外全局编译命令选项,非必需
link-option = "" # 链接器透传选项,可透传安全编译命令,非必需
output-type = "executable" # 编译输出产物类型,必需
src-dir = "" # 指定源码存放路径,非必需
target-dir = "" # 指定产物存放路径,非必需
package-configuration = {} # 单包配置选项,非必需
[workspace] # 工作空间管理字段,与 package 字段不能同时存在
members = [] # 工作空间成员模块列表,必需
build-members = [] # 工作空间编译模块列表,需要是成员模块列表的子集,非必需
test-members = [] # 工作空间测试模块列表,需要是编译模块列表的子集,非必需
compile-option = "" # 应用于所有工作空间成员模块的额外编译命令选项,非必需
override-compile-option = "" # 应用于所有工作空间成员模块的额外全局编译命令选项,非必需
link-option = "" # 应用于所有工作空间成员模块的链接器透传选项,非必需
target-dir = "" # 指定产物存放路径,非必需
[dependencies] # 源码依赖配置项,非必需
coo = { git = "xxx",branch = "dev" , version = "1.0.0"} # 导入 `git` 依赖,`version`字段可缺省
doo = { path = "./pro1" ,version = "1.0.0"} # 导入源码依赖,`version`字段可缺省
[test-dependencies] # 测试阶段的依赖配置项,格式和 dependencies 相同,非必需
[script-dependencies] # 构建脚本的依赖配置项,格式和 dependencies 相同,非必需
[replace] # 依赖替换配置项,格式和 dependencies 相同,非必需
[ffi.c] # 导入 C 语言的库依赖,非必需
clib1.path = "xxx"
[profile] # 命令剖面配置项,非必需
build = {} # build 命令配置项
test = {} # test 命令配置项
bench = {} # bench 命令配置项
customized-option = {} # 自定义透传选项
[target.x86_64-unknown-linux-gnu] # 后端和平台隔离配置项,非必需
compile-option = "value1" # 额外编译命令选项,适用于特定 target 的编译流程和指定该 target 作为交叉编译目标平台的编译流程,非必需
override-compile-option = "value2" # 额外全局编译命令选项,适用于特定 target 的编译流程和指定该 target 作为交叉编译目标平台的编译流程,非必需
link-option = "value3" # 链接器透传选项,适用于特定 target 的编译流程和指定该 target 作为交叉编译目标平台的编译流程,非必需
[target.x86_64-w64-mingw32.dependencies] # 适用于对应 target 的源码依赖配置项,非必需
[target.x86_64-w64-mingw32.test-dependencies] # 适用于对应 target 的测试阶段依赖配置项,非必需
[target.x86_64-unknown-linux-gnu.bin-dependencies] # 仓颉二进制库依赖,适用于特定 target 的编译流程和指定该 target 作为交叉编译目标平台的编译流程,非必需
path-option = ["./test/pro0", "./test/pro1"] # 以文件目录形式配置二进制库依赖
[target.x86_64-unknown-linux-gnu.bin-dependencies.package-option] # 以单文件形式配置二进制库依赖
"pro0.xoo" = "./test/pro0/pro0.xoo.cjo"
"pro0.yoo" = "./test/pro0/pro0.yoo.cjo"
"pro1.zoo" = "./test/pro1/pro1.zoo.cjo"
条件编译
开发者可以通过预定义或自定义的条件完成条件编译;仓颉目前支持导入和声明的条件编译。
导入和声明的条件编译
仓颉支持使用内置编译标记 @When 来完成条件编译,编译条件使用 [] 括起来,[] 内支持输入一组或多组编译条件。@When 可以作用于导入节点和除 package 外的声明节点。
使用方法
以内置 os 编译条件为例,其使用方法如下:
@When[os == "Linux"]
class mc{}
main(): Int64 {
var a = mc()
return 0
}
在上面代码中,开发者在 Linux 系统中可以正确编译执行;在非 Linux 系统中,则会遇到找不到 mc 类定义的编译错误。
值得注意的是:
-
仓颉不支持编译条件嵌套,以下写法均不允许:
@When[os == "Windows"] @When[os == "Linux"] // Error, illegal nested when conditional compilation import std.ast.* @When[os == "Windows"] @When[os == "Linux"] // Error, illegal nested when conditional compilation func A(){} -
@When[...]作为内置编译标记,在导入前处理,由宏展开生成的代码中含有@When[...]会编译报错,如:@M0 // macro which returns the input @When[os == "Linux"] // Error, unexpected when conditional compilation directive func A(){}
内置编译条件变量
仓颉提供的内置条件变量有: os、 backend、 arch、 cjc_version、 debug 和 test。
os
os 表示目标平台的操作系统。os 支持 == 和 != 两种操作符。支持的操作系统有:Windows、Linux、macOS。
使用方式如下:
@When[os == "Linux"]
func foo() {
print("Linux, ")
}
@When[os == "Windows"]
func foo() {
print("Windows, ")
}
@When[os != "Windows"]
func fee() {
println("NOT Windows")
}
@When[os != "Linux"]
func fee() {
println("NOT Linux")
}
main() {
foo()
fee()
}
如果在 Windows 环境下编译执行,会得到 Windows, NOT Linux 的信息;如果是在 Linux 环境下,则会得到 Linux, NOT Windows 的信息。
backend
仓颉是多后端语言,backend 表示目标平台的后端类型,用于支持多种后端条件编译。backend 条件支持 == 和 != 两种操作符。
支持的后端有:cjnative、cjvm。
使用方式如下:
@When[backend == "cjnative"]
func foo() {
print("cjnative backend, ")
}
@When[backend == "cjvm"]
func foo() {
print("cjvm backend, ")
}
@When[backend != "cjnative"]
func fee() {
println("NOT cjnative backend")
}
@When[backend != "cjvm"]
func fee() {
println("NOT cjvm backend")
}
main() {
foo()
fee()
}
用 cjnative 后端的发布包编译执行,会得到 cjnative backend, NOT cjvm backend 的信息;用 cjvm 后端的发布包编译执行,则会得到 cjvm backend, NOT cjnative backend 的信息。
arch
arch 表示目标平台的处理器架构。arch 条件支持 == 和 != 两种操作符。
支持的处理器架构有:x86_64、aarch64。
使用方式如下:
@When[arch == "aarch64"]
var arch = "aarch64"
@When[arch == "x86_64"]
var arch = "x86_64"
main() {
println(arch)
}
在 x86_64 架构的目标平台编译执行,会得到 x86_64 的信息;在 aarch64 架构的目标平台编译执行,会得到 aarch64 的信息。
cjc_version
cjc_version 是仓颉内置的条件,开发者可以根据当前仓颉编译器的版本选择要编译的代码。cjc_version 条件支持 ==、!=、>、<、>=、<= 六种操作符,格式为 xx.xx.xx 支持每个 xx 支持 1-2 位数字,计算规则为补位 (补齐 2 位) 比较,例如:0.18.8 < 0.18.11, 0.18.8 == 0.18.08。
使用方式如下:
@When[cjc_version == "0.18.6"]
func foo() {
println("cjc_version equals 0.18.6")
}
@When[cjc_version != "0.18.6"]
func foo() {
println("cjc_version is NOT equal to 0.18.6")
}
@When[cjc_version > "0.18.6"]
func fnn() {
println("cjc_version is greater than 0.18.6")
}
@When[cjc_version <= "0.18.6"]
func fnn() {
println("cjc_version is less than or equal to 0.18.6")
}
@When[cjc_version < "0.18.6"]
func fee() {
println("cjc_version is less than 0.18.6")
}
@When[cjc_version >= "0.18.6"]
func fee() {
println("cjc_version is greater than or equal to 0.18.6")
}
main() {
foo()
fnn()
fee()
}
根据 cjc 的版本,上面代码的执行输出结果会有不同。
debug
debug 表示当前是否启用了调试模式即开启 -g 编译选项, 可以用于在编译代码时进行调试和发布版本之间的切换。debug 条件仅支持逻辑非运算符(!)。
使用方式如下:
@When[debug]
func foo() {
println("debug")
}
@When[!debug]
func foo() {
println("NOT debug")
}
main() {
foo()
}
启用 -g 编译执行会得到 cjc debug 的信息,如果没有启用 -g 编译执行会得到 NOT debug 的信息。
test
test 表示当前是否启用了单元测试选项 --test。test 条件仅支持逻辑非运算符(!)。可以用于区分测试代码与普通代码。
使用方式如下:
@When[test]
@Test
class Tests {
@TestCase
public func case1(): Unit {
@Expect("run", foo())
}
}
func foo() {
"run"
}
@When[!test]
main () {
println(foo())
}
使用 --test 编译执行得到的测试结果,不使用 --test 也可正常完成编译运行得到 run 的信息。
自定义编译条件变量
仓颉允许开发者自定义编译条件变量和取值,自定义的条件变量必须是一个合法的标识符且不允许和内置条件变量同名,其值是一个字符串字面量。自定义条件支持 == 和 != 两种运算符。和内置条件变量不同点在于自定义的条件需要开发者在编译时通过 --cfg 编译选项或者在配置文件 cfg.toml 中定义。
配置自定义条件变量
配置自定义条件变量的方式有两种:在编译选项中直接配置键值对或在配置文件配置键值对。
开发者可以使用 --cfg <value> 以键值对的形式向编译器传递自定义编译条件变量或者指定配置文件 cfg.toml 的搜索路径。
-
选项值需要使用双引号括起来。
-
若选项值中包含
=则会按照键值对的形式直接进行配置(若路径中包含=则需要通过\转义),多个键值对可以使用逗号,分隔。如:$ cjc --cfg "feature = lion, platform = dsp" source.cj -
允许多次使用
--cfg编译选项配置,例如:$ cjc --cfg "feature = lion" --cfg "platform = dsp" source.cj -
不允许多次定义同一个条件变量,例如:
$ cjc --cfg "feature = lion" --cfg "feature = meta" source.cj$ cjc --cfg "feature = lion, feature = meta" source.cj上述两条编译指令都会报错。
-
若选项值中不包含
=或存在通过\转义的=则将选项值作为配置文件cfg.toml的搜索路径传递给编译器,例如:$ cjc --cfg "./cfg" source.cj若
./cfg目录下存在cfg.toml,则编译器会在编译时自动获取./cfg/cfg.toml中配置的自定义编译条件。cfg.toml文件中应采用键值对的方式配置自定义条件变量,每个键值对独占一行,键名是一个合法的仓颉普通标识符,键值是一个双引号括起来的字符串,字符串不支持转义。cfg.toml文件中也支持全行注释和行末注释,例如:feature = "lion" platform = "dsp" # 全行注释 feature = "meta" # 行末注释 -
多次使用
--cfg配置cfg.toml文件的搜索路径时,按照传入的顺序依次搜索cfg.toml文件,若在所有传入的搜索路径下都没有找到cfg.toml文件,则在默认路径下搜索配置文件cfg.toml。 -
多次使用
--cfg编译选项进行配置时,若某次以键值对的形式直接进行配置,则会忽略配置文件cfg.toml中的配置。 -
若未使用
--cfg编译选项,编译器会在默认路径(通过--package或-p指定的package目录或cjc执行目录)下搜索配置文件cfg.toml。
多条件编译
仓颉条件编译允许开发者自由组合多个条件编译选项。支持逻辑运算符组合多个条件,支持括号运算符明确优先级。
使用方式如下:
//source.cj
@When[(test || feature == "lion") && !debug]
func fee() {
println("feature lion")
}
main() {
fee()
}
使用如下编译命令编译运行上段代码:
$ cjc --cfg="feature=lion" source.cj -o runner.out
会得到输出结果如下:
feature lion
部署仓颉运行时
为了使仓颉可执行程序能够在不同的操作系统环境中正常运行,仓颉语言提供了一套运行时(runtime)环境。该运行时环境为仓颉可执行程序提供了对内存和其他系统资源的访问,例如在运行过程中依赖的仓颉动态库。
安装完整的仓颉工具链包含了仓颉代码编译环境和仓颉运行时的安装(详情请参见安装仓颉工具链章节)。如果不需要编译代码,仅仅是运行可执行程序,也可以在环境中独立部署运行时。
本节介绍仓颉运行时的部署。
值得注意的是,编译时使用全静态链接仓颉库,运行时模块已在编译时嵌入到可执行文件中,因此无需在运行环境额外部署运行时,可直接在运行环境中运行编译所得的可执行文件。
Linux
-
首先请前往仓颉官方发布渠道,下载适配平台架构的安装包:
cangjie-sdk-linux-x64-x.y.z.tar.gz:适用于 x86_64 架构 Linux 系统的仓颉工具链。cangjie-sdk-linux-aarch64-x.y.z.tar.gz:适用于 aarch64 架构 Linux 系统的仓颉工具链。
-
请将下载的安装包解压到合适的目录。
解压完成后,可以在当前工作路径下看到一个名为
cangjie的目录,其中存放了仓颉工具链的全部内容。cangjie目录下的runtime目录,即为运行时库,存放了仓颉runtime的全部动态库。 -
请在运行环境执行如下命令完成
runtime的部署(其中${CANGJIE_HOME}请修改为cangjie目录所在的路径,${hw_arch}请修改为对应的硬件架构):export LD_LIBRARY_PATH=${CANGJIE_HOME}/runtime/lib/linux_${hw_arch}_llvm:${LD_LIBRARY_PATH}
macOS
-
首先请前往仓颉官方发布渠道,下载适配平台架构的安装包:
cangjie-sdk-mac-aarch64-x.y.z.tar.gz:适用于 aarch64/arm64 架构 macOS 系统的仓颉工具链。
-
请将下载的安装包解压到合适的目录。
解压完成后,可以在当前工作路径下看到一个名为
cangjie的目录,其中存放了仓颉工具链的全部内容。cangjie目录下的runtime目录,即为运行时库,存放了仓颉runtime的全部动态库。 -
请在运行环境执行如下命令完成
runtime的部署(其中${CANGJIE_HOME}请修改为cangjie目录所在的路径,${hw_arch}请修改为对应的硬件架构):export DYLD_LIBRARY_PATH=${CANGJIE_HOME}/runtime/lib/darwin_${hw_arch}_llvm:${DYLD_LIBRARY_PATH}
Windows
-
首先请前往仓颉官方发布渠道,下载适配平台架构的安装包:
cangjie-sdk-windows-x64-x.y.z.zip:适用于 x86_64 架构 Windows 系统的仓颉工具链。
-
请将下载的安装包解压到合适的目录。
解压完成后,可以在当前工作路径下看到一个名为
cangjie的目录,其中存放了仓颉工具链的全部内容。cangjie目录下的runtime目录,即为运行时库,存放了仓颉runtime的全部动态库。 -
此处为开发者提供三种环境下部署
runtime的方法,可以根据使用习惯及环境配置,选择一种执行(其中${CANGJIE_HOME}请修改为cangjie目录所在的路径,${hw_arch}请修改为对应的硬件架构):-
若使用 Windows 命令提示符(CMD)环境,请执行:
set "PATH=${CANGJIE_HOME}\runtime\lib\windows_x86_64_llvm;%PATH%;" -
若使用 PowerShell 环境,请执行:
$env:PATH = "${CANGJIE_HOME}\runtime\lib\windows_x86_64_llvm;" + $env:Path -
若使用 MSYS shell、bash 等环境,请执行:
export PATH=${CANGJIE_HOME}/runtime/lib/windows_x86_64_llvm
-
运行仓颉可执行程序
直接运行
Linux / macOS
-
首先请查阅部署仓颉运行时章节完成运行时库的部署。
-
将编译得到的可执行文件
main拷贝至运行环境中,执行可执行文件即可。./main值得注意的是,使用
cjpm编译得到的可执行文件main在target/release/bin目录下。
Windows
-
首先请查阅部署仓颉运行时章节,完成运行时库的部署。
-
将编译得到的可执行文件
main.exe拷贝至运行环境中,执行可执行文件即可。.\main.exe值得注意的是,使用
cjpm编译得到的可执行文件main.exe在target\release\bin目录下。
使用 cjpm 运行
开发者常用 cjpm 来管理、编译、运行仓颉项目。
开发者可以根据安装仓颉工具链章节,在运行环境上安装完整的仓颉工具链。 安装完成后,将整个仓颉项目拷贝至运行环境,使用 cjpm run 命令运行仓颉项目即可。
cjc 编译选项
本章介绍常用的 cjc 编译选项。若某一选项同时适用于 cjc-frontend,则该选项会有 [frontend] 上标;若该选项在 cjc-frontend 下行为与 cjc 不同,选项会有额外说明。
-
两个横杠开头的选项为长选项,如
--xxxx。 如果长选项有可选参数,那么选项和参数之间需要用等号连接,如--xxxx=<value>。 如果长选项有必选参数,那么选项和参数之间既可以用空格隔开,也可以用等号连接,如--xxxx <value>与--xxxx=<value>等价。 -
一个横杠开头的选项为短选项,如
-x。 对于短选项,如果其后有参数,选项和参数之间可以用空格隔开,也可以不隔开,如-x <value>与-x<value>等价。
基本选项
--output-type=[exe|staticlib|dylib] [frontend]
指定输出文件的类型。exe 模式下会生成可执行文件,staticlib 模式下会生成静态库文件( .a 文件),dylib 模式下会生成动态库文件(Linux 平台为 .so 文件、Windows 平台为 .dll 文件,macOS 平台为 .dylib 文件)。
cjc 默认为 exe 模式。
除了可以将 .cj 文件编译成一个可执行文件以外,也可以将其编译成一个静态或者是动态的链接库,例如使用:
$ cjc tool.cj --output-type=dylib
可以将 tool.cj 编译成一个动态链接库,在 Linux 平台上,cjc 会生成一个名为 libtool.so 的动态链接库文件。
值得注意的是,若编译可执行程序时链接了仓颉的动态库文件,必须同时指定 --dy-std 选项,详情请见 --dy-std 选项说明。
[frontend] 在 cjc-frontend 中,编译流程仅进行至 LLVM IR,因此输出总是 .bc 文件,但不同的 --output-type 类型仍会影响前端编译的策略。
--package, -p [frontend]
编译包,使用此选项时需要指定一个目录作为输入,目录中的源码文件需要属于同一个包。
假设有文件 log/printer.cj:
package log
public func printLog(message: String) {
println("[Log]: ${message}")
}
与文件 main.cj:
import log.*
main() {
printLog("Everything is great")
}
可以使用
$ cjc -p log --output-type=staticlib
来编译 log 包,cjc 会在当前目录下生成一个 liblog.a 文件。
可以使用 liblog.a 文件来编译 main.cj ,编译命令如下:
$ cjc main.cj liblog.a
cjc 会将 main.cj 与 liblog.a 一同编译成一个可执行文件 main 。
--module-name <value> [frontend]
指定要编译的模块的名称。
假设有文件 my_module/src/log/printer.cj:
package log
public func printLog(message: String) {
println("[Log]: ${message}")
}
与文件 main.cj:
import my_module.log.*
main() {
printLog("Everything is great")
}
可以使用
$ cjc -p my_module/src/log --module-name my_module --output-type=staticlib -o my_module/liblog.a
来编译 log 包并指定其模块名为 my_module,cjc 会在 my_module 目录下生成一个 my_module/liblog.a 文件。
然后可以使用 liblog.a 文件来编译导入了 log 包的 main.cj ,编译命令如下:
$ cjc main.cj my_module/liblog.a
cjc 会将 main.cj 与 liblog.a 一同编译成一个可执行文件 main 。
--output <value>, -o <value>, -o<value> [frontend]
指定输出文件的路径,编译器的输出将被写入指定文件。
例如,以下命令会将输出的可执行文件名称指定为 a.out。
cjc main.cj -o a.out
注意:
编译目标平台为
Windows时,使用-o选项指定的可执行文件名称不允许为cjc.exe;编译目标平台为非Windows时,不允许为cjc,否则可能导致运行错误。
--library <value>, -l <value>, -l<value>
指定要链接的库文件。
给定的库文件会被直接传给链接器,此编译选项一般需要和 --library-path <value> 配合使用。
文件名的格式应为 lib[arg].[extension]。当需要链接库 a 时,可以使用选项 -l a,库文件搜索目录下的 liba.a、liba.so(或链接 Windows 目标程序时会搜索 liba.dll)等文件会被链接器搜索到并根据需要被链接至最终输出中。
--library-path <value>, -L <value>, -L<value>
指定要链接的库文件所在的目录。
使用 --library <value> 选项时,通常也需要使用此选项来指定要链接的库文件所在的目录。
--library-path <value> 指定的路径会被加入链接器的库文件搜索路径。此外,环境变量 LIBRARY_PATH 中指定的路径也会被加入链接器的库文件搜索路径中,通过 --library-path 指定的路径会比 LIBRARY_PATH 中的路径拥有更高的优先级。
假设有从以下 C 语言源文件通过 C 语言编译器编译得到的动态库文件 libcProg.so,
#include <stdio.h>
void printHello() {
printf("Hello World\n");
}
与仓颉文件 main.cj:
foreign func printHello(): Unit
main(): Int64 {
unsafe {
printHello()
}
return 0
}
可以使用
cjc main.cj -L . -l cProg
来编译 main.cj 并指定要链接的 cProg 库,这里 cjc 会输出一个可执行文件 main。
执行 main 会有如下输出:
$ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./main
Hello World
值得注意的是,由于使用了动态库文件,这里需要将库文件所在目录加入 $LD_LIBRARY_PATH 以保证 main 能够在执行时进行动态链接。
-g [frontend]
生成带有调试信息的可执行文件或库文件。
注意:
-g只能配合-O0使用,如果使用更高的优化级别可能会导致调试功能出现异常。
--trimpath <value> [frontend]
移除调试信息中源文件路径信息的前缀。
编译仓颉代码时,cjc 会保存源文件(.cj 文件)的绝对路径信息以在运行时提供调试与异常信息。
使用此选项可以将指定的路径前缀从源文件路径信息中移除,cjc 的输出文件中的源文件路径信息不会包含用户指定的部分。
可以多次使用 --trimpath 指定多个不同的路径前缀;对于每个源文件路径,编译器会将第一个匹配到的前缀从路径中移除。
--coverage [frontend]
生成支持统计代码覆盖率的可执行程序。编译器会为每一个编译单元生成一个后缀名为 gcno 的代码信息文件。在执行程序后,每一个编译单元都会生成一个后缀名为 gcda 的执行统计文件。根据这两个文件,配合使用 cjcov 工具可以生成本次执行下的代码覆盖率报表。
注意:
--coverage只能配合-O0使用,如果使用更高的优化级别,编译器将告警并强制使用-O0。--coverage用于编译生成可执行程序,如果用于生成静态库或者动态库,那么在最终使用该库时可能出现链接错误。
--int-overflow=[throwing|wrapping|saturating] [frontend]
指定固定精度整数运算的溢出策略,默认为 throwing。
throwing策略下,整数运算溢出时会抛出异常。wrapping策略下,整数运算溢出时会回转至对应固定精度整数的另一端。saturating策略下,整数运算溢出时会选择对应固定精度的极值作为结果。
--diagnostic-format=[default|noColor|json] [frontend]
注意:
Windows 版本暂不支持输出带颜色渲染的错误信息。
指定错误信息的输出格式,默认为 default 。
default错误信息默认格式输出(带颜色)noColor错误信息默认格式输出(无颜色)json错误信息json格式输出
--verbose, -V [frontend]
cjc 会打印出编译器版本信息、工具链依赖的相关信息以及编译过程中执行的命令。
--help, -h [frontend]
打印可用的编译选项。
使用此选项时,编译器仅会打印编译选项相关信息,不会对任何输入文件进行编译。
--version, -v [frontend]
打印编译器版本信息。
使用此选项时,编译器仅会打印版本信息,不会对任何输入文件进行编译。
--save-temps <value>
保留编译过程中生成的中间文件并保存至 <value> 路径下。
编译器会保留编译过程中生成的 .bc、.o 等中间文件。
--import-path <value> [frontend]
指定导入模块的 AST 文件的搜索路径。
假设已有以下目录结构,libs/myModule 目录中包含 myModule 模块的库文件和 log 包的 AST 导出文件:
.
├── libs
| └── myModule
| ├── log.cjo
| └── libmyModule.a
└── main.cj
且有如下 main.cj 文件:
import myModule.log.printLog
main() {
printLog("Everything is great")
}
可以通过使用 --import-path ./libs 来将 ./libs 加入导入模块的 AST 文件搜索路径,cjc 会使用 ./libs/myModule/log.cjo 文件来对 main.cj 文件进行语义检查与编译。
--import-path 提供与 CANGJIE_PATH 环境变量相同的功能,但通过 --import-path 设置的路径拥有更高的优先级。
--scan-dependency [frontend]
通过 --scan-dependency 指令可以获得指定包源码或者一个包的 cjo 文件对于其他包的直接依赖以及其他信息,以 json 格式输出。
// this file is placed under directory pkgA
macro package pkgA
import pkgB.*
import std.io.*
import pkgB.subB.*
cjc --scan-dependency --package pkgA
或
cjc --scan-dependency pkgA.cjo
{
"package": "pkgA",
"isMacro": true,
"dependencies": [
{
"package": "pkgB",
"isStd": false,
"imports": [
{
"file": "pkgA/pkgA.cj",
"begin": {
"line": 2,
"column": 1
},
"end": {
"line": 2,
"column": 14
}
}
]
},
{
"package": "pkgB.subB",
"isStd": false,
"imports": [
{
"file": "pkgA/pkgA.cj",
"begin": {
"line": 4,
"column": 1
},
"end": {
"line": 4,
"column": 19
}
}
]
},
{
"package": "std.io",
"isStd": true,
"imports": [
{
"file": "pkgA/pkgA.cj",
"begin": {
"line": 3,
"column": 1
},
"end": {
"line": 3,
"column": 16
}
}
]
}
]
}
--no-sub-pkg [frontend]
表明当前编译包没有子包。
开启该选项后,编译器可以进一步缩减 code size 大小。
--warn-off, -Woff <value> [frontend]
关闭编译期出现的全部或部分警告。
<value> 可以为 all 或者一个设定好的警告组别。当参数为 all 时,对于编译过程中生成的所有警告,编译器都不会打印;当参数为其他设定好的组别时,编译器将不会打印编译过程中生成的该组别警告。
在打印每个警告时,会有一行 #note 提示该警告属于什么组别并如何关闭它,可以通过 --help 打印所有可用的编译选项参数,来查阅具体的组别名称。
--warn-on, -Won <value> [frontend]
开启编译期出现的全部或部分警告。
--warn-on 的 <value> 与 --warn-off 的 <value> 取值范围相同,--warn-on 通常与 --warn-off 组合使用;比如,可以通过设定 -Woff all -Won <value> 来仅允许组别为 <value> 的警告被打印。
特别要注意的是,--warn-on 与 --warn-off 在使用上顺序敏感;针对同一组别,后设定的选项会覆盖之前选项的设定,比如,调换上例中两个编译选项的位置,使其变为 -Won <value> -Woff all,其效果将变为关闭所有警告。
--error-count-limit <value> [frontend]
限制编译器打印错误个数的上限。
参数 <value> 可以为 all 或一个非负整数。当参数为 all 时,编译器会打印编译过程中生成的所有错误;当参数为非负整数 N 时,编译器最多会打印 N 个错误。此选项默认值为 8。
--output-dir <value> [frontend]
控制编译器生成的中间文件与最终文件的保存目录。
控制编译器生成的中间文件的保存目录,例如 .cjo 文件。当指定 --output-dir <path1> 时也指定了 --output <path2>,则中间文件会被保存至 <path1>,最终输出会被保存至 <path1>/<path2> 。
注意:
同时指定此选项与
--output选项时,--output选项的参数必须是一个相对路径。
--static
静态链接仓颉库。
此选项仅在编译可执行文件时生效。
值得注意的是:
--static 选项仅适用于 Linux 平台,在其他平台不生效。
--static-std
静态链接仓颉库的 std 模块。
此选项仅在编译动态链接库或可执行文件时生效。
当编译可执行程序时(即指定了 --output-type=exe 时),cjc 默认静态链接仓颉库的 std 模块。
--dy-std
动态链接仓颉库的 std 模块。
此选项仅在编译动态链接库或可执行文件时生效。
当编译动态库时(即指定了 --output-type=dylib 时),cjc 默认动态链接仓颉库的 std 模块。
值得注意的是:
--static-std和--dy-std选项一起使用时,仅最后一个选项生效。- 当编译可执行程序时链接了仓颉动态库(即通过
--output-type=dylib选项编译的产物),必须显式指定--dy-std选项动态链接标准库,否则可能导致程序集中出现多份标准库,最终可能会导致运行时问题。
--static-libs
该选项已废弃,并会在未来版本被移除。当前版本使用该选项没有功能性作用。
--dy-libs
该选项已废弃,并会在未来版本被移除。当前版本使用该选项没有功能性作用。
--stack-trace-format=[default|simple|all]
指定异常调用栈打印格式,用来控制异常抛出时的栈帧信息显示,默认为 default 格式。
异常调用栈的格式说明如下:
default格式:省略泛型参数的函数名 (文件名:行号)simple格式:文件名:行号all格式:完整的函数名 (文件名:行号)
--lto=[full|thin]
使能且指定 LTO (Link Time Optimization 链接时优化)优化编译模式。
值得注意的是:
Windows以及macOS平台不支持该功能;- 当使能且指定
LTO(Link Time Optimization链接时优化)优化编译模式时,不允许同时使用如下优化编译选项:-Os、-Oz。
LTO 优化支持两种编译模式:
-
--lto=full:full LTO将所有编译模块合并到一起,在全局上进行优化,这种方式可以获得最大的优化潜力,同时也需要更长的编译时间。 -
--lto=thin:相比于full LTO,thin LTO在多模块上使用并行优化,同时默认支持链接时增量编译,编译时间比full LTO短,因为失去了更多的全局信息,所以优化效果不如full LTO。- 通常情况下优化效果对比:
full LTO>thin LTO> 常规静态链接编译。 - 通常情况下编译时间对比:
full LTO>thin LTO> 常规静态链接编译。
- 通常情况下优化效果对比:
LTO 优化使用场景:
-
使用以下命令编译可执行文件。
$ cjc test.cj --lto=full or $ cjc test.cj --lto=thin -
使用以下命令编译
LTO模式下需要的静态库(.bc文件),并且使用该库文件参与可执行文件编译。# 生成的静态库为 .bc 文件 $ cjc pkg.cj --lto=full --output-type=staticlib -o libpkg.bc # .bc 文件和源文件一起输入给仓颉编译器编译可执行文件 $ cjc test.cj libpkg.bc --lto=full注意:
LTO模式下的静态库(.bc文件)输入时需要将该文件的路径输入仓颉编译器。 -
在
LTO模式下,静态链接标准库(--static-std)时,标准库的代码也会参与LTO优化,并静态链接到可执行文件;动态链接标准库(--dy-std)时,在LTO模式下依旧使用标准库中的动态库参与链接。# 静态链接,标准库代码也参与 LTO 优化 $ cjc test.cj --lto=full --static-std # 动态链接,依旧使用动态库参与链接,标准库代码不会参与 LTO 优化 $ cjc test.cj --lto=full --dy-std
--compile-as-exe
该选项使能会隐藏 LTO 模式下加载的 bc 文件符号可见性,仅保留 package init 符号可见性。在此基础上,LLVM 原生优化会在此基础上执行激进的无用符号删除。该选项仅在 --lto 开启下有效。
# 编译通过
$ cjc test.cj --lto=[full|thin] --compile-as-exe
# 编译报错
$ cjc test.cj --compile-as-exe
--pgo-instr-gen
使能插桩编译,生成携带插桩信息的可执行程序。
编译 macOS 与 Windows 目标时暂不支持使用该功能。
PGO(全称 Profile-Guided Optimization)是一种常用的编译优化技术,通过使用运行时 profiling 信息进一步提升程序性能。Instrumentation-based PGO 是使用插桩信息的一种 PGO 优化手段,它通常包含三个步骤:
- 编译器对源码插桩编译,生成插桩后的可执行程序(instrumented program);
- 运行插桩后的可执行程序,生成配置文件;
- 编译器使用配置文件,再次对源码进行编译。
# 生成支持源码执行信息统计(携带插桩信息)的可执行程序 test
$ cjc test.cj --pgo-instr-gen -o test
# 运行可执行程序 test 结束后,生成 default.profraw 配置文件
$ ./test
--pgo-instr-use=<.profdata>
使用指定 profdata 配置文件指导编译并生成优化后的可执行程序。
编译 macOS 目标时暂不支持使用该功能。
注意:
--pgo-instr-use编译选项仅支持格式为profdata的配置文件。可使用llvm-profdata工具可将profraw配置文件转换为profdata配置文件。
# 将 `profraw` 文件转换为 `profdata` 文件。
$ LD_LIBRARY_PATH=$CANGJIE_HOME/third_party/llvm/lib:$LD_LIBRARY_PATH $CANGJIE_HOME/third_party/llvm/bin/llvm-profdata merge default.profraw -o default.profdata
# 使用指定 `default.profdata` 配置文件指导编译并生成优化后的可执行程序 `testOptimized`
$ cjc test.cj --pgo-instr-use=default.profdata -o testOptimized
--target <value> [frontend]
指定编译的目标平台的 triple。
参数 <value> 一般为符合以下格式的字符串:<arch>(-<vendor>)-<os>(-<env>)。其中:
<arch>表示目标平台的系统架构,例如aarch64,x86_64等;<vendor>表示开发目标平台的厂商,常见的例如pc,apple等,在没有明确平台厂商或厂商不重要的情况下也经常写作unknown或直接省略;<os>表示目标平台的操作系统,例如Linux,Win32等;<env>表示目标平台的 ABI 或标准规范,用于更细粒度地区分同一操作系统的不同运行环境,例如gnu,musl等。在操作系统不需要根据<env>进行更细地区分的时候,此项也可以省略。
目前,cjc 已支持交叉编译的本地平台和目标平台如下表所示:
| 本地平台 (host) | 目标平台 (target) |
|---|---|
| x86_64-linux-gnu | x86_64-windows-gnu |
| aarch64-linux-gnu | x86_64-windows-gnu |
在使用 --target 指定目标平台进行交叉编译之前,请准备好对应目标平台的交叉编译工具链,以及可以在本地平台上运行的、向该目标平台编译的对应 Cangjie SDK 版本。
--target-cpu <value>
注意:
该选项为实验性功能,使用该功能生成的二进制可能存在潜在的运行时问题,请注意使用该选项的风险。此选项必须配合
--experimental选项一同使用。
指定编译目标的 CPU 类型。
指定编译目标的 CPU 类型时,编译器在生成二进制时会尝试使用该 CPU 类型特有的扩展指令集,并尝试应用适用于该 CPU 类型的优化。为某个特定 CPU 类型生成的二进制通常会失去可移植性,该二进制可能无法在其他(拥有相同架构指令集的)CPU 上运行。
该选项支持以下经过测试的 CPU 类型:
x86-64 架构:
- generic
aarch64 架构:
- generic
- tsv110
generic 为通用 CPU 类型,指定 generic 时编译器会生成适用于该架构的通用指令,这样生成的二进制在操作系统和二进制本身的动态依赖一致的前提下,可以在基于该架构的各种 CPU 上运行,无关于具体的 CPU 类型。--target-cpu 选项的默认值为 generic。
该选项还支持以下 CPU 类型,但以下 CPU 类型未经过测试验证,请注意使用以下 CPU 类型生成的二进制可能会存在运行时问题。
x86-64 架构:
- alderlake
- amdfam10
- athlon
- athlon-4
- athlon-fx
- athlon-mp
- athlon-tbird
- athlon-xp
- athlon64
- athlon64-sse3
- atom
- barcelona
- bdver1
- bdver2
- bdver3
- bdver4
- bonnell
- broadwell
- btver1
- btver2
- c3
- c3-2
- cannonlake
- cascadelake
- cooperlake
- core-avx-i
- core-avx2
- core2
- corei7
- corei7-avx
- geode
- goldmont
- goldmont-plus
- haswell
- i386
- i486
- i586
- i686
- icelake-client
- icelake-server
- ivybridge
- k6
- k6-2
- k6-3
- k8
- k8-sse3
- knl
- knm
- lakemont
- nehalem
- nocona
- opteron
- opteron-sse3
- penryn
- pentium
- pentium-m
- pentium-mmx
- pentium2
- pentium3
- pentium3m
- pentium4
- pentium4m
- pentiumpro
- prescott
- rocketlake
- sandybridge
- sapphirerapids
- silvermont
- skx
- skylake
- skylake-avx512
- slm
- tigerlake
- tremont
- westmere
- winchip-c6
- winchip2
- x86-64
- x86-64-v2
- x86-64-v3
- x86-64-v4
- yonah
- znver1
- znver2
- znver3
aarch64 架构:
- a64fx
- ampere1
- apple-a10
- apple-a11
- apple-a12
- apple-a13
- apple-a14
- apple-a7
- apple-a8
- apple-a9
- apple-latest
- apple-m1
- apple-s4
- apple-s5
- carmel
- cortex-a34
- cortex-a35
- cortex-a510
- cortex-a53
- cortex-a55
- cortex-a57
- cortex-a65
- cortex-a65ae
- cortex-a710
- cortex-a72
- cortex-a73
- cortex-a75
- cortex-a76
- cortex-a76ae
- cortex-a77
- cortex-a78
- cortex-a78c
- cortex-r82
- cortex-x1
- cortex-x1c
- cortex-x2
- cyclone
- exynos-m3
- exynos-m4
- exynos-m5
- falkor
- kryo
- neoverse-512tvb
- neoverse-e1
- neoverse-n1
- neoverse-n2
- neoverse-v1
- saphira
- thunderx
- thunderx2t99
- thunderx3t110
- thunderxt81
- thunderxt83
- thunderxt88
除以上可选 CPU 类型外,该选项还可以使用 native 作为当前 CPU 类型。编译器会尝试识别当前机器的 CPU 类型,并使用该 CPU 类型作为目标类型生成二进制文件。
--toolchain <value>, -B <value>, -B<value>
指定编译工具链中,二进制文件存放的路径。
这些二进制文件包括编译器、链接器、工具链提供的 C 运行时目标文件(如 crt0.o、 crti.o 等)。
在准备好编译工具链后,可以在将其存放在一个自定义路径,然后通过 --toolchain <value> 向编译器传入该路径,即可让编译器调用到该路径下的二进制文件进行交叉编译。
--sysroot <value>
指定编译工具链的根目录路径。
对于目录结构固定的交叉编译工具链,如果没有指定该目录以外的二进制和动态库、静态库文件路径的需求,可以直接使用 --sysroot <value> 向编译器传入工具链的根目录路径,编译器会根据目标平台种类分析对应的目录结构,自动搜索所需的二进制文件和动态库、静态库文件。使用该选项后,无需再指定 --toolchain、--library-path 参数。
如果向 triple 为 arch-os-env 的平台进行交叉编译,且交叉编译工具链有以下目录结构:
/usr/sdk/arch-os-env
├── bin
| ├── arch-os-env-gcc (交叉编译器)
| ├── arch-os-env-ld (链接器)
| └── ...
├── lib
| ├── crt1.o (C 运行时目标文件)
| ├── crti.o
| ├── crtn.o
| ├── libc.so (动态库)
| ├── libm.so
| └── ...
└── ...
对于仓颉源文件 hello.cj ,可以使用以下命令,将 hello.cj 交叉编译至 arch-os-env 平台:
cjc --target=arch-os-env --toolchain /usr/sdk/arch-os-env/bin --toolchain /usr/sdk/arch-os-env/lib --library-path /usr/sdk/arch-os-env/lib hello.cj -o hello
也可以使用简写的参数:
cjc --target=arch-os-env -B/usr/sdk/arch-os-env/bin -B/usr/sdk/arch-os-env/lib -L/usr/sdk/arch-os-env/lib hello.cj -o hello
如果该工具链的目录符合惯例的目录结构,可以不使用 --toolchain、--library-path 参数,直接使用以下命令:
cjc --target=arch-os-env --sysroot /usr/sdk/arch-os-env hello.cj -o hello
--strip-all, -s
编译可执行文件或动态库时,指定该选项以删除输出文件中的符号表。
--discard-eh-frame
编译可执行文件或动态库时,指定该选项可以删除 eh_frame 段以及 eh_frame_hdr 段中的部分信息(涉及到 crt 的相关信息不作处理),减少可执行文件或动态库的大小,但会影响调试信息。
编译 macOS 目标时暂不支持使用该功能。
--set-runtime-rpath
将仓颉运行时库所在目录的绝对路径写入到二进制的 RPATH/RUNPATH 段中,使用该选项后在构建所在环境中运行该仓颉程序时无需再使用 LD_LIBRARY_PATH (适用于 Linux 平台) 或 DYLD_LIBRARY_PATH (适用于 macOS 平台) 设置仓颉运行时库目录。
编译 Windows 目标时不支持使用该功能。
--link-options <value>1
指定链接器选项。
cjc 会将该选项的参数透传给链接器。可用的参数会因系统或指定的链接器不同而不同。可以多次使用 --link-options 指定多个链接器选项。
1 上标表示链接器透传选项可能会因为链接器的不同而不同,具体支持的选项请查阅链接器文档。
--disable-reflection
关闭反射选项,即编译过程中不生成相关反射信息。
注意:
交叉编译至 aarch64-linux-ohos 目标时,默认关闭反射信息,该选项不生效。
--profile-compile-time [frontend]
输出各编译阶段时间消耗数据到一份文件中,该文件以 .time.prof 为后缀,保存在 --output 指定的目录中,若 --output 指定的是一个文件,则 .time.prof 与该文件同级。
--profile-compile-memory [frontend]
输出各编译阶段内存消耗数据到一份文件中,该文件以 .mem.prof 为后缀,保存在 --output 指定的目录中,若 --output 指定的是一个文件,则 .mem.prof 与该文件同级。
单元测试选项
--test [frontend]
unittest 测试框架提供的入口,由宏自动生成。当使用 cjc --test 选项编译时,程序入口不再是 main,而是 test_entry。unittest 测试框架的使用方法请参见《仓颉编程语言标准库 API》文档。
对于 pkgc 目录下的仓颉文件 a.cj:
import std.unittest.*
import std.unittest.testmacro.*
@Test
public class TestA {
@TestCase
public func case1(): Unit {
print("case1\n")
}
}
可以在 pkgc 目录下使用:
cjc a.cj --test
来编译 a.cj ,执行 main 会有如下输出:
注意:
不保证用例每次执行的用时都相同。
case1
--------------------------------------------------------------------------------------------------
TP: default, time elapsed: 29710 ns, Result:
TCS: TestA, time elapsed: 26881 ns, RESULT:
[ PASSED ] CASE: case1 (16747 ns)
Summary: TOTAL: 1
PASSED: 1, SKIPPED: 0, ERROR: 0
FAILED: 0
--------------------------------------------------------------------------------------------------
对于如下目录结构:
application
├── src
├── pkgc
| ├── a1.cj
| └── a2.cj
└── a3.cj
可以在 application目录下使用 -p 编译选项配合编译整包:
cjc pkgc --test -p
来编译整个 pkgc 包下的测试用例 a1.cj 和 a2.cj。
/*a1.cj*/
package a
import std.unittest.*
import std.unittest.testmacro.*
@Test
public class TestA {
@TestCase
public func caseA(): Unit {
print("case1\n")
}
}
/*a2.cj*/
package a
import std.unittest.*
import std.unittest.testmacro.*
@Test
public class TestB {
@TestCase
public func caseB(): Unit {
throw IndexOutOfBoundsException()
}
}
执行 main 会有如下输出(输出信息仅供参考):
case1
--------------------------------------------------------------------------------------------------
TP: a, time elapsed: 367800 ns, Result:
TCS: TestA, time elapsed: 16802 ns, RESULT:
[ PASSED ] CASE: caseA (14490 ns)
TCS: TestB, time elapsed: 347754 ns, RESULT:
[ ERROR ] CASE: caseB (345453 ns)
REASON: An exception has occurred:IndexOutOfBoundsException
at std/core.Exception::init()(std/core/exception.cj:23)
at std/core.IndexOutOfBoundsException::init()(std/core/index_out_of_bounds_exception.cj:9)
at a.TestB::caseB()(/home/houle/cjtest/application/pkgc/a2.cj:7)
at a.lambda.1()(/home/houle/cjtest/application/pkgc/a2.cj:7)
at std/unittest.TestCases::execute()(std/unittest/test_case.cj:92)
at std/unittest.UT::run(std/unittest::UTestRunner)(std/unittest/test_runner.cj:194)
at std/unittest.UTestRunner::doRun()(std/unittest/test_runner.cj:78)
at std/unittest.UT::run(std/unittest::UTestRunner)(std/unittest/test_runner.cj:200)
at std/unittest.UTestRunner::doRun()(std/unittest/test_runner.cj:78)
at std/unittest.UT::run(std/unittest::UTestRunner)(std/unittest/test_runner.cj:200)
at std/unittest.UTestRunner::doRun()(std/unittest/test_runner.cj:75)
at std/unittest.entryMain(std/unittest::TestPackage)(std/unittest/entry_main.cj:11)
Summary: TOTAL: 2
PASSED: 1, SKIPPED: 0, ERROR: 1
FAILED: 0
--------------------------------------------------------------------------------------------------
--test-only [frontend]
--test-only 选项用于单独编译包的测试部分。
如果启用此选项,编译器将仅编译包中的测试文件(以 _test.cj 结尾)。
注意:
使用此选项时,应单独以常规模式编译相同的包,然后通过
-L/-l链接选项添加依赖,或在使用LTO选项时添加依赖的.bc文件。否则,编译器将报缺少依赖的符号的错误。
示例:
/*main.cj*/
package my_pkg
func concatM(s1: String, s2: String): String {
return s1 + s2
}
main() {
println(concatM("a", "b"))
0
}
/*main_test.cj*/
package my_pkg
@Test
class Tests {
@TestCase
public func case1(): Unit {
@Expect("ac", concatM("a", "c"))
}
}
使用编译器编译的命令如下:
# Compile the production part of the package first, only `main.cj` file would be compiled here
cjc -p my_pkg --output-type=staticlib -o=output/libmain.a
# Compile the test part of the package, Only `main_test.cj` file would be compiled here
cjc -p my_pkg --test-only -L output -lmain --import-path output
--export-for-test [frontend]
在编译源码部分时增加该选项可导出一些原先不导出的类型声明,使同一包下的测试代码在用 --test-only 编译可使用。具体导出类型如下:
- 来源于其他的包的类型,在本包进行扩展的声明
- foreign 函数
典型使用场景如下:
代码结构为
src
├── foo.cj
├── bar.cj
├── foo_test.cj
└── bar_test.cj
// foo.cj
package my_pkg
class Foo { /*...*/ }
extend String {
func invertSlashes() { /*...*/ }
}
// bar.cj
package my_pkg
foreign func strlen(str: CPointer<UInt8>): Int32
// foo_test.cj
package my_pkg
@Test
class TestFoo {
@TestCase
func testInvertSlashes() {
@Assert("\\Users\\Admin\\Documents".invertSlashes(), "/Users/Admin/Documents")
}
}
// bar_test.cj
package my_pkg
@Test
class TestBar {
@TestCase
func testInvertSlashes() {
@Assert(strlen(LibC.mallocCString("abcde").getChars()), 5)
}
}
当需要分开编译同一包中的源码和测试代码时,我们可以使用以下命令:
# Compile the production part of the package first (`foo.cj` and `bar.cj` files)
cjc -p my_pkg --output-type=static --export-for-test -o=output/libmain.a
# Compile the test part of the package (`foo_test.cj` and `bar_test.cj` files)
cjc -p my_pkg --test-only -L output -lmain
在使用 --test-only 选项编译的同名包之外,使用 --export-for-test 选项将没有可见的效果。
注意:
本选项不建议在测试场景以外使用,当使能该选项编译源码时,二进制大小将增加。
--mock <on|off|runtime-error> [frontend]
如果传递了 on ,则该包将使能 mock 编译,该选项允许在测试用例中 mock 该包中的类。off 是一种显式禁用 mock 的方法。
注意:
在测试模式下(当使能
--test)自动启用对此包的 mock 支持,不需要显式传递--mock选项。
runtime-error 仅在测试模式下可用(当使能 --test 时),它允许编译带有 mock 代码的包,但不在编译器中做任何 mock 相关的处理(这些处理可能会造成一些开销并影响测试的运行时性能)。这对于带有 mock 代码用例进行基准测试时可能是有用的。使用此编译选项时,避免编译带有 mock 代码的用例并运行测试,否则将抛出运行时异常。
宏选项
cjc 支持以下宏选项,关于宏的更多内容请参见“宏的简介”章节。
--compile-macro [frontend]
编译宏定义文件,生成默认的宏定义动态库文件。
--debug-macro [frontend]
生成宏展开后的仓颉代码文件。该选项可用于调试宏展开功能。
--parallel-macro-expansion [frontend]
开启宏展开并行。该选项可用于缩短宏展开编译时间。
条件编译选项
cjc 支持以下条件编译选项,关于条件编译的更多内容请参见“条件编译”。
--cfg <value> [frontend]
指定自定义编译条件。
并行编译选项
cjc 支持以下并行编译选项,以获得更高的编译效率。
--jobs <value>, -j <value> [frontend]
设置并行编译时所允许的最大并行数。其中 value 必须是一个合理的非负整数,当 value 大于硬件支持的最大并行能力时,编译器将以硬件支持的最大并行能力执行并行编译。
如果该编译选项未设置,编译器会基于硬件能力自动计算最大并行数。
注意:
--jobs 1表示完全使用串行方式进行编译。
--aggressive-parallel-compile, --apc, --aggressive-parallel-compile=<value>, --apc=<value> [frontend]
开启此选项后,编译器会采用更加激进的策略(可能会对优化造成影响,从而导致程序运行性能下降)执行激进并行编译,以便获得更高的编译效率。其中 value 是一个可选参数,表示激进并行编译部分允许的最大并行数:
- 如果使用
value,则value必须是一个合理的非负整数,当value大于硬件支持的最大并行能力时,编译器会基于硬件能力自动计算最大并行数。建议将value设置为小于硬件的物理核数的非负整数。 - 如果不使用
value,则激进并行编译默认开启,且激进并行编译部分的并行数与--jobs一致。
此外,如果两次编译同一份代码时此选项的 value 值不同,或此选项的开关状态不同,编译器不保证这两次编译的产物的二进制一致性。
激进并行编译的开启或关闭规则如下:
-
在以下场景中,激进并行编译将由编译器强制关闭,无法启用:
--fobf-string--fobf-const--fobf-layout--fobf-cf-flatten--fobf-cf-bogus--lto--coverage- 编译 Windows 目标
- 编译 macOS 目标
-
若使用
--aggressive-parallel-compile=<value>或--apc=<value>,则激进并行编译的开关由value控制:value <= 1:关闭激进并行编译。value > 1:开启激进并行编译,且激进并行编译的并行数取决于value。
-
若使用
--aggressive-parallel-compile或--apc,则激进并行编译默认开启,且激进并行编译的并行数与--jobs一致。 -
若该编译选项未设置,编译器将根据场景默认开启或关闭激进并行编译:
-O0或-g:激进并行编译将由编译器默认开启,且激进并行编译的并行数与--jobs一致;可以通过--aggressive-parallel-compile=<value>或--apc=<value>且value <= 1关闭激进并行编译。- 非
-O0且非-g:激进并行编译将由编译器默认关闭;可以通过--aggressive-parallel-compile=<value>或--apc=<value>且value > 1开启激进并行编译。
优化选项
--fchir-constant-propagation [frontend]
开启 chir 常量传播优化。
--fno-chir-constant-propagation [frontend]
关闭 chir 常量传播优化。
--fchir-function-inlining [frontend]
开启 chir 函数内联优化。
--fno-chir-function-inlining [frontend]
关闭 chir 函数内联优化。
--fchir-devirtualization [frontend]
开启 chir 去虚函数调用优化。
--fno-chir-devirtualization [frontend]
关闭 chir 去虚函数调用优化。
--fast-math [frontend]
开启此选项后,编译器会对浮点数作一些激进且有可能损失精度的假设,以便优化浮点数运算。
-O<N> [frontend]
使用参数指定的代码优化级别。
指定越高的优化级别,编译器会越多地进行代码优化以生成更高效的程序,同时也可能会需要更长的编译时间。
cjc 默认使用 O0 级别的代码优化。当前 cjc 支持如下优化级别:O0、O1、O2、Os、Oz。
当优化等级等于 2 时,cjc 除了进行对应的优化外,还会开启以下选项:
--fchir-constant-propagation--fchir-function-inlining--fchir-devirtualization
当优化等级等于 s 时, cjc除了进行 O2 级别优化外,将针对 code size 进行优化。
当优化等级等于 z 时, cjc除了进行 Os 级别优化外,还将进一步缩减 code size 大小。
注意:
当优化等级等于 s 或 z 时,不允许同时使用链接时优化编译选项
--lto=[full|thin]。
-O [frontend]
使用 O1 级别的代码优化,等价于 -O1。
代码混淆选项
cjc 支持代码混淆功能,以提供对代码的额外安全保护,默认不开启。
cjc 支持以下代码混淆选项:
--fobf-string
开启字符串混淆。
混淆代码中出现的字符串常量,攻击者无法静态直接读取二进制程序中的字符串数据。
--fno-obf-string
关闭字符串混淆。
--fobf-const
开启常量混淆。
混淆代码中使用的数值常量,将数值运算指令替换成等效的、更复杂的数值运算指令序列。
--fno-obf-const
关闭常量混淆。
--fobf-layout
开启外形混淆。
外形混淆功能会混淆代码中的符号(包括函数名和全局变量名)、路径名、代码行号和函数排布顺序。使用该编译选项后,cjc 会在当前目录生成符号映射输出文件 *.obf.map。如果配置了 --obf-sym-output-mapping 选项,则 --obf-sym-output-mapping 的参数值将作为 cjc 生成的符号映射输出文件名。符号映射输出文件中包含混淆前后符号的映射关系,使用符号映射输出文件可以解混淆被混淆过的符号。
注意:
外形混淆功能和并行编译功能相互冲突,请勿同时开启。如果和并行编译同时开启,并行编译将失效。
--fno-obf-layout
关闭外形混淆。
--obf-sym-prefix <string>
指定外形混淆功能在混淆符号时添加的前缀字符串。
设置该选项后,所有被混淆符号都会加上该前缀。在编译混淆多个仓颉包时可能出现符号冲突的问题,可以使用该选项给不同的包指定不同的前缀,避免符号冲突。
--obf-sym-output-mapping <file>
指定外形混淆的符号映射输出文件。
符号映射输出文件记录了符号的原始名称、混淆后的名称和所属文件路径。使用符号映射输出文件可以解混淆被混淆过的符号。
--obf-sym-input-mapping <file,...>
指定外形混淆的符号映射输入文件。
外形混淆功能会使用这些文件中的映射关系对符号进行混淆。因此在编译存在调用关系的仓颉包,请使用被调用包的符号映射输出文件作为调用包混淆时的 --obf-sym-input-mapping 选项的参数,以此保证同一个符号在调用包和被调用包两者混淆时混淆结果一致。
--obf-apply-mapping-file <file>
提供自定义的外形混淆符号映射关系文件,外形混淆功能将按照文件里的映射关系混淆符号。
文件格式如下:
<original_symbol_name> <new_symbol_name>
其中 original_symbol_name 是混淆前的名称,new_symbol_name 是混淆后的名称。original_symbol_name 由多个 field 组成。field 表示字段名,可以是模块名、包名、类名、结构体名、枚举名、函数名或变量名。field 之间用分隔符 '.' 分隔。如果 field 是函数名,则需要将函数的参数类型用括号 '()' 修饰并附加在函数名后面。对于无参函数括号内的内容为空。如果 field 存在泛型参数,也需要用括号 '<>' 将具体的泛型参数附加在 field 后面。
外形混淆功能会将仓颉应用中的 original_symbol_name 替换为 new_symbol_name。对于不在该文件中的符号,外形混淆功能会正常使用随机名称进行替换。如果该文件中指定的映射关系和 --obf-sym-input-mapping 中的映射关系相冲突,编译器会抛出异常并停止编译。
--fobf-export-symbols
允许外形混淆功能混淆导出符号,该选项在开启外形混淆功能时默认开启。
开启该选项后,外形混淆功能会对导出符号进行混淆。
--fno-obf-export-symbols
禁止外形混淆功能混淆导出符号。
--fobf-source-path
允许外形混淆功能混淆符号的路径信息,该选项在开启外形混淆功能时默认开启。
开启该选项后,外形混淆功能会混淆异常堆栈信息中的路径信息,将路径名替换为字符串 "SOURCE"。
--fno-obf-source-path
禁止外形混淆功能混淆堆栈信息中的路径信息。
--fobf-line-number
允许外形混淆功能混淆堆栈信息中的行号信息。
开启该选项后,外形混淆功能会混淆异常堆栈信息中的行号信息,将行号替换为 0。
--fno-obf-line-number
禁止外形混淆功能混淆堆栈信息中的行号信息。
--fobf-cf-flatten
开启控制流平坦化混淆。
混淆代码中既存的控制流,使其转移逻辑变得复杂。
--fno-obf-cf-flatten
关闭控制流平坦化混淆。
--fobf-cf-bogus
开启虚假控制流混淆。
在代码中插入虚假的控制流,使代码逻辑变得复杂。
--fno-obf-cf-bogus
关闭虚假控制流混淆。
--fobf-all
开启所有混淆功能。
指定该选项等同于同时指定以下选项:
--fobf-string--fobf-const--fobf-layout--fobf-cf-flatten--fobf-cf-bogus
--obf-config <file>
指定代码混淆配置文件路径。
在配置文件中可以禁止混淆工具对某些函数或者符号进行混淆。
配置文件的具体格式如下:
obf_func1 name1
obf_func2 name2
...
第一个参数 obf_func 是具体的混淆功能:
obf-cf-bogus:虚假控制流混淆obf-cf-flatten:控制流平坦化混淆obf-const:常数混淆obf-layout:外形混淆
第二个参数 name 是需要被保留的对象,由多个 field 组成。field 表示字段名,可以是包名、类名、结构体名、枚举名、函数名或变量名。
field 之间用分隔符 '.' 分隔。如果 field 是函数名,则需要将函数的参数类型用括号 '()' 修饰并附加在函数名后面。对于无参函数括号内的内容为空。
例如,假设在包 packA 中有以下代码:
package packA
class MyClassA {
func funcA(a: String, b: Int64): String {
return a
}
}
如果要禁止控制流平坦化功能混淆 funcA,用户可以编写如下规则:
obf-cf-flatten packA.MyClassA.funcA(std.core.String, Int64)
用户也可以使用通配符编写更加灵活的规则,达到一条规则保留多个对象的效果。目前支持的通配符包含以下 3 类:
混淆功能通配符:
| 混淆功能通配符 | 说明 |
|---|---|
? | 匹配名称中的单个字符 |
* | 匹配名称中的任意数量字符 |
字段名通配符:
| 字段名通配符 | 说明 |
|---|---|
? | 匹配字段名中单个非分隔符 '.' 的字符 |
* | 匹配字段名中的不包含分隔符 '.' 和参数的任意数量字符 |
** | 匹配字段名中的任意数量字符,包括字段之间的分隔符 '.' 和参数。'**' 只有在单独作为一个 field 时才生效,否则会被当作 '*' 处理 |
函数的参数类型通配符:
| 参数类型通配符 | 说明 |
|---|---|
... | 匹配任意数量的参数 |
*** | 匹配一个任意类型的参数 |
说明:
参数类型也由字段名组成,因此也可以使用字段名通配符对单个参数类型进行匹配。
以下是通配符使用示例:
例子 1:
obf-cf-flatten pro?.myfunc()
该规则表示禁止 obf-cf-flatten 功能混淆函数 pro?.myfunc(),pro?.myfunc() 可以匹配 pro0.myfunc(),但不能匹配 pro00.myfunc()。
例子 2:
* pro0.**
该规则表示禁止任何混淆功能混淆包 pro0 下的任何函数和变量。
例子 3:
* pro*.myfunc(...)
该规则表示禁止任何混淆功能混淆函数 pro*.myfunc(...),pro*.myfunc(...) 可以匹配以 pro 开头的任意单层包内的 myfunc 函数,且可以为任意参数。
如果需要匹配多层包名,比如 pro0.mypack.myfunc(),请使用 pro*.**.myfunc(...)。请注意 '**' 只有单独作为字段名时才生效,因此 pro**.myfunc(...) 和 pro*.myfunc(...) 等价,无法匹配多层包名。如果要匹配以 pro 开头的所有包下的所有 myfunc 函数(包括类中名为 myfunc 的函数),请使用 pro*.**.myfunc(...)。
例子 4:
obf-cf-* pro0.MyClassA.myfunc(**.MyClassB, ***, ...)
该规则表示禁止 obf-cf-* 功能混淆函数 pro0.MyClassA.myfunc(**.MyClassB, ***, ...),其中 obf-cf-* 会匹配 obf-cf-bogus 和 obf-cf-flatten 两种混淆功能,pro0.MyClassA.myfunc(**.MyClassB, ***, ...) 会匹配函数 pro0.MyClassA.myfunc,且函数的第一个参数可以是任意包下的 MyClassB 类型,第二个参数可以是任意类型,后面可以接零至多个任意参数。
--obf-level <value>
指定混淆功能强度级别。
可指定 1-9 强度级别。默认强度级别为 5。级别数字越大,强度则越高,该选项会影响输出文件的大小以及执行开销。
--obf-seed <value>
指定混淆算法的随机数种子。
通过指定混淆算法的随机数种子,可以使同一份仓颉代码在不同构建时有不同的混淆结果。默认场景下,对于同一份仓颉代码,在每次混淆后都拥有相同的混淆结果。
安全编译选项
cjc 默认生成地址无关代码,在编译可执行文件时默认生成地址无关可执行文件。
在构建 Release 版本时,建议根据以下规则打开/关闭编译选项以提高安全性。
启用 --trimpath <value> [frontend]
从调试与异常信息中将指定的绝对路径前缀移除,使用该选项可以避免构建路径信息被写入二进制程序中。
使用该选项后,二进制中的源码路径信息通常不再完整,可能影响调试体验,建议在构建调试版本时关闭该选项。
启用 --strip-all, -s
移除二进制中的符号表,使用该选项可以删除运行时不需要的符号相关信息。
使用该选项后,二进制将无法调试,请在构建调试版本时关闭该选项。
禁用 --set-runtime-rpath
若可执行程序会被分发至不同环境运行,或其他普通用户对当前正在使用的仓颉运行时库目录拥有写权限,使用该选项可能导致安全风险,因此禁用该选项。
编译 Windows 目标时不涉及该选项。
启用 --link-options "-z noexecstack"1
设置线程栈不可执行。
仅编译 Linux 目标时可用。
启用 --link-options "-z relro"1
设置 GOT 表重定位只读。
仅编译 Linux 目标时可用。
启用 --link-options "-z now"1
设置立即绑定。
仅编译 Linux 目标时可用。
代码覆盖率插桩选项
注意:
Windows 和 macOS 版本目前不支持代码覆盖率插桩选项。
仓颉支持对代码覆盖率插桩(SanitizerCoverage,以下简称 SanCov),提供与 LLVM 的 SanitizerCoverage 一致的接口,编译器在函数级或 BasicBlock 级插入覆盖率反馈函数,用户只需要实现约定好的回调函数即可在运行过程中感知程序运行状态。
仓颉提供的 SanCov 功能以 package 为单位,即整个 package 只有全部插桩和全部不插桩两种情况。
--sanitizer-coverage-level=0/1/2
插桩级别:
- 0 表示不插桩;
- 1 表示函数级插桩,仅在函数入口处插入回调函数;
- 2 表示 BasicBlock 级插桩,在各个 BasicBlock 处插入回调函数。
如果不指定,默认值为 2。
该编译选项仅影响 --sanitizer-coverage-trace-pc-guard、--sanitizer-coverage-inline-8bit-counters 和 --sanitizer-coverage-inline-bool-flag 的插桩级别。
--sanitizer-coverage-trace-pc-guard
开启该选项,会在每个 Edge 插入函数调用 __sanitizer_cov_trace_pc_guard(uint32_t *guard_variable),受 sanitizer-coverage-level 影响。
值得注意的是,该功能存在与 gcc/llvm 实现不一致的地方:不会在 constructor 插入 void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop),而是在 package 初始化阶段插入函数调用 uint32_t *__cj_sancov_pc_guard_ctor(uint64_t edgeCount)。
__cj_sancov_pc_guard_ctor 回调函数需要开发者自行实现,开启 SanCov 的 package 会尽可能早地调用该回调函数,入参是该 Package 的 Edge 个数,返回值是通常是 calloc 创建的内存区域。
如果需要调用 __sanitizer_cov_trace_pc_guard_init,建议在 __cj_sancov_pc_guard_ctor 中调用,使用动态创建的缓冲区计算该函数的入参和返回值。
一个标准的 __cj_sancov_pc_guard_ctor 参考实现如下:
uint32_t *__cj_sancov_pc_guard_ctor(uint64_t edgeCount) {
uint32_t *p = (uint32_t *) calloc(edgeCount, sizeof(uint32_t));
__sanitizer_cov_trace_pc_guard_init(p, p + edgeCount);
return p;
}
--sanitizer-coverage-inline-8bit-counters
开启该选项后,会在每个 Edge 插入一个累加器,每经历过一次,该累加器加一,受 sanitizer-coverage-level 影响。
值得注意的是,该功能存在与 gcc/llvm 实现不一致的地方:不会在 constructor 插入 void __sanitizer_cov_8bit_counters_init(char *start, char *stop),而是在 package 初始化阶段插入函数调用 uint8_t *__cj_sancov_8bit_counters_ctor(uint64_t edgeCount)。
__cj_sancov_pc_guard_ctor 回调函数需要开发者自行实现,开启 SanCov 的 package 会尽可能早地调用该回调函数,入参是该 Package 的 Edge 个数,返回值是通常是 calloc 创建的内存区域。
如果需要调用 __sanitizer_cov_8bit_counters_init,建议在 __cj_sancov_8bit_counters_ctor 中调用,使用动态创建的缓冲区计算该函数的入参和返回值。
一个标准的 __cj_sancov_8bit_counters_ctor 参考实现如下:
uint8_t *__cj_sancov_8bit_counters_ctor(uint64_t edgeCount) {
uint8_t *p = (uint8_t *) calloc(edgeCount, sizeof(uint8_t));
__sanitizer_cov_8bit_counters_init(p, p + edgeCount);
return p;
}
--sanitizer-coverage-inline-bool-flag
开启该选项后,会在每个 Edge 插入布尔值,经历过的 Edge 对应的布尔值会被设置为 True,受 sanitizer-coverage-level 影响。
值得注意的是,该功能存在与 gcc/llvm 实现不一致的地方:不会在 constructor 插入 void __sanitizer_cov_bool_flag_init(bool *start, bool *stop),而是在 package 初始化阶段插入函数调用 bool *__cj_sancov_bool_flag_ctor(uint64_t edgeCount)。
__cj_sancov_bool_flag_ctor 回调函数需要开发者自行实现,开启 SanCov 的 package 会尽可能早地调用该回调函数,入参是该 Package 的 Edge 个数,返回值是通常是 calloc 创建的内存区域。
如果需要调用 __sanitizer_cov_bool_flag_init,建议在 __cj_sancov_bool_flag_ctor 中调用,使用动态创建的缓冲区计算该函数的入参和返回值。
一个标准的 __cj_sancov_bool_flag_ctor 参考实现如下:
bool *__cj_sancov_bool_flag_ctor(uint64_t edgeCount) {
bool *p = (bool *) calloc(edgeCount, sizeof(bool));
__sanitizer_cov_bool_flag_init(p, p + edgeCount);
return p;
}
--sanitizer-coverage-pc-table
该编译选项用于提供插桩点和源码之间的对应关系,当前只提供精确到函数级的对应关系。需要与 --sanitizer-coverage-trace-pc-guard、--sanitizer-coverage-inline-8bit-counters、--sanitizer-coverage-inline-bool-flag 共用,至少需要开启其中一项,可以同时开启多项。
值得注意的是,该功能存在与 gcc/llvm 实现不一致的地方:不会在 constructor 插入 void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg, const uintptr_t *pcs_end);,而是在 package 初始化阶段插入函数调用 void __cj_sancov_pcs_init(int8_t *packageName, uint64_t n, int8_t **funcNameTable, int8_t **fileNameTable, uint64_t *lineNumberTable),各入参含义如下:
int8_t *packageName: 字符串,表示包名(插桩用 c 风格的 int8 数组作为入参来表达字符串,下同)。uint64_t n: 共有 n 个函数被插桩。int8_t **funcNameTable: 长度为 n 的字符串数组,第 i 个插桩点对应的函数名为 funcNameTable[i]。int8_t **fileNameTable: 长度为 n 的字符串数组,第 i 个插桩点对应的文件名为 fileNameTable[i]。uint64_t *lineNumberTable: 长度为 n 的 uint64 数组,第 i 个插桩点对应的行号为 lineNumberTable[i]。
如果需要调用 __sanitizer_cov_pcs_init,需要自行完成仓颉 pc-table 到 C 语言 pc-table 的转化。
--sanitizer-coverage-stack-depth
开启该编译选项后,由于仓颉无法获取 SP 指针的值,因此只能在每个函数入口处插入调用 __updateSancovStackDepth,在 C 侧实现该函数即可获得 SP 指针。
一个标准的 updateSancovStackDepth 实现如下:
thread_local void* __sancov_lowest_stack;
void __updateSancovStackDepth()
{
register void* sp = __builtin_frame_address(0);
if (sp < __sancov_lowest_stack) {
__sancov_lowest_stack = sp;
}
}
--sanitizer-coverage-trace-compares
开启该选项后,会在所有的 compare 指令和 match 指令调用前插入函数回调函数,具体列表如下,与 LLVM 系的 API 功能一致。参考 Tracing data flow。
void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2);
void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2);
void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2);
void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2);
void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2);
void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2);
void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2);
void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2);
void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases);
--sanitizer-coverage-trace-memcmp
该编译选项用于在 String 、 Array 等比较中反馈前缀比较信息。开启该选项后,会对 String 和 Array 的比较函数前插入函数回调函数。具体对于以下对各 String 和 Array 的 API,分别插入对应桩函数:
- String==: __sanitizer_weak_hook_memcmp
- String.startsWith: __sanitizer_weak_hook_memcmp
- String.endsWith: __sanitizer_weak_hook_memcmp
- String.indexOf: __sanitizer_weak_hook_strstr
- String.replace: __sanitizer_weak_hook_strstr
- String.contains: __sanitizer_weak_hook_strstr
- CString==: __sanitizer_weak_hook_strcmp
- CString.startswith: __sanitizer_weak_hook_memcmp
- CString.endswith: __sanitizer_weak_hook_strncmp
- CString.compare: __sanitizer_weak_hook_strcmp
- CString.equalsLower: __sanitizer_weak_hook_strcasecmp
- Array==: __sanitizer_weak_hook_memcmp
- ArrayList==: __sanitizer_weak_hook_memcmp
实验性功能选项
--experimental [frontend]
启用实验性功能,允许在命令行使用其他实验性功能选项。
注意:
使用实验性功能生成的二进制文件可能存在潜在的运行时问题,请注意使用该选项的风险。
其他功能
编译器报错信息显示颜色
对于 Windows 版本的仓颉编译器,仅在运行于 Windows 10 version 1511 (Build 10586) 或更高版本的系统时,编译器报错信息才会显示颜色,否则不显示颜色。
设置 build-id
通过 --link-options "--build-id=<arg>"1 可以透传链接器选项以设置 build-id。
编译 Windows 目标时不支持此功能。
设置 rpath
通过 --link-options "-rpath=<arg>"1 可以透传链接器选项以设置 rpath。
编译 Windows 目标时不支持此功能。
增量编译
通过 --incremental-compile[frontend]开启增量编译。开启后,cjc会在编译时根据前次编译的缓存文件加快此次编译的速度。
注意:
该选项为实验性功能,使用该功能生成的二进制有可能会存在潜在的运行时问题,请注意使用该选项的风险。此选项必须配合
--experimental选项一同使用。 指定此选项时会保存增量编译缓存及日志到输出文件路径下的.cached目录。
cjc 用到的环境变量
这里介绍一些仓颉编译器在编译代码的过程中可能使用到的环境变量。
TMPDIR 或者 TMP
仓颉编译器会将编译过程中生成的临时文件放置在临时目录中。默认情况下,Linux 和 macOS 操作系统会将其放在 /tmp 目录下,而 Windows 操作系统则会将其放在 C:\Windows\Temp 目录下。仓颉编译器还支持自定义临时文件存放目录,在 Linux 和 macOS 操作系统上,可以通过设置环境变量 TMPDIR 来更改临时文件目录,而在 Windows 操作系统上,则可以通过设置环境变量 TMP 来更改临时文件目录。
例如: 在 Linux shell 中
export TMPDIR=/home/xxxx
在 Windows cmd 中
set TMP=D:\\xxxx
Linux 版本工具链的支持与安装
仓颉工具链当前基于以下 Linux 发行版进行了完整功能测试:
- SUSE Linux Enterprise Server 12 SP5
- Ubuntu 18.04
- Ubuntu 20.04
- UnionTech OS Server 20
- Kylin Linux Advanced Server Release V10
适用于各 Linux 发行版的仓颉工具链依赖安装命令
注意:
当前仓颉工具链依赖的某些工具在一些 Linux 发行版上可能无法通过系统默认软件源直接安装。可参考下一节编译安装依赖工具进行手动安装。
SUSE Linux Enterprise Server 12 SP5
$ zypper install \
binutils \
glibc-devel \
gcc-c++
此外,还需要安装 OpenSSL 3,安装方法请参见编译安装依赖工具。
Ubuntu 18.04
$ apt-get install \
binutils \
libc-dev \
libc++-dev \
libgcc-7-dev
此外,还需要安装 OpenSSL 3,安装方法请参见编译安装依赖工具。
Ubuntu 20.04
$ apt-get install \
binutils \
libc-dev \
libc++-dev \
libgcc-9-dev
此外,还需要安装 OpenSSL 3,安装方法请参见编译安装依赖工具。
UnionTech OS Server 20
$ yum install \
binutils \
glibc-devel \
libstdc++-devel \
gcc \
此外,还需要安装 OpenSSL 3,安装方法请参见编译安装依赖工具。
Kylin Linux Advanced Server release V10
$ yum install \
binutils \
glibc-devel \
libstdc++-devel \
gcc \
此外,还需要安装 OpenSSL 3,安装方法请参见编译安装依赖工具。
其他 Linux 发行版
根据使用的 Linux 发行版的不同,可能需要参考以上系统的依赖安装命令,使用系统包管理工具安装对应依赖。若使用的系统没有提供相关软件包,可能需要自行安装链接工具、C 语言开发工具、C++ 开发工具、GCC 编译器、以及 OpenSSL 3 以正常使用仓颉工具链。
编译安装依赖工具
当前仓颉工具链中的部分标准库(以及部分工具)使用了 OpenSSL 3 开源软件。对于系统包管理工具未提供 OpenSSL 3 的场景,用户可能需要源码编译安装 OpenSSL 3,本节提供了 OpenSSL 3 源码编译的方法和步骤。
OpenSSL 3
从以下链接可以下载到 OpenSSL 3 的源码:
建议使用 OpenSSL 3.0.7 或更高版本。
注意:
请在执行以下编译和安装命令前仔细阅读注意事项,并根据实际情况调整命令。不正确的配置和安装可能会导致系统其他软件不可用。如果在编译安装过程中遇到问题或希望进行额外的安装配置,请参见 OpenSSL 源码中的
INSTALL文件或 OpenSSL 的 FAQ。
此处以 OpenSSL 3.0.7 为例,下载后使用以下命令解压压缩包:
$ tar xf openssl-3.0.7.tar.gz
解压完成后进入目录:
$ cd openssl-3.0.7
编译 OpenSSL:
注意:
如果系统已经安装了 OpenSSL,建议使用
--prefix=<path>选项指定一个自定义安装路径,例如--prefix=/usr/local/openssl-3.0.7或开发者的个人目录。在系统目录已经存在 OpenSSL 的场景下直接使用以下命令编译安装可能会使系统 OpenSSL 被覆盖,并导致依赖系统 OpenSSL 的应用不可用。
$ ./Configure --libdir=lib
$ make
测试 OpenSSL:
$ make test
将 OpenSSL 安装至系统目录(或先前指定的 --prefix 目录),可能需要提供 root 权限以成功执行以下命令:
$ make install
或
$ sudo make install
如果先前编译 OpenSSL 时没有通过 --prefix 设置自定义安装路径,则 OpenSSL 安装已经完成了。如果先前通过 --prefix 指定了自定义的安装路径,还需要设置以下变量,以使仓颉工具链可以找到 OpenSSL 3。
注意:
如果系统中原先存在其他版本的 OpenSSL,通过以下方式配置后,除了仓颉工具链外,其他编译开发工具默认使用的 OpenSSL 版本也可能受到影响。如果使用其他编译开发工具时出现 OpenSSL 不兼容的情况,请仅为仓颉开发环境配置以下变量。
请将 <prefix> 替换为指定的自定义安装路径。
$ export LIBRARY_PATH=<prefix>/lib:$LIBRARY_PATH
$ export LD_LIBRARY_PATH=<prefix>/lib:$LD_LIBRARY_PATH
通过以上方式所配置的环境变量仅在当前执行命令的 shell 会话窗口有效。若希望 shell 每次启动时都自动配置,可以在 $HOME/.bashrc、$HOME/.zshrc 或其他 shell 配置文件(依开发者的 shell 种类而定)加入以上命令。
若希望配置可以默认对所有用户生效,可以执行以下命令:
请将 <prefix> 替换为指定的自定义安装路径。
$ echo "export LIBRARY_PATH=<prefix>/lib:$LIBRARY_PATH" >> /etc/profile
$ echo "<prefix>/lib" >> /etc/ld.so.conf
$ ldconfig
执行完毕后重新打开 shell 会话窗口即可生效。
至此,OpenSSL 3 已经成功安装,可以回到原来的章节继续阅读或尝试运行仓颉编译器了。
runtime 环境变量使用手册
本节介绍 runtime(运行时)所提供的环境变量。
在 Linux shell 与 macOS shell 中,可以使用以下方式设置仓颉运行时提供的环境变量:
$ export VARIABLE=value
在 Windows cmd 中,可以使用以下方式设置仓颉运行时提供的环境变量:
> set VARIABLE=value
本节后续的示例均为 Linux shell 中的设置方式,若与运行平台不符,请根据运行平台选择合适的环境变量设置方式。
runtime 初始化可选配置
注意:
- 所有整型参数为 Int64 类型,浮点型参数为 Float64 类型;
- 所有参数如果未显式规定最大值,默认隐式最大值为该类型最大值;
- 所有参数若超出范围则设置无效,自动使用默认值。
cjHeapSize
指定仓颉堆的最大值,支持单位为 kb(KB)、mb(MB)、gb(GB),支持设置范围为[4MB, 系统物理内存],超出范围的设置无效,仍旧使用默认值。若物理内存低于 1GB,默认值为 64 MB,否则为 256 MB。
例如:
export cjHeapSize=4GB
cjRegionSize
指定 region 分配器 thread local buffer 的大小,支持单位为 kb(KB)、mb(MB)、gb(GB),支持设置范围为[4kb, 2048kb],超出范围的设置无效,仍旧使用默认值。默认值为 64 KB。
例如:
export cjRegionSize=1024kb
cjLargeThresholdSize
需要大量连续内存空间的对象(例如长数组)称为大对象。堆内频繁分配大对象可能导致堆内连续空间不足,从而触发堆溢出问题。通过增加大对象的最大值,可以提升堆内空间的连续性。
在仓颉语言中,大对象的阈值为 cjLargeThresholdSize 和 cjRegionSize 的较小者。cjLargeThresholdSize 支持的单位有 kb(KB)、mb(MB)、gb(GB),支持的范围是 [4KB, 2048KB],超出范围的设置无效,仍旧使用默认值。默认值为 32 KB。
说明:
较大的大对象阈值可能影响程序性能,开发者可根据实际情况设置。
例如:
export cjLargeThresholdSize=1024kb
cjExemptionThreshold
指定存活 region 的水线值,取值 (0,1],该值与 region 的大小相乘,若 region 中存活对象的大小大于相乘后的值,则该 region 不会被回收(其中死亡对象继续占用内存)。该值指定得越大,region 被回收的概率越大,堆中的碎片空间就越少,但频繁回收 region 也会影响性能。超出范围的设置无效,仍旧使用默认值。默认值为 0.8,即 80%。
例如:
export cjExemptionThreshold=0.8
cjHeapUtilization
指定仓颉堆的利用率,该参数用于 GC 后更新堆水线的参考依据之一,取值 (0, 1],堆水线是指当堆中对象总大小达到水线值时则进行 GC。该参数指定越小,则更新后的堆水线会越高,则触发 GC 的概率会相对变低。超出范围的设置无效,仍旧使用默认值。默认值为 0.8,即 80%。
例如:
export cjHeapUtilization=0.8
cjCacheRatio
指定堆缓存率,该参数用于 GC 后的堆缓存,堆内缓存率不高于此值。取值 [0, 1],超出范围的设置无效,仍旧使用默认值,默认值为 1。该参数仅在 openEuler 平台生效。
例如:
export cjCacheRatio=0.25
cjHeapGrowth
指定仓颉堆的增长率,该参数用于 GC 后更新堆水线的参考依据之一,取值必须大于 0。增长率的计算方式为 1 + cjHeapGrowth。该参数指定越大,则更新后的堆水线会越高,则触发 GC 的概率会相对变低。默认值为 0.15,表示增长率为 1.15。
例如:
export cjHeapGrowth=0.15
cjAllocationRate
指定仓颉运行时分配对象的速率,该值必须大于 0,单位为 MB/s,表示每秒可分配对象的数量。默认值为 10240,表示每秒可分配 10240 MB 对象。
例如:
export cjAllocationRate=10240
cjAllocationWaitTime
指定仓颉运行时分配对象时的等待时间,该值必须大于 0,支持单位为 s、ms、us、ns,推荐单位为纳秒(ns)。若本次分配对象距离上一次分配对象的时间间隔小于此值,则将等待。默认值为 1000 ns。
例如:
export cjAllocationWaitTime=1000ns
cjGCThreshold
指定仓颉堆的参考水线值,支持单位为 kb(KB)、mb(MB)、gb(GB), 取值必须为大于 0 的整数。当仓颉堆大小超过该值时,触发 GC。默认值为堆大小。
例如:
export cjGCThreshold=20480KB
cjGarbageThreshold
当 GC 发生时,如果 region 中死亡对象所占比率大于此环境变量,此 region 会被放入回收候选集中,后续可被回收(如果受到其他策略影响也可能不被回收),默认值为 0.5,无量纲,支持设置的区间为[0.0, 1.0]。
例如:
export cjGarbageThreshold=0.5
cjGCInterval
指定两次 GC 的间隔时间值,取值必须大于 0,支持单位为 s、ms、us、ns,推荐单位为毫秒(ms)。若本次 GC 距离上次 GC 的间隔小于此值,则本次 GC 将被忽略。该参数可以控制 GC 的频率。默认值为 150 ms。
例如:
export cjGCInterval=150ms
cjBackupGCInterval
指定 backup GC 的间隔值,取值必须大于 0,支持单位为 s、ms、us、ns,推荐单位为秒(s),当仓颉运行时在该参数设定时间内未触发 GC,则触发一次 backup GC。默认值为 240 秒,即 4 分钟。
例如:
export cjBackupGCInterval=240s
cjProcessorNum
指定仓颉线程的最大并发数,支持设置范围为 (0, CPU 核数 * 2],超出范围的设置无效,仍旧使用默认值。调用系统 API 获取 cpu 核数,若成功默认值为 cpu 核数,否则默认值为 8。
例如:
export cjProcessorNum=2
cjStackSize
指定仓颉线程的栈大小,支持单位为 kb(KB)、mb(MB)、gb(GB),支持设置范围为 Linux 平台下[64KB, 1GB],Windows 平台下[128KB, 1GB],超出范围的设置无效,仍旧使用默认值。默认值为 128KB。
例如:
export cjStackSize=100kb
运维日志可选配置
MRT_LOG_FILE_SIZE
指定 runtime 运维日志的文件大小,默认值为 10 MB,支持单位为 kb(KB)、mb(MB)、gb(GB),设置值需大于 0。
日志大小超过该值时,会重新回到日志开头进行打印。
最终生成日志大小略大于 MRT_LOG_FILE_SIZE。
例如:
export MRT_LOG_FILE_SIZE=100kb
MRT_LOG_PATH
指定 runtime 运维日志的输出路径,若该环境变量未设置或路径设置失败,则运维日志默认打印到 stdout(标准输出)或 stderr(标准错误)中。
例如:
export MRT_LOG_PATH=/home/cangjie/runtime/runtime_log.txt
MRT_LOG_LEVEL
指定 runtime 运维日志的最小输出级别,大于等于这个级别的日志会被打印,默认值为 e,支持设置值为[v|d|i|w|e|f|s]。v(VERBOSE)、d(DEBUGY)、i(INFO)、w(WARNING)、e(ERROR)、f(FATAL)、s(FATAL_WITHOUT_ABORT)。
例如:
export MRT_LOG_LEVEL=v
MRT_REPORT
指定 runtime GC 日志的输出路径,若该环境变量未设置或路径设置失败,该日志默认不打印。
例如:
export MRT_REPORT=/home/cangjie/runtime/gc_log.txt
MRT_LOG_CJTHREAD
指定 cjthread 日志的输出路径,若该环境变量未设置或路径设置失败,该日志默认不打印。
例如:
export MRT_LOG_CJTHREAD=/home/cangjie/runtime/cjthread_log.txt
cjHeapDumpOnOOM
指定是否要在发生堆溢出后输出堆快照文件,默认不开启。支持设置值为[on|off],设定为 on 时开启功能,设定 off 或者其他值不开启功能。
例如:
export cjHeapDumpOnOOM=on
cjHeapDumpLog
指定输出堆快照文件的路径。注意指定的路径必须存在,且应用执行者对其具有读写权限。如果不指定,堆快照文件将输出到当前执行目录。
例如:
export cjHeapDumpLog=/home/cangjie
运行环境可选配置
MRT_STACK_CHECK
开启 native stack overflow 检查,默认不开启,支持设置值为 1、true、TRUE 开启功能。
例如:
export MRT_STACK_CHECK=true
CJ_SOF_SIZE
当 StackOverflowError 发生时,将自动进行异常栈折叠方便用户阅读,折叠后栈帧层数默认值是 32。可以通过配置此环境变量控制折叠栈长度,支持设置为 int 范围内的整数。 CJ_SOF_SIZE = 0,打印所有调用栈; CJ_SOF_SIZE < 0,从栈底开始打印环境变量配置层数; CJ_SOF_SIZE > 0,从栈顶开始打印环境变量配置层数; CJ_SOF_SIZE 未配置,默认打印栈顶开始 32 层调用栈;
例如:
export CJ_SOF_SIZE=30
关键字
关键字是不能作为标识符使用的特殊字符串,仓颉语言的关键字如下表所示:
| 关键字 | 关键字 | 关键字 |
|---|---|---|
| as | abstract | break |
| Bool | case | catch |
| class | const | continue |
| Rune | do | else |
| enum | extend | for |
| func | false | finally |
| foreign | Float16 | Float32 |
| Float64 | if | in |
| is | init | import |
| interface | Int8 | Int16 |
| Int32 | Int64 | IntNative |
| let | mut | main |
| macro | match | Nothing |
| open | operator | override |
| prop | public | package |
| private | protected | quote |
| redef | return | spawn |
| super | static | struct |
| synchronized | try | this |
| true | type | throw |
| This | unsafe | Unit |
| UInt8 | UInt16 | UInt32 |
| UInt64 | UIntNative | var |
| VArray | where | while |
操作符
下表列出了仓颉支持的所有操作符的优先级及结合性,其中优先级一栏数值越小,对应操作符的优先级越高。
| 操作符 | 优先级 | 含义 | 示例 | 结合方向 |
|---|---|---|---|---|
@ | 0 | 宏调用 | @id | 右结合 |
. | 1 | 成员访问 | expr.id | 左结合 |
[] | 1 | 索引 | expr[expr] | 左结合 |
() | 1 | 函数调用 | expr(expr) | 左结合 |
++ | 2 | 自增 | var++ | 无 |
-- | 2 | 自减 | var-- | 无 |
? | 2 | 问号 | expr?.id, expr?[expr], expr?(expr), expr?{expr} | 无 |
! | 3 | 按位求反、逻辑非 | !expr | 右结合 |
- | 3 | 一元负号 | -expr | 右结合 |
** | 4 | 幂运算 | expr ** expr | 右结合 |
*, / | 5 | 乘法,除法 | expr * expr, expr / expr | 左结合 |
% | 5 | 取模 | expr % expr | 左结合 |
+, - | 6 | 加法,减法 | expr + expr, expr - expr | 左结合 |
<< | 7 | 按位左移 | expr << expr | 左结合 |
>> | 7 | 按位右移 | expr >> expr | 左结合 |
.. | 8 | 左闭右开区间操作符 | expr..expr | 无 |
..= | 8 | 左闭右闭区间操作符 | expr..=expr | 无 |
< | 9 | 小于 | expr < expr | 无 |
<= | 9 | 小于等于 | expr <= expr | 无 |
> | 9 | 大于 | expr > expr | 无 |
>= | 9 | 大于等于 | expr >= expr | 无 |
is | 9 | 类型检查 | expr is Type | 无 |
as | 9 | 类型转换 | expr as Type | 无 |
== | 10 | 判等 | expr == expr | 无 |
!= | 10 | 判不等 | expr != expr | 无 |
& | 11 | 按位与 | expr & expr | 左结合 |
^ | 12 | 按位异或 | expr ^ expr | 左结合 |
| | 13 | 按位或 | expr | expr | 左结合 |
&& | 14 | 逻辑与 | expr && expr | 左结合 |
|| | 15 | 逻辑或 | expr || expr | 左结合 |
?? | 16 | coalescing 操作符 | expr ?? expr | 右结合 |
|> | 17 | pipeline 操作符 | id |> expr | 左结合 |
~> | 17 | composition 操作符 | expr ~> expr | 左结合 |
= | 18 | 赋值 | id = expr | 无 |
**= | 18 | 复合运算符 | id **= expr | 无 |
*= | 18 | 复合运算符 | id *= expr | 无 |
/= | 18 | 复合运算符 | id /= expr | 无 |
%= | 18 | 复合运算符 | id %= expr | 无 |
+= | 18 | 复合运算符 | id += expr | 无 |
-= | 18 | 复合运算符 | id -= expr | 无 |
<<= | 18 | 复合运算符 | id <<= expr | 无 |
>>= | 18 | 复合运算符 | id >>= expr | 无 |
&= | 18 | 复合运算符 | id &= expr | 无 |
^= | 18 | 复合运算符 | id ^= expr | 无 |
|= | 18 | 复合运算符 | id |= expr | 无 |
&&= | 18 | 复合运算符 | id &&= expr | 无 |
||= | 18 | 复合运算符 | id ||= expr | 无 |
操作符函数
下表列出了仓颉支持的所有操作符函数。
| 操作符函数 | 函数签名 | 示例 |
|---|---|---|
[] (索引取值) | operator func [](index1: T1, index2: T2, ...): R | this[index1, index2, ...] |
[] (索引赋值) | operator func [](index1: T1, index2: T2, ..., value!: TN): R | this[index1, index2, ...] = value |
() | operator func ()(param1: T1, param2: T2, ...): R | this(param1, param2, ...) |
! | operator func !(): R | !this |
** | operator func **(other: T): R | this ** other |
* | operator func *(other: T): R | this * other |
/ | operator func /(other: T): R | this / other |
% | operator func %(other: T): R | this % other |
+ | operator func +(other: T): R | this + other |
- | operator func -(other: T): R | this - other |
<< | operator func <<(other: T): R | this << other |
>> | operator func >>(other: T): R | this >> other |
< | operator func <(other: T): R | this < other |
<= | operator func <=(other: T): R | this <= other |
> | operator func >(other: T): R | this > other |
>= | operator func >=(other: T): R | this >= other |
== | operator func ==(other: T): R | this == other |
!= | operator func !=(other: T): R | this != other |
& | operator func &(other: T): R | this & other |
^ | operator func ^(other: T): R | this ^ other |
| | operator func |(other: T): R | this | other |
TokenKind 类型
public enum TokenKind <: ToString {
DOT| /* "." */
COMMA| /* "," */
LPAREN| /* "(" */
RPAREN| /* ")" */
LSQUARE| /* "[" */
RSQUARE| /* "]" */
LCURL| /* "{" */
RCURL| /* "}" */
EXP| /* "**" */
MUL| /* "*" */
MOD| /* "%" */
DIV| /* "/" */
ADD| /* "+" */
SUB| /* "-" */
INCR| /* "++" */
DECR| /* "--" */
AND| /* "&&" */
OR| /* "||" */
COALESCING| /* "??" */
PIPELINE| /* "|>" */
COMPOSITION| /* "~>" */
NOT| /* "!" */
BITAND| /* "&" */
BITOR| /* "|" */
BITXOR| /* "^" */
BITNOT| /* "~" */
LSHIFT| /* "<<" */
RSHIFT| /* ">>" */
COLON| /* ":" */
SEMI| /* ";" */
ASSIGN| /* "=" */
ADD_ASSIGN| /* "+=" */
SUB_ASSIGN| /* "-=" */
MUL_ASSIGN| /* "*=" */
EXP_ASSIGN| /* "**=" */
DIV_ASSIGN| /* "/=" */
MOD_ASSIGN| /* "%=" */
AND_ASSIGN| /* "&&=" */
OR_ASSIGN| /* "||=" */
BITAND_ASSIGN| /* "&=" */
BITOR_ASSIGN| /* "|=" */
BITXOR_ASSIGN| /* "^=" */
LSHIFT_ASSIGN| /* "<<=" */
RSHIFT_ASSIGN| /* ">>=" */
ARROW| /* "->" */
BACKARROW| /* "<-" */
DOUBLE_ARROW| /* "=>" */
RANGEOP| /* ".." */
CLOSEDRANGEOP| /* "..=" */
ELLIPSIS| /* "..." */
HASH| /* "#" */
AT| /* "@" */
QUEST| /* "?" */
LT| /* "<" */
GT| /* ">" */
LE| /* "<=" */
GE| /* ">=" */
IS| /* "is" */
AS| /* "as" */
NOTEQ| /* "!=" */
EQUAL| /* "==" */
WILDCARD| /* "_" */
INT8| /* "Int8" */
INT16| /* "Int16" */
INT32| /* "Int32" */
INT64| /* "Int64" */
INTNATIVE| /* "IntNative" */
UINT8| /* "UInt8" */
UINT16| /* "UInt16" */
UINT32| /* "UInt32" */
UINT64| /* "UInt64" */
UINTNATIVE| /* "UIntNative" */
FLOAT16| /* "Float16" */
FLOAT32| /* "Float32" */
FLOAT64| /* "Float64" */
RUNE| /* "Rune" */
BOOLEAN| /* "Bool" */
NOTHING| /* "Nothing" */
UNIT| /* "Unit" */
STRUCT| /* "struct" */
ENUM| /* "enum" */
VARRAY| /* "VArray" */
THISTYPE| /* "This" */
PACKAGE| /* "package" */
IMPORT| /* "import" */
CLASS| /* "class" */
INTERFACE| /* "interface" */
FUNC| /* "func" */
MACRO| /* "macro" */
QUOTE| /* "quote" */
DOLLAR| /* "$" */
LET| /* "let" */
VAR| /* "var" */
CONST| /* "const" */
TYPE| /* "type" */
INIT| /* "init" */
THIS| /* "this" */
SUPER| /* "super" */
IF| /* "if" */
ELSE| /* "else" */
CASE| /* "case" */
TRY| /* "try" */
CATCH| /* "catch" */
FINALLY| /* "finally" */
FOR| /* "for" */
DO| /* "do" */
WHILE| /* "while" */
THROW| /* "throw" */
RETURN| /* "return" */
CONTINUE| /* "continue" */
BREAK| /* "break" */
IN| /* "in" */
NOT_IN| /* "!in" */
MATCH| /* "match" */
WHERE| /* "where" */
EXTEND| /* "extend" */
WITH| /* "with" */
PROP| /* "prop" */
STATIC| /* "static" */
PUBLIC| /* "public" */
PRIVATE| /* "private" */
INTERNAL| /* "internal" */
PROTECTED| /* "protected" */
OVERRIDE| /* "override" */
REDEF| /* "redef" */
ABSTRACT| /* "abstract" */
SEALED| /* "sealed" */
OPEN| /* "open" */
FOREIGN| /* "foreign" */
INOUT| /* "inout" */
MUT| /* "mut" */
UNSAFE| /* "unsafe" */
OPERATOR| /* "operator" */
SPAWN| /* "spawn" */
SYNCHRONIZED| /* "synchronized */
UPPERBOUND| /* "<:" */
MAIN| /* "main" */
IDENTIFIER| /* "x" */
PACKAGE_IDENTIFIER| /* "x-y" */
INTEGER_LITERAL| /* e.g. "1" */
RUNE_BYTE_LITERAL| /* e.g. "b'x'" */
FLOAT_LITERAL| /* e.g. "'1.0'" */
COMMENT| /* e.g. "//xx" */
NL| /* newline */
END| /* end of file */
SENTINEL| /* ";" */
RUNE_LITERAL| /* e.g. "r'x'" */
STRING_LITERAL| /* e.g. ""xx"" */
SINGLE_QUOTED_STRING_LITERAL|
/* e.g. "'xx'" */
JSTRING_LITERAL| /* e.g. "J"xx"" */
MULTILINE_STRING| /* e.g. """"aaa"""" */
MULTILINE_RAW_STRING| /* e.g. "#"aaa"#" */
BOOL_LITERAL| /* "true" or "false" */
UNIT_LITERAL| /* "()" */
DOLLAR_IDENTIFIER| /* e.g. "$x" */
ANNOTATION| /* e.g. "@When" */
AT_EXCL| /* e.g. "@!" */
ILLEGAL|
...
}
仓颉编程语言标准库概述
仓颉编程语言标准库(std)是安装仓颉 SDK 时默认自带的库。标准库预先定义了一组函数、类、结构体等,旨在提供常用的功能和工具,以便开发者能够更快速、更高效地编写程序。
仓颉标准库有其三项特点和追求:
- 使用方便:标准库随编译器、工具链一起发布,不需要用户另外下载,开箱即用。
- 功能通用:标准库提供了开发者最常使用的一些库能力,旨在为开发者解决大部分基础问题。
- 质量标杆:标准库追求在性能、代码风格等方面为其他仓颉库树立范例和标杆。
使用指导
在仓颉编程语言中,标准库包含了若干包(package),而包是编译的最小单元。每个包可以单独输出 AST(Abstract Syntax Trees,抽象语法树)文件、静态库文件、动态库文件等产物。包可以定义子包,从而构成树形结构。没有父包的包称为 root 包,root 包及其子包(包括子包的子包)构成的整棵树称为模块(module)。模块的名称与 root 包相同,是开发者发布的最小单元。
包的导入规则如下:
-
可以导入某个包中的一个顶层声明或定义,语法如下:
import fullPackageName.itemName其中 fullPackageName 为完整路径包名,itemName 为声明的名字,例如:
import std.collection.ArrayList -
如果要导入的多个 itemName 同属于一个 fullPackageName,可以使用:
import fullPackageName.{itemName[, itemName]*}例如:
import std.collection.{ArrayList, HashMap} -
还可以将 fullPackageName 包中所有 public 修饰的顶层声明或定义全部导入,语法如下:
import fullPackageName.*例如:
import std.collection.*
包列表
std 含若干包,提供丰富的基础功能:
| 包名 | 功能 |
|---|---|
| core | core 包是标准库的核心包,提供了适用仓颉语言编程最基本的一些 API 能力。 |
| argopt | argopt 包提供从命令行参数字符串解析出参数名和参数值的相关能力。 |
| ast | ast 包主要包含了仓颉源码的语法解析器和仓颉语法树节点,提供语法解析函数。 |
| binary | binary 包提供了基础数据类型和二进制字节数组的不同端序转换接口,以及端序反转接口。 |
| collection | collection 包提供了常见数据结构的高效实现、相关抽象的接口的定义以及在集合类型中常用的函数功能。 |
| collection.concurrent | collection.concurrent 包提供了并发安全的集合类型实现。 |
| console | console 包提供和标准输入、标准输出、标准错误进行交互的方法。 |
| convert | convert 包提供从字符串转到特定类型的 Convert 系列函数以及提供格式化能力,主要为将仓颉类型实例转换为格式化字符串。 |
| crypto.cipher | crypto.cipher 包提供对称加解密通用接口。 |
| crypto.digest | crypto.digest 包提供常用摘要算法的通用接口,包括 MD5、SHA1、SHA224、SHA256、SHA384、SHA512、HMAC、SM3。 |
| database.sql | database.sql 包提供仓颉访问数据库的接口。 |
| deriving | deriving 包提供一组宏来自动生成接口实现。 |
| env | env 包提供当前进程的相关信息与功能、包括环境变量、命令行参数、标准流、退出程序。 |
| fs | fs(file system)包提供对文件、文件夹、路径、文件元数据信息的一些操作函数。 |
| io | io 包提供程序与外部设备进行数据交换的能力。 |
| math | math 包提供常见的数学运算,常数定义,浮点数处理等功能。 |
| math.numeric | math.numeric 包对基础类型可表达范围之外提供扩展能力。 |
| net | net 包提供常见的网络通信功能。 |
| objectpool | objectpool 包提供了对象缓存和复用的功能。 |
| overflow | overflow 包提供了溢出处理相关能力。 |
| posix | posix 包封装 POSIX 系统调用,提供跨平台的系统操作接口。 |
| process | process 包主要提供 Process 进程操作接口,主要包括进程创建,标准流获取,进程等待,进程信息查询等。 |
| random | random 包提供生成伪随机数的能力。 |
| reflect | reflect 包提供了反射功能,使得程序在运行时能够获取到各种实例的类型信息,并进行各种读写和调用操作。 |
| regex | regex 包使用正则表达式分析处理文本的能力(支持 UTF-8 编码的 Unicode 字符串),支持查找、分割、替换、验证等功能。 |
| runtime | runtime 包的作用是与程序的运行时环境进行交互,提供了一系列函数和变量,用于控制、管理和监视程序的执行。 |
| sort | sort 包提供数组类型的排序函数。 |
| sync | sync 包提供并发编程相关的能力。 |
| time | time 包提供了与时间相关的类型,包括日期时间,时间间隔,单调时间和时区等,并提供了计算和比较的功能。 |
| unicode | unicode 包提供了按 unicode 编码标准处理字符的能力。 |
| unittest | unittest 包用于编写仓颉项目单元测试代码,提供包括代码编写、运行和调测在内的基本功能。 |
| unittest.mock | unittest.mock 包提供仓颉单元测试的 mock 框架,提供 API 用于创建和配置 mock 对象,这些 mock 对象与真实对象拥有签名一致的 API 。 |
| unittest.testmacro | unittest.testmacro 为单元测试框架提供了用户所需的宏。 |
| unittest.mock.mockmacro | unittest.mock.mockmacro 为 mock 框架提供了用户所需的宏。 |
| unittest.common | unittest.common 为单元测试框架提供了打印所需的类型和一些通用方法。 |
| unittest.diff | unittest.diff 为单元测试框架提供了打印差异对比信息所需的 API 。 |
| unittest.prop_test | unittest.prop_test 为单元测试框架提供了参数化测试所需的类型和一些通用方法。 |
std.core
功能介绍
core 包是标准库的核心包,提供了适用仓颉语言编程最基本的一些 API 能力。
提供了内置类型(有符号整型、无符号整型、浮点型等)、常用函数(print、println、eprint 等)、常用接口(ToString、Hashable、Equatable、Collection 等)、常用类和结构体(Array、String、Range 等)、常用异常类(Error、Exception 以及它们的一些细分子类)。
说明:
core 包不需要显式导入,默认导入。
API 列表
函数
| 函数名 | 功能 |
|---|---|
| acquireArrayRawData(Array<T>) where T <: CType | 获取 Array<T> 中数据的原始指针实例,T 需要满足 CType 约束。 |
| alignOf<T>() where T <: CType | 获取类型 T 的内存对齐值。 |
| eprint(String, Bool) | 将指定字符串打印到标准错误文本流。 |
| eprintln(String) | 将指定字符串打印到标准错误文本流,末尾添加换行。 |
| eprint<T>(T, Bool) where T <: ToString | 将指定 T 类型实例的字符串表示打印到标准错误文本流。 |
| eprintln<T>(T) where T <: ToString | 将指定 T 类型实例的字符串表示打印到标准错误文本流,末尾添加换行。 |
| ifNone(Option<T>, () -> Unit) | 如果输入是 Option.None 类型数据,则执行 action 函数。 |
| ifSome(Option<T>, (T) -> Unit) | 如果输入是 Option.Some 类型数据,则执行 action 函数。 |
| max<T>(T, T, Array<T>) where T <: Comparable<T> | 获取一组数据中的最大值 |
| min<T>(T, T, Array<T>) where T <: Comparable<T> | 获取一组数据中的最小值 |
| print(Bool, Bool) | 向控制台输出 Bool 类型数据的字符串表达。 |
| print(Float16, Bool) | 向控制台输出 Float16 类型数据的字符串表达。 |
| print(Float32, Bool) | 向控制台输出 Float32 类型数据的字符串表达。 |
| print(Float64, Bool) | 向控制台输出 Float64 类型数据的字符串表达。 |
| print(Int16, Bool) | 向控制台输出 Int16 类型数据的字符串表达。 |
| print(Int32, Bool) | 向控制台输出 Int32 类型数据的字符串表达。 |
| print(Int64, Bool) | 向控制台输出 Int64 类型数据的字符串表达。 |
| print(Int8, Bool) | 向控制台输出 Int8 类型数据的字符串表达。 |
| print(Rune, Bool) | 向控制台输出 Rune 类型数据的字符串表达。 |
| print(String, Bool) | 向控制台输出指定字符串。 |
| print(UInt16, Bool) | 向控制台输出 UInt16 类型数据的字符串表达。 |
| print(UInt32, Bool) | 向控制台输出 UInt32 类型数据的字符串表达。 |
| print(UInt64, Bool) | 向控制台输出 UInt64 类型数据的字符串表达。 |
| print(UInt8, Bool) | 向控制台输出 UInt8 类型数据的字符串表达。 |
| print<T>(T, Bool) where T <: ToString | 向控制台输出 T 类型实例的字符串表示。 |
| println() | 向标准输出(stdout)输出换行符。 |
| println(Bool) | 向控制台输出 Bool 类型数据的字符串表达,末尾添加换行。 |
| println(Float16) | 向控制台输出 Float16 类型数据的字符串表达,末尾添加换行。 |
| println(Float32) | 向控制台输出 Float32 类型数据的字符串表达,末尾添加换行。 |
| println(Float64) | 向控制台输出 Float64 类型数据的字符串表达,末尾添加换行。 |
| println(Int16) | 向控制台输出 Int16 类型数据的字符串表达,末尾添加换行。 |
| println(Int32) | 向控制台输出 Int32 类型数据的字符串表达,末尾添加换行。 |
| println(Int64) | 向控制台输出 Int64 类型数据的字符串表达,末尾添加换行。 |
| println(Int8) | 向控制台输出 Int8 类型数据的字符串表达,末尾添加换行。 |
| println(Rune) | 向控制台输出 Rune 类型数据的字符串表达,末尾添加换行。 |
| println(String) | 向控制台输出指定字符串,末尾添加换行。 |
| println(UInt16) | 向控制台输出 UInt16 类型数据的字符串表达,末尾添加换行。 |
| println(UInt32) | 向控制台输出 UInt32 类型数据的字符串表达,末尾添加换行。 |
| println(UInt64) | 向控制台输出 UInt64 类型数据的字符串表达,末尾添加换行。 |
| println(UInt8) | 向控制台输出 UInt8 类型数据的字符串表达,末尾添加换行。 |
| println<T>(T) where T <: ToString | 向控制台输出 T 类型实例的字符串表示,末尾添加换行。 |
| readln() | 接受控制台输入,直到遇到换行或EOF结束。 |
| refEq(Object, Object) | 判断两个 Object 实例的内存地址是否相同。 |
| releaseArrayRawData(CPointerHandle<T>) where T <: CType | 释放原始指针实例,该实例通过 acquireArrayRawData 获取。 |
| sizeOf<T>() where T <: CType | 获取类型 T 所占用的内存空间大小。 |
| sleep(Duration) | 休眠当前线程。 |
| zeroValue<T>() | 获取一个已全零初始化的 T 类型实例。 |
类型别名
内置类型
| 内置类型名 | 功能 |
|---|---|
| Int8 | 表示 8 位有符号整型,表示范围为 [-2^7, 2^7 - 1]。 |
| Int16 | 表示 16 位有符号整型,表示范围为 [-2^{15}, 2^{15} - 1]。 |
| Int32 | 表示 32 位有符号整型,表示范围为 [-2^{31}, 2^{31} - 1]。 |
| Int64 | 表示 64 位有符号整型,表示范围为 [-2^{63}, 2^{63} - 1]。 |
| IntNative | 表示平台相关的有符号整型,其长度与当前系统的位宽一致。 |
| UInt8 | 表示 8 位无符号整型,表示范围为 [0 ~ 2^8 - 1]。 |
| UInt16 | 表示 16 位无符号整型,表示范围为 [0 ~ 2^{16} - 1]。 |
| UInt32 | 表示 32 位无符号整型,表示范围为 [0 ~ 2^{32} - 1]。 |
| UInt64 | 表示 64 位无符号整型,表示范围为 [0 ~ 2^{64} - 1]。 |
| UIntNative | 表示平台相关的无符号整型,其长度与当前系统的位宽一致。 |
| Float16 | 表示 16 位浮点数,符合 IEEE 754 中的半精度格式(binary16)。 |
| Float32 | 表示 32 位浮点数,符合 IEEE 754 中的单精度格式(binary32)。 |
| Float64 | 表示 64 位浮点数,符合 IEEE 754 中的双精度格式(binary64)。 |
| Bool | 表示布尔类型,有 true 和 false 两种取值。 |
| Rune | 表示 unicode 字符集中的字符。 |
| Unit | 表示仓颉语言中只关心副作用而不关心值的表达式的类型。 |
| CPointer<T> | 表示 T 类型实例的指针,在与 C 语言互操作的场景下使用,对应 C 语言的 T*。 |
| CString | 表示 C 风格字符串,在与 C 语言互操作的场景下使用。 |
接口
| 接口名 | 功能 |
|---|---|
| Any | Any 是所有类型的父类型,所有 interface 都默认继承它,所有非 interface 类型都默认实现它。 |
| Hasher | 该接口用于处理哈希组合运算。 |
| ThreadContext | 仓颉线程上下文接口。 |
| Countable<T> | 该接口表示类型可数。 |
| Collection<T> | 该接口用来表示集合,通常容器类型应该实现该接口。 |
| Less<T> | 该接口表示小于计算。 |
| Greater<T> | 该接口表示大于计算。 |
| LessOrEqual<T> | 该接口表示小于等于计算。 |
| GreaterOrEqual<T> | 该接口表示大于等于计算。 |
| Comparable<T> | 该接口表示比较运算,是等于、小于、大于、小于等于、大于等于接口的集合体。 |
| Equal<T> | 该接口用于支持判等操作。 |
| NotEqual<T> | 该接口用于支持判不等操作。 |
| Equatable<T> | 该接口是判等和判不等两个接口的集合体。 |
| Hashable | 该接口用于计算哈希值。 |
| Iterable<E> | 该接口表示可迭代,实现了该接口的类型(通常为容器类型)可以在 for-in 语句中实现迭代,也可以获取其对应的迭代器类型实例,调用 next 函数实现迭代。 |
| Resource | 该接口用于资源管理,通常用于内存、句柄等资源的关闭和释放。 |
| ToString | 该接口用来提供具体类型的字符串表示。 |
| CType | 表示支持与 C 语言互操作的接口。 |
类
| 类名 | 功能 |
|---|---|
| ArrayIterator<T> | 数组迭代器,迭代功能详述见 Iterable 和 Iterator 接口说明。 |
| Box<T> | Box 类型提供了为其他类型添加一层 class 封装的能力。 |
| Future<T> | Future<T> 实例代表一个仓颉线程任务,可用于获取仓颉线程的计算结果,向仓颉线程发送取消信号。 |
| Iterator<T> | 该类表示迭代器,提供 next 方法支持对容器内的成员进行迭代遍历。 |
| Object | 构造一个 object 实例。 |
| RangeIterator<T> <: Iterator<T> where T <: Countable<T> & Comparable<T> & Equatable<T> | Range 类型的迭代器,迭代功能详述见 Iterable 和 Iterator 接口说明。 |
| StackTraceElement | 表示一个异常堆栈的具体信息,包括异常发生的类名、函数名、文件名、行号。 |
| StringBuilder | 该类主要用于字符串的构建。 |
| Thread | Thread 类代表一个仓颉类,可用于获取线程 ID 及名字、查询线程是否存在取消请求、注册线程未处理异常的处理函数等。 |
| ThreadLocal<T> | 该类表示仓颉线程局部变量。 |
枚举
| 枚举名 | 功能 |
|---|---|
| AnnotationKind | 表示自定义注解希望支持的位置。 |
| Endian | 枚举类型 Endian 表示运行平台的端序,分为大端序和小端序。 |
| Ordering | Ordering 表示比较大小的结果,它包含三种情况:小于,大于和等于。 |
| Option<T> | Option<T> 是对 T 类型的封装,表示可能有值也可能无值。 |
结构体
| 结构体名 | 功能 |
|---|---|
| Array<T> | 仓颉数组类型,用来表示单一类型的元素构成的有序序列。 |
| CPointerHandle<T> where T <: CType | 表示 Array 数组的原始指针,该类型中的泛型参数应该满足 CType 约束。 |
| CPointerResource<T> where T <: CType | 该结构体表示 CPointer 对应的资源管理类型,其实例可以通过 CPointer 的成员函数 asResource 获取。 |
| CStringResource | 该结构体表示 CString 对应的资源管理类型,其实例可以通过 CString 的成员函数 asResource 获取。 |
| DefaultHasher | 该结构体提供了默认哈希算法实现。 |
| Duration | 表示时间间隔,是一个描述一段时间的时间类型,提供了常用的静态实例,以及计算、比较等功能。 |
| LibC | 提供了仓颉中较为高频使用的 C 接口,如申请、释放堆上 CType 实例。 |
| Range<T> where T <: Countable<T> & Comparable<T> & Equatable<T> | 该类是区间类型,用于表示一个拥有固定范围和步长的 T 的序列,要求 T 是可数的,有序的。 |
| String | 该结构体表示仓颉字符串,提供了构造、查找、拼接等一系列字符串操作。 |
异常类
| 异常类名 | 功能 |
|---|---|
| ArithmeticException | 算术异常类,发生算术异常时使用。 |
| Error | Error 是所有错误类的父类。该类不可被继承,不可初始化,但是可以被捕获到。 |
| Exception | Exception 是所有异常类的父类。 |
| IllegalArgumentException | 表示参数非法的异常类。 |
| IllegalFormatException | 表示变量的格式无效或不标准时的异常类。 |
| IllegalMemoryException | 表示内存操作错误的异常类。 |
| IllegalStateException | 表示状态非法的异常类。 |
| IncompatiblePackageException | 表示包不兼容的异常类。 |
| IndexOutOfBoundsException | 表示索引越界的异常类。 |
| InternalError | 表示内部错误的错误类,该类不可初始化,但是可以被捕获到。 |
| NegativeArraySizeException | 表示数组大小为负数的异常类。 |
| NoneValueException | 表示 Option<T> 实例的值为 None 的异常类,通常在 getOrThrow 函数中被抛出。 |
| OutOfMemoryError | 表示内存不足错误的错误类,该类不可被继承,不可初始化,但是可以被捕获到。 |
| OverflowException | 表示算术运算溢出的异常类。 |
| SpawnException | 线程异常类,表示线程处理过程中发生异常。 |
| StackOverflowError | 表示堆栈溢出错误的错误类,该类不可被继承,不可初始化,但是可以被捕获到。 |
| TimeoutException | 当阻塞操作超时时引发异常。 |
| UnsupportedException | 表示功能未支持的异常类。 |
函数
func acquireArrayRawData<T>(Array<T>) where T <: CType
public unsafe func acquireArrayRawData<T>(arr: Array<T>): CPointerHandle<T> where T <: CType
功能:获取 Array<T> 中数据的原始指针实例,指针实例指向数组首元素的地址,T 需要满足 CType 约束。
注意:
指针使用完后需要及时用 releaseArrayRawData 函数释放该指针。 指针的获取和释放之间仅可包含简单的 foreign C 函数调用等逻辑,不构造例如 CString 等的仓颉对象,否则可能造成不可预期现象。
参数:
- arr: Array<T> - 待获取原始指针的数组。
返回值:
- CPointerHandle<T> - 数组的原始指针实例。
示例:
main() {
var arr: Array<Int64> = [1, 2, 3, 4]
var cptrHandle: CPointerHandle<Int64> = unsafe { acquireArrayRawData(arr) }
var cptr: CPointer<Int64> = cptrHandle.pointer
let num: Int64 = unsafe { cptr.read() }
println("The first element of the array is ${num} ")
unsafe { releaseArrayRawData<Int64>(cptrHandle) }
}
运行结果:
The first element of the array is 1
func alignOf<T>() where T <: CType
public func alignOf<T>(): UIntNative where T <: CType
功能:获取类型 T 的内存对齐值。
返回值:
- UIntNative - 类型 T 满足内存对齐要求的字节数。
示例:
@C
struct Data {
var a: Int64 = 0
var b: Float32 = 0.0
}
main() {
let alignSizeInt8: UIntNative = alignOf<Int8>()
println("The memory alignment requirement for Int64 type is ${alignSizeInt8} byte")
let alignSizeInt32: UIntNative = alignOf<Int32>()
println("The memory alignment requirement for Int64 type is ${alignSizeInt32} bytes")
let alignSizeInt64: UIntNative = alignOf<Int64>()
println("The memory alignment requirement for Int64 type is ${alignSizeInt64} bytes")
let alignSizeData: UIntNative = alignOf<Data>()
println("The memory alignment requirement for Int64 type is ${alignSizeData} bytes")
}
运行结果:
The memory alignment requirement for Int64 type is 1 byte
The memory alignment requirement for Int64 type is 4 bytes
The memory alignment requirement for Int64 type is 8 bytes
The memory alignment requirement for Int64 type is 8 bytes
func eprint(String, Bool)
public func eprint(str: String, flush!: Bool = true): Unit
功能:将指定字符串打印到标准错误文本流。
如抛出异常时,消息将打印到标准错误文本流(stderr),而不是标准输出(stdout)。
参数:
- str: String - 待输出的字符串。
- flush!: Bool - 是否将缓存数据区的内容立即刷新写入与标准错误流相关的文件和设备中,true表示立即刷新,false表示暂不刷新 ,默认 false。
示例:
main() {
try {
throw NegativeArraySizeException("I am an Exception!")
} catch (e: NegativeArraySizeException) {
eprint("NegativeArraySizeException is caught!", flush: true)
}
}
运行结果:
NegativeArraySizeException is caught!
func eprintln(String)
public func eprintln(str: String): Unit
功能:将指定字符串打印到标准错误文本流,末尾添加换行。
如抛出异常时,消息将打印到标准错误文本流(stderr),而不是标准输出(stdout)。
参数:
- str: String - 待输出的字符串。
示例:
main() {
try {
throw NegativeArraySizeException("I am an Exception!")
} catch (e: NegativeArraySizeException) {
eprintln("NegativeArraySizeException is caught!")
}
}
运行结果:
NegativeArraySizeException is caught!
func eprint<T>(T, Bool) where T <: ToString
public func eprint<T>(arg: T, flush!: Bool = false): Unit where T <: ToString
功能:将指定 T 类型实例的字符串表示打印到标准错误文本流。
如抛出异常时,消息将打印到标准错误文本流(stderr),而不是标准输出(stdout)。
参数:
- arg: T - 待打印的 T 类型实例,该函数将打印其 toString 的返回值。
- flush!: Bool - 是否清空缓存,true 清空,false 不清空,默认 false。
示例:
class Rectangle <: ToString{
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
public func toString(): String{
return "width: ${this.width}, height: ${this.height}"
}
}
main() {
try {
throw NegativeArraySizeException("I am an Exception!")
} catch (e: NegativeArraySizeException) {
eprint<Rectangle>(Rectangle(10,20), flush: true)
}
}
运行结果:
width: 10, height: 20
func eprintln<T>(T) where T <: ToString
public func eprintln<T>(arg: T): Unit where T <: ToString
功能:将指定 T 类型实例的字符串表示打印到标准错误文本流,末尾添加换行。
如抛出异常时,消息将打印到标准错误文本流(stderr),而不是标准输出(stdout)。
参数:
- arg: T - 待打印的 T 类型实例,该函数将打印其 toString 的返回值。
示例:
class Rectangle <: ToString{
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
public func toString(): String{
return "width: ${this.width}, height: ${this.height}"
}
}
main() {
try {
throw NegativeArraySizeException("I am an Exception!")
} catch (e: NegativeArraySizeException) {
eprintln<Rectangle>(Rectangle(10,20))
}
}
运行结果:
width: 10, height: 20
func ifNone<T>(Option<T>, () -> Unit)
public func ifNone<T>(o: Option<T>, action: () -> Unit): Unit
功能:如果输入是 Option.None 类型数据,则执行 action 函数。
参数:
示例:
main() {
let num: Option<Int64> = None
ifNone<Int64>(num,{=> println("num is None")})
}
运行结果:
num is None
func ifSome<T>(Option<T>, (T) -> Unit)
public func ifSome<T>(o: Option<T>, action: (T) -> Unit): Unit
功能:如果输入是 Option.Some 类型数据,则执行 action 函数。
参数:
- o: Option<T> - 待判断是否为 Option.Some 的 Option<T> 类型实例,同时其封装的
T类型实例将作为 action 函数的输入。 - action: (T) ->Unit - 待执行函数。
示例:
main() {
let num: Option<Int64> = Some(200)
ifSome<Int64>(num,{numValue: Int64 => println("num is ${numValue}")})
}
运行结果:
num is 200
func max<T>(T, T, Array<T>) where T <: Comparable<T>
public func max<T>(a: T, b: T, others: Array<T>): T where T <: Comparable<T>
功能:根据 T 类型的 Comparable 接口实现,返回一组数据中的最大值,由于此函数的第三个参数是一个变长参数,支持获取二个以上的数据的比较。
注意:
浮点数类型的比较也将按照 Comparable 的结果进行比较,如果浮点书中有非数
NaN,结果将不正确,此时建议使用 Float16、Float32、Float64 的static func max方法。
参数:
- a: T - 第一个待比较的数。
- b: T - 第二个待比较的数。
- others: Array<T> - 其他待比较的数。
返回值:
- T - 返回参数中的最大值。
示例:
class Rectangle <: Comparable<Rectangle> & ToString{
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public prop area: Int64 {
get() {
return this.width * this.height
}
}
public func compare(t: Rectangle): Ordering {
if (t.area > this.area) {
return Ordering.LT
} else if (t.area == this.area) {
return Ordering.EQ
} else {
Ordering.GT
}
}
public func toString(): String{
return "width: ${this.width}, height: ${this.height}, area: ${this.area}"
}
}
main() {
var r1: Rectangle = Rectangle(10, 20)
var r2: Rectangle = Rectangle(20, 30)
println("The larger one is ${max(r1, r2)}")
}
运行结果:
The larger one is width: 20, height: 30, area: 600
func min<T>(T, T, Array<T>) where T <: Comparable<T>
public func min<T>(a: T, b: T, others: Array<T>): T where T <: Comparable<T>
功能:根据 T 类型的 Comparable 接口实现,返回一组数据中的最小值,由于此函数的第三个参数是一个变长参数,支持获取二个以上的数据的比较。
注意:
浮点数类型的比较也将按照Comparable的结果进行比较,如果浮点书中有非数
NaN,结果将不正确,此时建议使用 Float16、Float32、Float64 的static func min方法。
参数:
- a: T - 第一个待比较的数。
- b: T - 第二个待比较的数。
- others: Array<T> - 其他待比较的数。
返回值:
- T - 返回参数中的最小值。
示例:
class Rectangle <: Comparable<Rectangle> & ToString {
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public prop area: Int64 {
get() {
return this.width * this.height
}
}
public func compare(t: Rectangle): Ordering {
if (t.area > this.area) {
return Ordering.LT
} else if (t.area == this.area) {
return Ordering.EQ
} else {
Ordering.GT
}
}
public func toString(): String {
return "width: ${this.width}, height: ${this.height}, area: ${this.area}"
}
}
main() {
var r1: Rectangle = Rectangle(10, 20)
var r2: Rectangle = Rectangle(20, 30)
println("The smaller one is ${min(r1, r2)}")
}
运行结果:
The smaller one is width: 10, height: 20, area: 200
func print(Bool, Bool)
public func print(b: Bool, flush!: Bool = false): Unit
功能:向控制台输出 Bool 类型数据的字符串表达。
注意:
参数:
示例:
main() {
var flag: Bool = false
print(flag)
flag = true
println()
print(flag)
}
运行结果:
false
true
func print(Float16, Bool)
public func print(f: Float16, flush!: Bool = false): Unit
功能:向控制台输出 Float16 类型数据的小数点后六位的字符串表达,即超出六位的小数位不会输出,不足六位的小数位会补零。
参数:
示例:
main() {
var num1: Float16 = 0.76
var num2: Float16 = 0.68
print(num1)
println()
print(num2)
}
运行结果:
0.759766
0.680176
注意:
仓颉采用IEEE 754格式表示浮点数,保存数值可能会有误差。
func print(Float32, Bool)
public func print(f: Float32, flush!: Bool = false): Unit
功能:向控制台输出 Float32 类型数据的小数点后六位的字符串表达,即超出六位的小数位不会输出,不足六位的小数位会补零。
参数:
示例:
main() {
var num1: Float32 = 0.759766
var num2: Float32 = 0.680176
print(num1)
println()
print(num2)
}
运行结果:
0.759766
0.680176
func print(Float64, Bool)
public func print(f: Float64, flush!: Bool = false): Unit
功能:向控制台输出 Float64 类型数据的小数点后六位的字符串表达,即超出六位的小数位不会输出,不足六位的小数位会补零。
参数:
示例:
main() {
var num1: Float64 = 0.76453
var num2: Float64 = 0.683456
print(num1)
println()
print(num2)
}
运行结果:
0.764530
0.683456
func print(Int16, Bool)
public func print(i: Int16, flush!: Bool = false): Unit
功能:向控制台输出 Int16 类型数据的字符串表达。
参数:
示例:
main() {
var num1: Int16 = 10
var num2: Int16 = 2222
print(num1)
println()
print(num2)
}
运行结果:
10
2222
func print(Int32, Bool)
public func print(i: Int32, flush!: Bool = false): Unit
功能:向控制台输出 Int32 类型数据的字符串表达。
参数:
示例:
main() {
var num1: Int32 = 1024
var num2: Int32 = 2048
print(num1)
println()
print(num2)
}
运行结果:
1024
2048
func print(Int64, Bool)
public func print(i: Int64, flush!: Bool = false): Unit
功能:向控制台输出 Int64 类型数据的字符串表达。
参数:
示例:
main() {
var num1: Int64 = 1024
var num2: Int64 = 2048
print(num1)
println()
print(num2)
}
运行结果:
1024
2048
func print(Int8, Bool)
public func print(i: Int8, flush!: Bool = false): Unit
功能:向控制台输出 Int8 类型数据的字符串表达。
参数:
示例:
main() {
var num1: Int8 = 8
var num2: Int8 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func print(Rune, Bool)
public func print(c: Rune, flush!: Bool = false): Unit
功能:向控制台输出 Rune 类型数据的字符串表达。
参数:
示例:
main() {
var char: Rune = r'a'
print(char)
}
运行结果:
a
func print(String, Bool)
public func print(str: String, flush!: Bool = false): Unit
功能:向控制台输出指定字符串。
参数:
示例:
main() {
var str: String = "I like Cangjie"
print(str)
}
运行结果:
I like Cangjie
func print(UInt16, Bool)
public func print(i: UInt16, flush!: Bool = false): Unit
功能:向控制台输出 UInt16 类型数据的字符串表达。
参数:
示例:
main() {
var num1: UInt16 = 8
var num2: UInt16 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func print(UInt32, Bool)
public func print(i: UInt32, flush!: Bool = false): Unit
功能:向控制台输出 UInt32 类型数据的字符串表达。
参数:
示例:
main() {
var num1: UInt16 = 8
var num2: UInt16 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func print(UInt64, Bool)
public func print(i: UInt64, flush!: Bool = false): Unit
功能:向控制台输出 UInt64 类型数据的字符串表达。
参数:
示例:
main() {
var num1: UInt64 = 8
var num2: UInt64 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func print(UInt8, Bool)
public func print(i: UInt8, flush!: Bool = false): Unit
功能:向控制台输出 UInt8 类型数据的字符串表达。
参数:
示例:
main() {
var num1: UInt8 = 8
var num2: UInt8 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func print<T>(T, Bool) where T <: ToString
public func print<T>(arg: T, flush!: Bool = false): Unit where T <: ToString
功能:向控制台输出 T 类型实例的字符串表示。
参数:
示例:
class Rectangle <: ToString {
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
public func toString(): String {
return "width: ${this.width}, height: ${this.height}"
}
}
main() {
print<Rectangle>(Rectangle(10, 20))
}
运行结果:
width: 10, height: 20
func println()
public func println(): Unit
功能:向标准输出(stdout)输出换行符。
示例:
main() {
var num1: UInt8 = 8
var num2: UInt8 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func println(Bool)
public func println(b: Bool): Unit
功能:向控制台输出 Bool 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var flag1: Bool = true
var flag2: Bool = false
println(flag1)
println(flag2)
}
运行结果:
true
false
func println(Float16)
public func println(f: Float16): Unit
功能:向控制台输出 Float16 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: Float16 = 3.1415
var num2: Float16 = 3.141592
println(num1)
println(num2)
}
运行结果:
3.140625
3.140625
func println(Float32)
public func println(f: Float32): Unit
功能:向控制台输出 Float32 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: Float32 = 3.1415
var num2: Float32 = 3.141592
println(num1)
println(num2)
}
运行结果:
3.141500
3.141592
func println(Float64)
public func println(f: Float64): Unit
功能:向控制台输出 Float64 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: Float64 = 3.1415
var num2: Float64 = 3.141592
println(num1)
println(num2)
}
运行结果:
3.141500
3.141592
func println(Int16)
public func println(i: Int16): Unit
功能:向控制台输出 Int16 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: Int16 = 8
var num2: Int16 = 32
println(num1)
println(num2)
}
运行结果:
8
32
func println(Int32)
public func println(i: Int32): Unit
功能:向控制台输出 Int32 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: Int32 = 8
var num2: Int32 = 32
println(num1)
println(num2)
}
运行结果:
8
32
func println(Int64)
public func println(i: Int64): Unit
功能:向控制台输出 Int64 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: Int64 = 8
var num2: Int64 = 32
println(num1)
println(num2)
}
运行结果:
8
32
func println(Int8)
public func println(i: Int8): Unit
功能:向控制台输出 Int8 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: Int8 = 8
var num2: Int8 = 32
println(num1)
println(num2)
}
运行结果:
8
32
func println(Rune)
public func println(c: Rune): Unit
功能:向控制台输出 Rune 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var char1: Rune = r'a'
var char2: Rune = r'b'
println(char1)
println(char2)
}
运行结果:
a
b
func println(String)
public func println(str: String): Unit
功能:向控制台输出指定字符串,末尾添加换行。
参数:
- str: String - 待输出的字符串。
示例:
main() {
var str1: String = "I like Cangjie"
var str2: String = "I like programming"
println(str1)
println(str2)
}
运行结果:
I like Cangjie
I like programming
func println(UInt16)
public func println(i: UInt16): Unit
功能:向控制台输出 UInt16 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: UInt16 = 8
var num2: UInt16 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func println(UInt32)
public func println(i: UInt32): Unit
功能:向控制台输出 UInt32 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: UInt32 = 8
var num2: UInt32 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func println(UInt64)
public func println(i: UInt64): Unit
功能:向控制台输出 UInt64 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: UInt64 = 8
var num2: UInt64 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func println(UInt8)
public func println(i: UInt8): Unit
功能:向控制台输出 UInt8 类型数据的字符串表达,末尾添加换行。
参数:
示例:
main() {
var num1: UInt8 = 8
var num2: UInt8 = 32
print(num1)
println()
print(num2)
}
运行结果:
8
32
func println<T>(T) where T <: ToString
public func println<T>(arg: T): Unit where T <: ToString
功能:向控制台输出 T 类型实例的字符串表示,末尾添加换行。
参数:
- arg: T - 待输出的数据,支持实现了 ToString 接口的类型。
示例:
class Rectangle <: ToString {
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func toString(): String {
return "width: ${this.width}, height: ${this.height}"
}
}
main() {
println<Rectangle>(Rectangle(10, 20))
println<Rectangle>(Rectangle(5, 10))
}
运行结果:
width: 10, height: 20
width: 5, height: 10
func readln()
public func readln(): String
功能:接受控制台输入,直到遇到换行或EOF结束。
返回值:
- String - 接受到的字符串。
示例:
main() {
var str: String = readln() // Console input 12345 234 and enter
println(str)
}
运行结果:
12345 234
func refEq(Object, Object)
public func refEq(a: Object, b: Object): Bool
功能:判断两个 Object 实例的内存地址是否相同。
参数:
返回值:
示例:
class Rectangle {
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
}
main() {
var r1: Rectangle = Rectangle(10, 20)
var r2: Rectangle = r1
var r3: Rectangle = Rectangle(5, 6)
println(refEq(r1, r2))
println(refEq(r1, r3))
}
运行结果:
true
false
func releaseArrayRawData<T>(CPointerHandle<T>) where T <: CType
public unsafe func releaseArrayRawData<T>(handle: CPointerHandle<T>): Unit where T <: CType
功能:释放原始指针实例,该实例通过 acquireArrayRawData 获取。
参数:
- handle: CPointerHandle<T> - 待释放的指针实例。
示例:
main() {
var arr: Array<Int64> = [1, 2, 3, 4]
var cptrHandle: CPointerHandle<Int64> = unsafe { acquireArrayRawData(arr) }
var cptr: CPointer<Int64> = cptrHandle.pointer
let num: Int64 = unsafe { cptr.read() }
println("The first element of the array is ${num} ")
unsafe { releaseArrayRawData<Int64>(cptrHandle) }
}
运行结果:
The first element of the array is 1
func sizeOf<T>() where T <: CType
public func sizeOf<T>(): UIntNative where T <: CType
功能:获取类型 T 所占用的内存空间大小。
返回值:
- UIntNative - 类型 T 所占用内存空间的字节数。
示例:
@C
struct Data {
var a: Int64 = 0
var b: Float32 = 0.0
}
main() {
let sizeInt8: UIntNative = sizeOf<Int8>()
println("The size of Int8 is ${sizeInt8} byte")
let sizeInt32: UIntNative = sizeOf<Int32>()
println("The size of Int32 is ${sizeInt32} bytes")
let sizeInt64: UIntNative = sizeOf<Int64>()
println("The size of Int64 is ${sizeInt64} bytes")
let sizeData: UIntNative = sizeOf<Data>()
println("The size of Rectangle is ${sizeData} bytes")
}
运行结果:
The size of Int8 is 1 byte
The size of Int32 is 4 bytes
The size of Int64 is 8 bytes
The size of Rectangle is 16 bytes
func sleep(Duration)
public func sleep(dur: Duration): Unit
功能:休眠当前线程。
若 dur 小于等于 Duration.Zero,当前线程会让出运行权。
参数:
- dur: Duration - 线程休眠的时长。
示例:
import std.sync.*
import std.time.*
main(): Int64 {
spawn {
=>
println("New thread starts")
println("New thread ends")
}
println("Main thread")
println("The main thread starts to sleep.")
/* dur == 1 秒 */
sleep(1000 * Duration.millisecond)
println("The main thread ends sleep.")
return 0
}
在启动主线程后,执行到sleep函数的时候,主线程会让出系统执行权,并睡眠 1 秒后重新唤醒竞争系统执行权,继续执行剩余逻辑。在主线程睡眠期间,自定义线程拿到执行权,开始执行。运行结果:
Main thread
The main thread starts to sleep.
New thread starts
New thread ends
The main thread ends sleep.
func zeroValue<T>()
public unsafe func zeroValue<T>(): T
功能:获取一个已全零初始化的 T 类型实例。
注意:
通过该函数获取到的实例一定要赋值为正常初始化的值再使用,否则将引发程序崩溃。
返回值:
- T - 一个已全零初始化的 T 类型实例。
示例:
main(): Int64 {
var m = MyClass<Student>()
m.set(1, Student())
var s = m.get(1)
println(s)
s = m.get(2)
// 底下代码解除注释,运行时就会出错,因为其并不是 Student 对象
// println(s)
return 0
}
class MyClass<T> {
var myData: Array<T>
public init() {
// 用 zeroValue<T>() 对 Array 进行全零初始化
myData = Array<T>(10, repeat: unsafe { zeroValue<T>() })
}
public func get(index: Int64): T {
myData[index]
}
public func set(index: Int64, element: T): Unit {
myData[index] = element
}
}
class Student <: ToString {
public func toString() { "student" }
}
示例结果:
student
类型别名
type Byte
public type Byte = UInt8
type Int
public type Int = Int64
type UInt
public type UInt = UInt64
内置类型
Bool
功能:表示布尔类型,有 true 和 false 两种取值。
extend Bool <: Equatable<Bool>
extend Bool <: Equatable<Bool>
功能:为 Bool 类型扩展 Equatable<Bool> 接口,支持判等操作。
父类型:
extend Bool <: Hashable
extend Bool <: Hashable
功能:为 Bool 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
示例:
main() {
var flag: Bool = false
println(flag.hashCode())
flag = true
println(flag.hashCode())
}
运行结果:
0
1
extend Bool <: ToString
extend Bool <: ToString
功能:为 Bool 类型其扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 Bool 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
示例:
main() {
var flag: Bool = false
let str1: String = flag.toString()
println(str1)
flag = true
let str2: String = flag.toString()
println(str2)
}
运行结果:
false
true
CPointer<T>
功能:表示 T 类型实例的指针,在与 C 语言互操作的场景下使用,对应 C 语言的 T*。
其中 T 必须满足 CType 约束。
CPointer 类型必须满足:
- 大小和对齐与平台相关。
- 对它做加减法算术运算、读写内存,是需要在 unsafe 上下文操作的。
- CPointer<T1> 可以在 unsafe 上下文中使用类型强制转换,变成 CPointer<T2> 类型。
extend<T> CPointer<T>
extend<T> CPointer<T>
功能:为 CPointer<T> 扩展一些必要的指针使用相关接口,包含判空、读写数据等接口。
其中泛型 T 为指针类型,其满足 CType 约束。对 CPointer 做运算需要在 unsafe 上下文中进行。
func asResource()
public func asResource(): CPointerResource<T>
功能:获取该指针 CPointerResource 实例,该实例可以在 try-with-resource 语法上下文中实现内容自动释放。
返回值:
- CPointerResource<T> - 当前指针对应的 CPointerResource 实例。
示例:
foreign func malloc(size: UIntNative): CPointer<Unit>
main() {
let sizeofInt64: UIntNative = 8
var p1 = unsafe { malloc(sizeofInt64) }
var ptr = unsafe { CPointer<Int64>(p1) }
unsafe { ptr.write(10) }
var ptrResource: CPointerResource<Int64> = ptr.asResource()
try (r = ptrResource) {
var p = r.value
let num: Int64 = unsafe { p.read() }
println(num)
}
println(ptrResource.isClosed())
}
运行结果:
10
true
func isNotNull()
public func isNotNull(): Bool
功能:判断指针是否不为空。
返回值:
- Bool - 如果不为空返回 true,否则返回 false。
示例:
foreign func malloc(size: UIntNative): CPointer<Unit>
foreign func free(ptr: CPointer<Unit>): Unit
main() {
let p1 = CPointer<Int64>()
println(p1.isNotNull())
let sizeofInt64: UIntNative = 8
var p2 = unsafe { malloc(sizeofInt64) }
println(p2.isNotNull())
unsafe { free(p2) }
}
运行结果:
false
true
func isNull()
public func isNull(): Bool
功能:判断指针是否为空。
返回值:
- Bool - 如果为空返回 true,否则返回 false。
示例:
foreign func malloc(size: UIntNative): CPointer<Unit>
foreign func free(ptr: CPointer<Unit>): Unit
main() {
let sizeofInt64: UIntNative = 8
var p1 = unsafe { malloc(sizeofInt64) }
var ptr = unsafe { CPointer<Int64>(p1) }
unsafe { ptr.write(10) }
let num: Int64 = unsafe { ptr.read() }
println(num)
unsafe { free(p1) }
}
运行结果:
10
func read()
public unsafe func read(): T
功能:读取第一个数据,该接口需要用户保证指针的合法性,否则发生未定义行为。
返回值:
- T - 该对象类型的第一个数据。
示例:
foreign func malloc(size: UIntNative): CPointer<Unit>
foreign func free(ptr: CPointer<Unit>): Unit
main() {
let p1 = CPointer<Int64>()
println(p1.isNull())
let sizeofInt64: UIntNative = 8
var p2 = unsafe { malloc(sizeofInt64) }
println(p2.isNull())
unsafe { free(p2) }
}
运行结果:
true
false
func read(Int64)
public unsafe func read(idx: Int64): T
功能:根据下标读取对应的数据,该接口需要用户保证指针的合法性,否则发生未定义行为。
参数:
- idx: Int64 - 要获取数据的下标。
返回值:
- T - 输入下标对应的数据。
示例:
main() {
var arr: Array<Int64> = [1, 2, 3, 4]
var cptrHandle: CPointerHandle<Int64> = unsafe { acquireArrayRawData(arr) }
var cptr: CPointer<Int64> = cptrHandle.pointer
let num: Int64 = unsafe { cptr.read(2) }
println("The third element of the array is ${num} ")
unsafe { releaseArrayRawData<Int64>(cptrHandle) }
}
运行结果:
The third element of the array is 3
func toUIntNative()
public func toUIntNative(): UIntNative
功能:获取该指针的整型形式。
返回值:
- UIntNative - 该指针的整型形式。
示例:
foreign func malloc(size: UIntNative): CPointer<Unit>
foreign func free(ptr: CPointer<Unit>): Unit
main() {
let sizeofInt64: UIntNative = 8
var p = unsafe { malloc(sizeofInt64) }
var p1 = unsafe { CPointer<Int64>(p) }
unsafe { p1.write(8) }
println(p1.toUIntNative())
unsafe { free(p) }
}
运行结果:
93954490863648
func write(Int64, T)
public unsafe func write(idx: Int64, value: T): Unit
功能:在指定下标位置写入一个数据,该接口需要用户保证指针的合法性,否则发生未定义行为。
参数:
- idx: Int64 - 指定的下标位置。
- value: T - 写入的数据。
示例:
main() {
var arr: Array<Int64> = [1, 2, 3, 4]
var cptrHandle: CPointerHandle<Int64> = unsafe { acquireArrayRawData(arr) }
var cptr: CPointer<Int64> = cptrHandle.pointer
unsafe { cptr.write(2, 6) }
println("The third element of the array is ${arr[2]} ")
// The first element of the array is 1
unsafe { releaseArrayRawData<Int64>(cptrHandle) }
}
运行结果:
The third element of the array is 6
func write(T)
public unsafe func write(value: T): Unit
功能:写入一个数据,该数据总是在第一个,该接口需要用户保证指针的合法性,否则发生未定义行为。
参数:
- value: T - 要写入的数据。
示例:
foreign func malloc(size: UIntNative): CPointer<Unit>
foreign func free(ptr: CPointer<Unit>): Unit
main() {
let sizeofInt64: UIntNative = 8
var p = unsafe { malloc(sizeofInt64) }
var p1 = unsafe { CPointer<Int64>(p) }
unsafe { p1.write(8) }
let value: Int64 = unsafe { p1.read() }
println(value)
unsafe{ free(p) }
}
运行结果:
8
operator func +(Int64)
public unsafe operator func +(offset: Int64): CPointer<T>
功能:CPointer 对象指针后移,同 C 语言的指针加法操作。
参数:
- offset: Int64 - 偏移量。
返回值:
- CPointer<T> - 返回偏移后的指针。
示例:
main() {
var arr: Array<Int64> = [1, 2, 3, 4]
var cptrHandle: CPointerHandle<Int64> = unsafe { acquireArrayRawData(arr) }
var cptr: CPointer<Int64> = cptrHandle.pointer
let num1: Int64 = unsafe { cptr.read() }
println(num1)
cptr = unsafe { cptr + 1 }
let num2: Int64 = unsafe { cptr.read() }
println(num2)
unsafe { releaseArrayRawData<Int64>(cptrHandle) }
}
运行结果:
1
2
operator func -(Int64)
public unsafe operator func -(offset: Int64): CPointer<T>
功能:CPointer 对象指针前移,同 C 语言的指针减法操作。
参数:
- offset: Int64 - 偏移量。
返回值:
- CPointer<T> - 返回偏移后的指针。
示例:
main() {
var arr: Array<Int64> = [1, 2, 3, 4]
var cptrHandle: CPointerHandle<Int64> = unsafe { acquireArrayRawData(arr) }
var cptr: CPointer<Int64> = cptrHandle.pointer
let num1: Int64 = unsafe { cptr.read() }
println(num1)
cptr = unsafe { cptr + 1 }
let num2: Int64 = unsafe { cptr.read() }
println(num2)
cptr = unsafe { cptr - 1 }
let num3: Int64 = unsafe { cptr.read() }
println(num3)
unsafe { releaseArrayRawData<Int64>(cptrHandle) }
}
运行结果:
1
2
1
CString
功能:表示 C 风格字符串,在与 C 语言互操作的场景下使用。
可以通过 CString 的构造函数或 LibC 的 mallocCString 创建 C 风格字符串,如需在仓颉端释放,则调用 LibC 的 free 方法。
extend CString <: ToString
extend CString <: ToString
功能:为 CString 类型扩展一些字符串指针常用方法,包括判空、获取长度、判等、获取子串等。
父类型:
func asResource()
public func asResource(): CStringResource
功能:获取当前 CString 实例对应的 CStringResource C 字符串资源类型实例。
CStringResource 实现了 Resource 接口,可以在 try-with-resource 语法上下文中实现资源自动释放。
返回值:
- CStringResource - 对应的 CStringResource C 字符串资源类型实例。
示例:
foreign func malloc(size: UIntNative): CPointer<Unit>
main() {
var str: CString = unsafe { LibC.mallocCString("hello") }
var ptrResource: CStringResource = str.asResource()
try (r = ptrResource) {
var p = r.value
println(p.size())
}
println(ptrResource.isClosed())
}
运行结果:
5
true
func compare(CString)
public func compare(str: CString): Int32
功能:按字典序比较两个字符串,同 C 语言中的 strcmp。
参数:
- str: CString - 比较的目标字符串。
返回值:
- Int32 - 两者相等返回 0,如果当前字符串比参数 str 小,返回 -1,否则返回 1。
异常:
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
var str2: CString = unsafe { LibC.mallocCString("hello") }
println(str1.compare(str2))
var str3: CString = unsafe { LibC.mallocCString("hello") }
var str4: CString = unsafe { LibC.mallocCString("hellow") }
println(str3.compare(str4))
var str5: CString = unsafe { LibC.mallocCString("hello") }
var str6: CString = unsafe { LibC.mallocCString("allow") }
println(str5.compare(str6))
unsafe {
LibC.free(str1)
LibC.free(str2)
LibC.free(str3)
LibC.free(str4)
LibC.free(str5)
LibC.free(str6)
}
}
运行结果:
0
-1
1
func endsWith(CString)
public func endsWith(suffix: CString): Bool
功能:判断字符串是否包含指定后缀。
参数:
- suffix: CString - 匹配的目标后缀字符串。
返回值:
- Bool - 如果该字符串包含 suffix 后缀,返回 true,如果该字符串不包含 suffix 后缀,返回 false,特别地,如果原字符串或者 suffix 后缀字符串指针为空,均返回 false。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
var str2: CString = unsafe { LibC.mallocCString("lo") }
var str3: CString = unsafe { LibC.mallocCString("ao") }
println(str1.endsWith(str2))
println(str1.endsWith(str3))
unsafe {
LibC.free(str1)
LibC.free(str2)
LibC.free(str3)
}
}
运行结果:
true
false
func equals(CString)
public func equals(rhs: CString): Bool
功能:判断两个字符串是否相等。
参数:
- rhs: CString - 比较的目标字符串。
返回值:
- Bool - 如果两个字符串相等,返回 true,否则返回 false。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
var str2: CString = unsafe { LibC.mallocCString("hello") }
var str3: CString = unsafe { LibC.mallocCString("Hello") }
println(str1.equals(str2))
println(str1.equals(str3))
unsafe {
LibC.free(str1)
LibC.free(str2)
LibC.free(str3)
}
}
运行结果:
true
false
func equalsLower(CString)
public func equalsLower(rhs: CString): Bool
功能:判断两个字符串是否相等,忽略大小写。
参数:
- rhs: CString - 匹配的目标字符串。
返回值:
- Bool - 如果两个字符串忽略大小写相等,返回 true,否则返回 false。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
var str2: CString = unsafe { LibC.mallocCString("HELLO") }
var str3: CString = unsafe { LibC.mallocCString("Hello") }
println(str1.equalsLower(str2))
println(str1.equalsLower(str3))
unsafe {
LibC.free(str1)
LibC.free(str2)
LibC.free(str3)
}
}
运行结果:
true
true
func getChars()
public func getChars(): CPointer<UInt8>
功能:获取该字符串的指针。
返回值:
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
var ptr: CPointer<UInt8> = unsafe { str1.getChars() }
var c: UInt8 = unsafe { ptr.read() }
println(c) // h的ascii码为104
unsafe{
LibC.free(str1)
}
}
运行结果:
104
func isEmpty()
public func isEmpty(): Bool
功能:判断字符串是否为空字符串。
返回值:
- Bool - 如果为空字符串或字符串指针为空,返回 true,否则返回 false。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
println(str1.isEmpty())
unsafe {
LibC.free(str1)
}
}
运行结果:
false
func isNotEmpty()
public func isNotEmpty(): Bool
功能:判断字符串是否不为空字符串。
返回值:
- Bool - 如果不为空字符串,返回 true,如果字符串指针为空,返回 false。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
println(str1.isNotEmpty())
unsafe {
LibC.free(str1)
}
}
运行结果:
true
func isNull()
public func isNull(): Bool
功能:判断字符串指针是否为空。
返回值:
- Bool - 如果字符串指针为空,返回 true,否则返回 false。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
println(str1.isNull())
unsafe {
LibC.free(str1)
}
}
运行结果:
false
func size()
public func size(): Int64
功能:返回该字符串长度,同 C 语言中的 strlen。
返回值:
- Int64 - 字符串长度。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
println(str1.size())
unsafe {
LibC.free(str1)
}
}
运行结果:
5
func startsWith(CString)
public func startsWith(prefix: CString): Bool
功能:判断字符串是否包含指定前缀。
参数:
- prefix: CString - 匹配的目标前缀字符串。
返回值:
- Bool - 如果该字符串包含 prefix 前缀,返回 true,如果该字符串不包含 prefix 前缀,返回 false,特别地,如果原字符串或者 prefix 前缀字符串指针为空,均返回 false。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
var str2: CString = unsafe { LibC.mallocCString("he") }
println(str1.startsWith(str2))
unsafe {
LibC.free(str1)
LibC.free(str2)
}
}
运行结果:
true
func subCString(UIntNative)
public func subCString(beginIndex: UIntNative): CString
功能:截取指定位置开始至字符串结束的子串。
注意:
- 该接口返回为字符串的副本,返回的子串使用完后需要手动 free。
- 如果 beginIndex 与字符串长度相等,将返回空指针。
参数:
- beginIndex: UIntNative - 截取的起始位置,取值范围为 [0, this.size()]。
返回值:
- CString - 截取的子串。
异常:
- IndexOutOfBoundsException - 如果 beginIndex 大于字符串长度,抛出异常。
- IllegalMemoryException - 如果内存申请失败或内存拷贝失败时,抛出异常。
示例:
main() {
let index: UIntNative = 2
var str1: CString = unsafe { LibC.mallocCString("hello") }
var str2: CString = str1.subCString(index)
println(str2)
unsafe {
LibC.free(str1)
LibC.free(str2)
}
}
运行结果:
llo
func subCString(UIntNative, UIntNative)
public func subCString(beginIndex: UIntNative, subLen: UIntNative): CString
功能:截取字符串的子串,指定起始位置和截取长度。
如果截取的末尾位置超出字符串长度,截取至字符串末尾。
注意:
- 该接口返回为字符串的副本,返回的子串使用完后需要手动 free。
- 如果 beginIndex 等于于字符串长度,或 subLen 等于 0,返回空指针。
参数:
- beginIndex: UIntNative - 截取的起始位置,取值范围为 [0, this.size()]。
- subLen: UIntNative - 截取长度,取值范围为 [0, UIntNative.Max]。
返回值:
- CString - 截取的子串。
异常:
- IndexOutOfBoundsException - 如果 beginIndex 大于字符串长度,抛出异常。
- IllegalMemoryException - 如果内存申请失败或内存拷贝失败时,抛出异常。
示例:
main() {
let index: UIntNative = 2
let len: UIntNative = 2
var str1: CString = unsafe { LibC.mallocCString("hello") }
var str2: CString = str1.subCString(index, len)
println(str2)
unsafe {
LibC.free(str1)
LibC.free(str2)
}
}
运行结果:
ll
func toString()
public func toString(): String
功能:将 CString 类型转为仓颉的 String 类型。
返回值:
- String - 转换后的字符串。
异常:
- IllegalArgumentException - 不合法的 UTF-8 字节序列。
示例:
main() {
var str1: CString = unsafe { LibC.mallocCString("hello") }
println(str1.toString())
unsafe {
LibC.free(str1)
}
}
运行结果:
hello
Float16
功能:表示 16 位浮点数,符合 IEEE 754 中的半精度格式(binary16)。
extend Float16
extend Float16
功能:拓展半精度浮点数以支持一些数学常数。
static prop Inf
public static prop Inf: Float16
功能:获取半精度浮点数的无穷数。
类型:Float16
static prop Max
public static prop Max: Float16
功能:获取半精度浮点数的最大值。
类型:Float16
static prop Min
public static prop Min: Float16
功能:获取半精度浮点数的最小值。
类型:Float16
static prop MinDenormal
public static prop MinDenormal: Float16
功能:获取半精度浮点数的最小次正规数。最小的正的次正规数是以 IEEE 双精度格式表示的最小正数。
类型:Float16
static prop MinNormal
public static prop MinNormal: Float16
功能:获取半精度浮点数的最小正规数。
类型:Float16
static prop NaN
public static prop NaN: Float16
功能:获取半精度浮点数的非数。
类型:Float16
static func max(Float16, Float16, Array<Float16>)
public static func max(a: Float16, b: Float16, others: Array<Float16>): Float16
功能:返回一组Float16中的最大值,此函数的第三个参数是一个变长参数,可以获取二个以上的Float16最大值,如果参数中有 NaN,该函数会返回 NaN。
参数:
返回值:
- Float16 - 返回参数中的最大值。
static func min(Float16, Float16, Array<Float16>)
public static func min(a: Float16, b: Float16, others: Array<Float16>): Float16
功能:返回一组Float16中的最小值,此函数的第三个参数是一个变长参数,可以获取二个以上的Float16最小值,如果参数中有 NaN,该函数会返回 NaN。
参数:
返回值:
- Float16 - 返回参数中的最小值。
func isInf()
public func isInf(): Bool
功能:判断某个浮点数 Float16 是否为无穷数值。
返回值:
func isNaN()
public func isNaN(): Bool
功能:判断某个浮点数 Float16 是否为非数值。
返回值:
func isNormal()
public func isNormal(): Bool
功能:判断某个浮点数 Float16 是否为常规数值。
返回值:
extend Float16 <: Comparable<Float16>
extend Float16 <: Comparable<Float16>
功能:为 Float16 类型扩展 Comparable<Float16> 接口,支持比较操作。
父类型:
func compare(Float16)
public func compare(rhs: Float16): Ordering
功能:判断当前 Float16 值与指定 Float16 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: Float16 = 0.12
var num2: Float16 = 0.234
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend Float16
extend Float16
功能:支持与 UInt16 互相转换。
static func fromBits(UInt16)
public static func fromBits(bits: UInt16): Float16
功能:将指定的 UInt16 数转换为 Float16 数。
参数:
- bits: UInt16 - 要转换的数字。
返回值:
- Float16 - 转换结果,其位与参数 bits 值相同。
示例:
main() {
let v = Float16.fromBits(0x4A40)
println(v)
}
运行结果:
12.500000
func toBits()
public func toBits(): UInt16
功能:将指定的 Float16 数转换为以位表示的对应 UInt16 数。
返回值:
示例:
main() {
println(12.5f16.toBits()) // 0x4A40 19008
}
运行结果:
19008
extend Float16 <: Hashable
extend Float16 <: Hashable
功能:为 Float16 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend Float16 <: ToString
extend Float16 <: ToString
功能:为 Float16 类型其扩展 ToString 接口,实现向 String 类型的转换。默认保留 6 位小数。
父类型:
func toString()
public func toString(): String
功能:将 Float16 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
Float32
功能:表示 32 位浮点数,符合 IEEE 754 中的单精度格式(binary32)。
extend Float32
extend Float32
功能:拓展单精度浮点数以支持一些数学常数。
static prop Inf
public static prop Inf: Float32
功能:获取单精度浮点数的无穷数。
类型:Float32
static prop Max
public static prop Max: Float32
功能:获取单精度浮点数的最大值。
类型:Float32
static prop Min
public static prop Min: Float32
功能:获取单精度浮点数的最小值。
类型:Float32
static prop MinDenormal
public static prop MinDenormal: Float32
功能:获取单精度浮点数的最小次正规数。
类型:Float32
static prop MinNormal
public static prop MinNormal: Float32
功能:获取单精度浮点数的最小正规数。
类型:Float32
static prop NaN
public static prop NaN: Float32
功能:获取单精度浮点数的非数。
类型:Float32
static func max(Float32, Float32, Array<Float32>)
public static func max(a: Float32, b: Float32, others: Array<Float32>): Float32
功能:返回一组Float32中的最大值,此函数的第三个参数是一个变长参数,可以获取二个以上的Float32最大值,如果参数中有 NaN,该函数会返回 NaN。
参数:
返回值:
- Float32 - 返回参数中的最大值。
static func min(Float32, Float32, Array<Float32>)
public static func min(a: Float32, b: Float32, others: Array<Float32>): Float32
功能:返回一组Float32中的最小值,此函数的第三个参数是一个变长参数,可以获取二个以上的Float32最小值,如果参数中有 NaN,该函数会返回 NaN。
参数:
返回值:
- Float32 - 返回参数中的最小值。
func isInf()
public func isInf(): Bool
功能:判断某个浮点数 Float32 是否为无穷数值。
返回值:
func isNaN()
public func isNaN(): Bool
功能:判断某个浮点数 Float32 是否为非数值。
返回值:
func isNormal()
public func isNormal(): Bool
功能:判断某个浮点数 Float32 是否为常规数值。
返回值:
extend Float32 <: Comparable<Float32>
extend Float32 <: Comparable<Float32>
功能:为 Float32 类型扩展 Comparable<Float32> 接口,支持比较操作。
父类型:
func compare(Float32)
public func compare(rhs: Float32): Ordering
功能:判断当前 Float32 值与指定 Float32 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: Float32 = 0.12
var num2: Float32 = 0.234
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend Float32
extend Float32
功能:支持与 UInt32 互相转换。
static func fromBits(UInt32)
public static func fromBits(bits: UInt32): Float32
功能:将指定的 UInt32 类型转换为 Float32 类型。
参数:
- bits: UInt32 - 要转换的数字。
返回值:
- Float32 - 转换结果,其位与参数 bits 值相同。
示例:
main() {
let v = Float16.fromBits(0x4A40u16)
println(v)
}
运行结果:
12.500000
func toBits()
public func toBits(): UInt32
功能:将指定的 Float32 数转换为以位表示的对应 UInt32 数。
返回值:
示例:
main() {
println(13.88f32.toBits()) // 0x415E147B 1096684667
}
运行结果:
1096684667
extend Float32 <: Hashable
extend Float32 <: Hashable
功能:为 Float32 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend Float32 <: ToString
extend Float32 <: ToString
功能:为 Float32 类型其扩展 ToString 接口,实现向 String 类型的转换。默认保留 6 位小数。
父类型:
func toString()
public func toString(): String
功能:将 Float32 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
Float64
功能:表示 64 位浮点数,符合 IEEE 754 中的双精度格式(binary64)。
extend Float64
extend Float64
功能:拓展双精度浮点数以支持一些数学常数。
static prop Inf
public static prop Inf: Float64
功能:获取双精度浮点数的无穷数。
类型:Float64
static prop Max
public static prop Max: Float64
功能:获取双精度浮点数的最大值。
类型:Float64
static prop Min
public static prop Min: Float64
功能:获取双精度浮点数的最小值。
类型:Float64
static prop MinDenormal
public static prop MinDenormal: Float64
功能:获取双精度浮点数的最小次正规数。
类型:Float64
static prop MinNormal
public static prop MinNormal: Float64
功能:获取双精度浮点数的最小正规数。
类型:Float64
static prop NaN
public static prop NaN: Float64
功能:获取双精度浮点数的非数。
类型:Float64
static func max(Float64, Float64, Array<Float64>)
public static func max(a: Float64, b: Float64, others: Array<Float64>): Float64
功能:返回一组Float64中的最大值,此函数的第三个参数是一个变长参数,可以获取二个以上的Float64最大值,如果参数中有 NaN,该函数会返回 NaN。
参数:
返回值:
- Float64 - 返回参数中的最大值。
static func min(Float64, Float64, Array<Float64>)
public static func min(a: Float64, b: Float64, others: Array<Float64>): Float64
功能:返回一组Float64中的最小值,此函数的第三个参数是一个变长参数,可以获取二个以上的Float64最小值,如果参数中有 NaN,该函数会返回 NaN。
参数:
返回值:
- Float64 - 返回参数中的最小值。
func isInf()
public func isInf(): Bool
功能:判断某个浮点数 Float64 是否为无穷数值。
返回值:
func isNaN()
public func isNaN(): Bool
功能:判断某个浮点数 Float64 是否为非数值。
返回值:
func isNormal()
public func isNormal(): Bool
功能:判断某个浮点数 Float64 是否为常规数值。
返回值:
extend Float64 <: Comparable<Float64>
extend Float64 <: Comparable<Float64>
功能:为 Float64 类型扩展 Comparable<Float64> 接口,支持比较操作。
父类型:
func compare(Float64)
public func compare(rhs: Float64): Ordering
功能:判断当前 Float64 值与指定 Float64 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: Float64 = 0.12
var num2: Float64 = 0.234
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend Float64
extend Float64
功能:支持与 UInt64 互相转换。
static func fromBits(UInt64)
public static func fromBits(bits: UInt64): Float64
功能:将指定的 UInt64 数转换为 Float64 数。
参数:
- bits: UInt64 - 要转换的数字。
返回值:
- Float64 - 转换结果,其位与参数 bits 值相同。
示例:
main() {
let v = Float64.fromBits(0x402BC28F5C28F5C3)
println(v)
}
运行结果:
13.880000
func toBits()
public func toBits(): UInt64
功能:将指定的 Float64 数转换为以位表示的对应 UInt64 数。
返回值:
示例:
main() {
println(13.88f64.toBits()) // 0x402BC28F5C28F5C3 4624003363408246211
}
运行结果:
4624003363408246211
extend Float64 <: Hashable
extend Float64 <: Hashable
功能:为 Float64 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend Float64 <: ToString
extend Float64 <: ToString
功能:为 Float64 类型其扩展 ToString 接口,实现向 String 类型的转换。默认保留 6 位小数。
父类型:
func toString()
public func toString(): String
功能:将 Float64 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
Int16
功能:表示 16 位有符号整型,表示范围为 [-2^{15}, 2^{15} - 1]。
extend Int16
extend Int16
功能:拓展 16 位有符号整数以支持一些数学常数。
static prop Max
public static prop Max: Int16
功能:获取 16 位有符号整数的最大值。
类型:Int16
static prop Min
public static prop Min: Int16
功能:获取 16 位有符号整数的最小值。
类型:Int16
extend Int16 <: Comparable<Int16>
extend Int16 <: Comparable<Int16>
功能:为 Int16 类型扩展 Comparable<Int16> 接口,支持比较操作。
父类型:
func compare(Int16)
public func compare(rhs: Int16): Ordering
功能:判断当前 Int16 值与指定 Int16 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: Int16 = 2
var num2: Int16 = 3
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend Int16 <: Countable<Int16>
extend Int16 <: Countable<Int16>
功能:为 Int16 类型扩展 Countable<Int16> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): Int16
功能:获取在数轴上当前 Int16 位置往右移动 right 后对应位置的 Int16 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num1: Int16 = 32767
var num2: Int16 = 3
println(num1.next(5))
println(num2.next(10))
}
运行结果:
-32764
13
func position()
public func position(): Int64
功能:获取当前 Int16 值的位置信息,即将该 Int16 转换为 Int64 值。
返回值:
示例:
main() {
var num1: Int16 = 32767
var num2: Int16 = 3
println(num1.position())
println(num2.position())
}
运行结果:
32767
3
extend Int16 <: Hashable
extend Int16 <: Hashable
功能:为 Int16 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend Int16 <: ToString
extend Int16 <: ToString
功能:这里为 Int16 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 Int16 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
Int32
功能:表示 32 位有符号整型,表示范围为 [-2^{31}, 2^{31} - 1]。
extend Int32
extend Int32
功能:拓展 32 位有符号整数以支持一些数学常数。
static prop Max
public static prop Max: Int32
功能:获取 32 位有符号整数的最大值。
类型:Int32
static prop Min
public static prop Min: Int32
功能:获取 32 位有符号整数的最小值。
类型:Int32
extend Int32 <: Comparable<Int32>
extend Int32 <: Comparable<Int32>
功能:为 Int32 类型扩展 Comparable<Int32> 接口,支持比较操作。
父类型:
func compare(Int32)
public func compare(rhs: Int32): Ordering
功能:判断当前 Int32 值与指定 Int32 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: Int32 = 8
var num2: Int32 = 10
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend Int32 <: Countable<Int32>
extend Int32 <: Countable<Int32>
功能:为 Int32 类型扩展 Countable<Int32> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): Int32
功能:获取在数轴上当前 Int32 位置往右移动 right 后对应位置的 Int32 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num: Int32 = 3
println(num.next(10))
}
运行结果:
13
func position()
public func position(): Int64
功能:获取当前 Int32 值的位置信息,即将该 Int32 转换为 Int64 值。
返回值:
示例:
main() {
var num: Int32 = 3
println(num.position())
}
运行结果:
3
extend Int32 <: Hashable
extend Int32 <: Hashable
功能:为 Int32 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend Int32 <: ToString
extend Int32 <: ToString
功能:这里为 Int32 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 Int32 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
Int64
功能:表示 64 位有符号整型,表示范围为 [-2^{63}, 2^{63} - 1]。
extend Int64
extend Int64
功能:拓展 64 位有符号整数以支持一些数学常数。
static prop Max
public static prop Max: Int64
功能:获取 64 位有符号整数的最大值。
类型:Int64
static prop Min
public static prop Min: Int64
功能:获取 64 位有符号整数的最小值。
类型:Int64
extend Int64 <: Comparable<Int64>
extend Int64 <: Comparable<Int64>
功能:为 Int64 类型扩展 Comparable<Int64> 接口,支持比较操作。
父类型:
func compare(Int64)
public func compare(rhs: Int64): Ordering
功能:判断当前 Int64 值与指定 Int64 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: Int64 = 2
var num2: Int64 = 3
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend Int64 <: Countable<Int64>
extend Int64 <: Countable<Int64>
功能:为 Int64 类型扩展 Countable<Int64> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): Int64
功能:获取在数轴上当前 Int64 位置往右移动 right 后对应位置的 Int64 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num: Int64 = 3
println(num.next(10))
}
运行结果:
13
func position()
public func position(): Int64
功能:获取当前 Int64 值的位置信息,即返回该 Int64 值本身。
返回值:
示例:
main() {
var num: Int64 = 3
println(num.position())
}
运行结果:
3
extend Int64 <: Hashable
extend Int64 <: Hashable
功能:为 Int64 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend Int64 <: ToString
extend Int64 <: ToString
功能:这里为 Int64 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 Int64 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
Int8
功能:表示 8 位有符号整型,表示范围为 [-2^7, 2^7 - 1]。
extend Int8
extend Int8
功能:拓展 8 位有符号整数以支持一些数学常数。
static prop Max
public static prop Max: Int8
功能:获取 8 位有符号整数的最大值。
类型:Int8
static prop Min
public static prop Min: Int8
功能:获取 8 位有符号整数的最小值。
类型:Int8
extend Int8 <: Comparable<Int8>
extend Int8 <: Comparable<Int8>
功能:为 Int8 类型扩展 Comparable<Int8> 接口,支持比较操作。
父类型:
func compare(Int8)
public func compare(rhs: Int8): Ordering
功能:判断当前 Int8 值与指定 Int8 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: Int8 = 2
var num2: Int8 = 3
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend Int8 <: Countable<Int8>
extend Int8 <: Countable<Int8>
功能:为 Int8 类型扩展 Countable<Int8> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): Int8
功能:获取在数轴上当前 Int8 位置往右移动 right 后对应位置的 Int8 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num: Int8 = 3
println(num.next(5))
}
运行结果:
8
func position()
public func position(): Int64
功能:获取当前 Int8 值的位置信息,即将该 Int8 转换为 Int64 值。
返回值:
示例:
main() {
var num: Int8 = 3
println(num.position())
}
运行结果:
3
extend Int8 <: Hashable
extend Int8 <: Hashable
功能:为 Int8 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend Int8 <: ToString
extend Int8 <: ToString
功能:这里为 Int8 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 Int8 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
IntNative
功能:表示平台相关的有符号整型,其长度与当前系统的位宽一致。
extend IntNative
extend IntNative
功能:拓展平台相关有符号整数以支持一些数学常数。
static prop Max
public static prop Max: IntNative
功能:获取平台相关有符号整数的最大值。
类型:IntNative
static prop Min
public static prop Min: IntNative
功能:获取平台相关有符号整数的最小值。
类型:IntNative
extend IntNative <: Comparable<IntNative>
extend IntNative <: Comparable<IntNative>
功能:为 IntNative 类型扩展 Comparable<IntNative> 接口,支持比较操作。
父类型:
func compare(IntNative)
public func compare(rhs: IntNative): Ordering
功能:判断当前 IntNative 值与指定 IntNative 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: IntNative = 8
var num2: IntNative = 10
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend IntNative <: Countable<IntNative>
extend IntNative <: Countable<IntNative>
功能:为 IntNative 类型扩展 Countable<IntNative> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): IntNative
功能:获取在数轴上当前 IntNative 位置往右移动 right 后对应位置的 IntNative 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num: IntNative = 8
println(num.next(4))
}
运行结果:
12
func position()
public func position(): Int64
功能:获取当前 IntNative 值的位置信息,即将该 IntNative 转换为 Int64 值。
返回值:
示例:
main() {
var num: IntNative = 8
println(num.position())
}
运行结果:
8
extend IntNative <: Hashable
extend IntNative <: Hashable
功能:为 IntNative 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend IntNative <: ToString
extend IntNative <: ToString
功能:这里为 IntNative 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 IntNative 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
Rune
功能:表示 unicode 字符集中的字符。
表示范围为 Unicode scalar value,即从 \u{0000} 到 \u{D7FF},以及从 \u{E000} 到 \u{10FFF} 的字符。
extend Rune
extend Rune
功能:为 Rune 类型实现一系列扩展方法,主要为在 Ascii 字符集范围内的一些字符判断、转换等操作。
static func fromUtf8(Array<UInt8>, Int64)
public static func fromUtf8(arr: Array<UInt8>, index: Int64): (Rune, Int64)
功能:将字节数组中的指定元素,根据 UTF-8 编码规则转换成字符,并告知字符占用字节长度。
参数:
返回值:
异常:
- IllegalArgumentException - 不合法的 UTF-8 字节序列。
示例:
main() {
var arr: Array<UInt8> = [4u8, 8u8, 65u8] // A <=> 65
var tuple = Rune.fromUtf8(arr, 2)
println(tuple[0]) // Rune
println(tuple[1]) // len
}
运行结果:
A
1
static func getPreviousFromUtf8(Array<UInt8>, Int64)
public static func getPreviousFromUtf8(arr: Array<UInt8>, index: Int64): (Rune, Int64)
功能:获取字节数组中指定索引对应的字节所在的 UTF-8 编码字符,同时返回该字符首位字节码在数组中的索引。
当指定了一个索引,那么函数会找到数组对应索引位置并且根据 UTF-8 规则,查看该字节码是否是字符的首位字节码,如果不是就继续向前遍历,直到该字节码是首位字节码,然后利用字节码序列找到对应的字符。
参数:
返回值:
异常:
- IllegalArgumentException - 如果找不到对应首位字节码,即指定字节所在位置的字节不符合 UTF-8 编码,抛出异常。
static func intoUtf8Array(Rune, Array<UInt8>, Int64)
public static func intoUtf8Array(c: Rune, arr: Array<UInt8>, index: Int64): Int64
功能:该函数会把字符转成字节码序列然后覆盖 Array 数组内指定位置的字节码。
参数:
返回值:
- Int64 - 字符的字节码长度,例如中文是三个字节码长度。
示例:
main() {
var arr: Array<UInt8> = [ 1u8, 2u8, 3u8, 230u8, 136u8, 145u8]
var len: Int64 = Rune.intoUtf8Array(r'爱', arr, 2)
println(len)
println(arr[2]) // 字符爱的utf-8编码的第一个字节
}
运行结果:
3
231
static func utf8Size(Array<UInt8>, Int64)
public static func utf8Size(arr: Array<UInt8>, index: Int64): Int64
功能:该函数会返回字节数组指定索引位置为起始的字符占用的字节数。
在 UTF-8 编码中,ASCII 码首位字节第一位不为 1,其他长度的字符首位字节开头 1 的个数表明了该字符对应的字节码长度,该函数通过扫描首位,判断字节码长度。如果索引对应的不是首位字节码,就会抛出异常。
参数:
返回值:
- Int64 - 字符的字节码长度,例如中文是三个字节码长度。
异常:
- IllegalArgumentException - 如果索引位置的字节码不符合首位字节码规则,会抛出异常。
示例:
main() {
var arr: Array<UInt8> = [ 1u8, 2u8, 231u8, 136u8, 177u8, 145u8]
var len: Int64 = Rune.utf8Size(arr, 2)
println(len) // 索引为2-4的数组元素为中文字符爱的utf-8编码,占用三字节
}
运行结果:
3
static func utf8Size(Rune)
public static func utf8Size(c: Rune): Int64
功能:返回字符对应的 UTF-8 编码的字节码长度,例如中文字符的字节码长度是 3。
参数:
- c: Rune - 待计算 UTF-8 字节码长度的字符。
返回值:
- Int64 - 字符的 UTF-8 字节码长度。
示例:
main() {
var char: Rune = r'爱'
var len: Int64 = Rune.utf8Size(char)
println(len) // 中文字符爱的utf-8编码,占用三字节
}
运行结果:
3
func isAscii()
public func isAscii(): Bool
功能:判断字符是否是 Ascii 中的字符。
返回值:
- Bool - 如果是 Ascii 字符返回 true,否则返回 false。
func isAsciiControl()
public func isAsciiControl(): Bool
功能:判断字符是否是 Ascii 控制字符。其取值范围为 [00, 1F] 和 {7F} 的并集。
返回值:
- Bool - 如果是 Ascii 控制字符返回 true,否则返回 false。
func isAsciiGraphic()
public func isAsciiGraphic(): Bool
功能:判断字符是否是 Ascii 图形字符。其取值范围为 [21, 7E]。
返回值:
- Bool - 如果是 Ascii 图形字符返回 true,否则返回 false。
func isAsciiHex()
public func isAsciiHex(): Bool
功能:判断字符是否是 Ascii 十六进制字符。
返回值:
- Bool - 如果是 Ascii 十六进制字符返回 true,否则返回 false。
func isAsciiLetter()
public func isAsciiLetter(): Bool
功能:判断字符是否是 Ascii 字母字符。
返回值:
- Bool - 如果是 Ascii 字母字符返回 true,否则返回 false。
func isAsciiLowerCase()
public func isAsciiLowerCase(): Bool
功能:判断字符是否是 Ascii 小写字符。
返回值:
- Bool - 如果是 Ascii 小写字符返回 true,否则返回 false。
func isAsciiNumber()
public func isAsciiNumber(): Bool
功能:判断字符是否是 Ascii 数字字符。
返回值:
- Bool - 如果是 Ascii 数字字符返回 true,否则返回 false。
func isAsciiNumberOrLetter()
public func isAsciiNumberOrLetter(): Bool
功能:判断字符是否是 Ascii 数字或拉丁字母字符。
返回值:
- Bool - 如果是 Ascii 数字或拉丁字母字符返回 true,否则返回 false。
func isAsciiOct()
public func isAsciiOct(): Bool
功能:判断字符是否是 Ascii 八进制字符。
返回值:
- Bool - 如果是 Ascii 八进制字符返回 true,否则返回 false。
func isAsciiPunctuation()
public func isAsciiPunctuation(): Bool
功能:判断字符是否是 Ascii 标点符号字符。其取值范围为 [21, 2F]、[3A, 40]、[5B, 60] 和 [7B, 7E] 的并集。
返回值:
- Bool - 如果是 Ascii 标点符号字符返回 true,否则返回 false。
func isAsciiUpperCase()
public func isAsciiUpperCase(): Bool
功能:判断字符是否是 Ascii 大写字符。
返回值:
- Bool - 如果是 Ascii 大写字符返回 true,否则返回 false。
func isAsciiWhiteSpace()
public func isAsciiWhiteSpace(): Bool
功能:判断字符是否是 Ascii 空白字符。其取值范围为 [09, 0D] 和 {20} 的并集。
返回值:
- Bool - 如果是 Ascii 空白字符返回 true,否则返回 false。
func toAsciiLowerCase()
public func toAsciiLowerCase(): Rune
功能:将字符转换为 Ascii 小写字符,如果无法转换则保持现状。
返回值:
func toAsciiUpperCase()
public func toAsciiUpperCase(): Rune
功能:将字符转换为 Ascii 大写字符,如果无法转换则保持现状。
返回值:
extend Rune <: Comparable<Rune>
extend Rune <: Comparable<Rune>
功能:为 Rune 类型扩展 Comparable<Rune> 接口,支持比较操作。
父类型:
func compare(Rune)
public func compare(rhs: Rune): Ordering
功能:判断当前 Rune 实例与指定 Rune 实例的大小关系。
Rune 的大小关系指的是它们对应的 unicode 码点的大小关系。
参数:
返回值:
示例:
main() {
var char1: Rune = r'i'
var char2: Rune = r'j'
println(char1.compare(char2))
}
运行结果:
Ordering.LT
extend Rune <: Countable<Rune>
extend Rune <: Countable<Rune>
功能:为 Rune 类型扩展 Countable<Rune> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): Rune
功能:获取当前 Rune 值往右数 right 后所到位置的 Rune 值。
参数:
- right: Int64 - 往右数的个数。
返回值:
异常:
- OverflowException - 如果与 Int64 数进行加法运算后为不合法的 Unicode 值,抛出异常。
func position()
public func position(): Int64
功能:获取当前 Rune 值的位置信息,即将该 Rune 转换为 Int64 值。
返回值:
extend Rune <: Hashable
extend Rune <: Hashable
功能:为 Rune 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend Rune <: ToString
extend Rune <: ToString
功能:这里为 Rune 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 Rune 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
UInt16
功能:表示 16 位无符号整型,表示范围为 [0, 2^{16} - 1]。
extend UInt16
extend UInt16
功能:拓展 16 位无符号整数以支持一些数学常数。
static prop Max
public static prop Max: UInt16
功能:获取 16 位无符号整数的最大值。
类型:UInt16
static prop Min
public static prop Min: UInt16
功能:获取 16 位无符号整数的最小值。
类型:UInt16
extend UInt16 <: Comparable<UInt16>
extend UInt16 <: Comparable<UInt16>
功能:为 UInt16 类型扩展 Comparable<UInt16> 接口,支持比较操作。
父类型:
func compare(UInt16)
public func compare(rhs: UInt16): Ordering
功能:判断当前 UInt16 值与指定 UInt16 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: UInt16 = 2
var num2: UInt16 = 3
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend UInt16 <: Countable<UInt16>
extend UInt16 <: Countable<UInt16>
功能:为 UInt16 类型扩展 Countable<UInt16> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): UInt16
功能:获取在数轴上当前 UInt16 位置往右移动 right 后对应位置的 UInt16 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num: UInt16 = 3
println(num.next(10))
}
运行结果:
13
func position()
public func position(): Int64
功能:获取当前 UInt16 值的位置信息,即将该 UInt16 转换为 Int64 值。
返回值:
示例:
main() {
var num: UInt16 = 8
println(num.position())
}
运行结果:
8
extend UInt16 <: Hashable
extend UInt16 <: Hashable
功能:为 UInt16 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend UInt16 <: ToString
extend UInt16 <: ToString
功能:这里为 UInt16 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 UInt16 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
UInt32
功能:表示 32 位无符号整型,表示范围为 [0, 2^{32} - 1]。
extend UInt32
extend UInt32
功能:拓展 32 位无符号整数以支持一些数学常数。
static prop Max
public static prop Max: UInt32
功能:获取 32 位无符号整数的最大值。
类型:UInt32
static prop Min
public static prop Min: UInt32
功能:获取 32 位无符号整数的最小值。
类型:UInt32
extend UInt32 <: Comparable<UInt32>
extend UInt32 <: Comparable<UInt32>
功能:为 UInt32 类型扩展 Comparable<UInt32> 接口,支持比较操作。
父类型:
func compare(UInt32)
public func compare(rhs: UInt32): Ordering
功能:判断当前 UInt32 值与指定 UInt32 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: UInt32 = 2
var num2: UInt32 = 3
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend UInt32 <: Countable<UInt32>
extend UInt32 <: Countable<UInt32>
功能:为 UInt32 类型扩展 Countable<UInt32> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): UInt32
功能:获取在数轴上当前 UInt32 位置往右移动 right 后对应位置的 UInt32 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num: UInt32 = 3
println(num.next(10))
}
运行结果:
13
func position()
public func position(): Int64
功能:获取当前 UInt32 值的位置信息,即将该 UInt32 转换为 UInt64 值。
返回值:
示例:
main() {
var num: UInt32 = 8
println(num.position())
}
运行结果:
8
extend UInt32 <: Hashable
extend UInt32 <: Hashable
功能:为 UInt32 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend UInt32 <: ToString
extend UInt32 <: ToString
功能:这里为 UInt32 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 UInt32 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
UInt64
功能:表示 64 位无符号整型,表示范围为 [0, 2^{64} - 1]。
extend UInt64
extend UInt64
功能:拓展 64 位无符号整数以支持一些数学常数。
static prop Max
public static prop Max: UInt64
功能:获取 64 位无符号整数的最大值。
类型:UInt64
static prop Min
public static prop Min: UInt64
功能:获取 64 位无符号整数的最小值。
类型:UInt64
extend UInt64 <: Comparable<UInt64>
extend UInt64 <: Comparable<UInt64>
功能:为 UInt64 类型扩展 Comparable<UInt64> 接口,支持比较操作。
父类型:
func compare(UInt64)
public func compare(rhs: UInt64): Ordering
功能:判断当前 UInt64 值与指定 UInt64 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: UInt64 = 2
var num2: UInt64 = 3
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend UInt64 <: Countable<UInt64>
extend UInt64 <: Countable<UInt64>
功能:为 UInt64 类型扩展 Countable<UInt64> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): UInt64
功能:获取在数轴上当前 UInt64 位置往右移动 right 后对应位置的 UInt64 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num: UInt64 = 3
println(num.next(10))
}
运行结果:
13
func position()
public func position(): Int64
功能:获取当前 UInt64 值的位置信息,即将该 UInt64 转换为 Int64 值。
返回值:
示例:
main() {
var num: UInt64 = 8
println(num.position())
}
运行结果:
8
extend UInt64 <: Hashable
extend UInt64 <: Hashable
功能:为 UInt64 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend UInt64 <: ToString
extend UInt64 <: ToString
功能:这里为 UInt64 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 UInt64 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
UInt8
功能:表示 8 位无符号整型,表示范围为 [0, 2^8 - 1]。
extend UInt8
extend UInt8
功能:拓展 8 位无符号整数以支持一些数学常数。
static prop Max
public static prop Max: UInt8
功能:获取 8 位无符号整数的最大值。
类型:UInt8
static prop Min
public static prop Min: UInt8
功能:获取 8 位无符号整数的最小值。
类型:UInt8
extend UInt8 <: Comparable<UInt8>
extend UInt8 <: Comparable<UInt8>
功能:为 UInt8 类型扩展 Comparable<UInt8> 接口,支持比较操作。
父类型:
func compare(UInt8)
public func compare(rhs: UInt8): Ordering
功能:判断当前 UInt8 值与指定 UInt8 值的大小关系。
参数:
返回值:
示例:
main() {
var num1: UInt8 = 2
var num2: UInt8 = 3
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend UInt8 <: Countable<UInt8>
extend UInt8 <: Countable<UInt8>
功能:为 UInt8 类型扩展 Countable<UInt8> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): UInt8
功能:获取在数轴上当前 UInt8 位置往右移动 right 后对应位置的 UInt8 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
示例:
main() {
var num: UInt8 = 3
println(num.next(10))
}
运行结果:
13
func position()
public func position(): Int64
功能:获取当前 UInt8 值的位置信息,即将该 UInt8 转换为 Int64 值。
返回值:
示例:
main() {
var num: UInt8 = 8
println(num.position())
}
运行结果:
8
extend UInt8 <: Hashable
extend UInt8 <: Hashable
功能:为 UInt8 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend UInt8 <: ToString
extend UInt8 <: ToString
功能:这里为 UInt8 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 UInt8 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
UIntNative
功能:表示平台相关的无符号整型,其长度与当前系统的位宽一致。
extend UIntNative
extend UIntNative
功能:拓展平台相关无符号整数以支持一些数学常数。
static prop Max
public static prop Max: UIntNative
功能:获取平台相关无符号整数的最大值。
类型:UIntNative
static prop Min
public static prop Min: UIntNative
功能:获取平台相关无符号整数的最小值。
类型:UIntNative
extend UIntNative <: Comparable<UIntNative>
extend UIntNative <: Comparable<UIntNative>
功能:为 UIntNative 类型扩展 Comparable<UIntNative> 接口,支持比较操作。
父类型:
func compare(UIntNative)
public func compare(rhs: UIntNative): Ordering
功能:判断当前 UIntNative 值与指定 UIntNative 值的大小关系。
参数:
- rhs: UIntNative - 待比较的另一个 UIntNative 值。
返回值:
示例:
main() {
var num1: UIntNative = 2
var num2: UIntNative = 3
println(num1.compare(num2))
}
运行结果:
Ordering.LT
extend UIntNative <: Countable
extend UIntNative <: Countable<UIntNative>
功能:为 UIntNative 类型扩展 Countable<UIntNative> 接口,支持计数操作。
父类型:
func next(Int64)
public func next(right: Int64): UIntNative
功能:获取在数轴上当前 UIntNative 位置往右移动 right 后对应位置的 UIntNative 值。如果值溢出,则会从数轴最左边继续移动。
参数:
- right: Int64 - 往右数的个数。
返回值:
- UIntNative - 往右数
right后所到位置的 UIntNative 值。
示例:
main() {
var num: UIntNative = 3
println(num.next(10))
}
运行结果:
13
func position()
public func position(): Int64
功能:获取当前 UIntNative 值的位置信息,即将该 UIntNative 转换为 Int64 值。
返回值:
- Int64 - 当前 UIntNative 值的位置信息。
示例:
main() {
var num: UIntNative = 8
println(num.position())
}
运行结果:
8
extend UIntNative <: Hashable
extend UIntNative <: Hashable
功能:为 UIntNative 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend UIntNative <: ToString
extend UIntNative <: ToString
功能:这里为 UIntNative 类型扩展 ToString 接口,实现向 String 类型的转换。
父类型:
func toString()
public func toString(): String
功能:将 UIntNative 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
Unit
功能:表示仓颉语言中只关心副作用而不关心值的表达式的类型。
例如,print 函数、赋值表达式、复合赋值表达式、自增和自减表达式、循环表达式,它们的类型都是 Unit。
Unit 类型只有一个值,也是它的字面量:()。除了赋值、判等和判不等外,Unit 类型不支持其他操作。
extend Unit <: Equatable<Unit>
extend Unit <: Equatable<Unit>
功能:为 Unit 类型扩展 Equatable<Unit> 接口。
父类型:
extend Unit <: Hashable
extend Unit <: Hashable
功能:为 Unit 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值,Unit 的哈希值为 0。
返回值:
- Int64 - 哈希值。
extend Unit <: ToString
extend Unit <: ToString
功能:为 Unit 类型其扩展 ToString 接口,实现向 String 类型的转换。
Unit 的字符串表示是 "()"。
父类型:
func toString()
public func toString(): String
功能:将 Unit 值转换为可输出的字符串。
返回值:
- String - 转化后的字符串。
接口
interface Any
public interface Any
功能:Any 是所有类型的父类型,所有 interface 都默认继承它,所有非 interface 类型都默认实现它。
extend Byte
extend Byte
功能:为 Byte 类型实现一系列扩展方法,主要为在 Ascii 字符集范围内的一些字符判断、转换等操作。
func isAscii()
public func isAscii(): Bool
功能:判断 Byte 是否是在 Ascii 范围内。
返回值:
func isAsciiControl()
public func isAsciiControl(): Bool
功能:判断 Byte 是否是在 Ascii 控制字符范围内。其取值范围为 [00, 1F] 和 {7F} 的并集。
返回值:
func isAsciiGraphic()
public func isAsciiGraphic(): Bool
功能:判断 Byte 是否是在 Ascii 图形字符范围内。其取值范围为 [21, 7E]。
返回值:
func isAsciiHex()
public func isAsciiHex(): Bool
功能:判断 Byte 是否是在 Ascii 十六进制数字范围内。
返回值:
func isAsciiLetter()
public func isAsciiLetter(): Bool
功能:判断 Byte 是否是在 Ascii 拉丁字母范围内。
返回值:
func isAsciiLowerCase()
public func isAsciiLowerCase(): Bool
功能:判断 Byte 是否是在 Ascii 小写拉丁字母范围内。
返回值:
func isAsciiNumber()
public func isAsciiNumber(): Bool
功能:判断 Byte 是否是在 Ascii 十进制数字范围内。
返回值:
func isAsciiNumberOrLetter()
public func isAsciiNumberOrLetter(): Bool
功能:判断 Byte 是否是在 Ascii 十进制数字和拉丁字母范围内。
返回值:
func isAsciiOct()
public func isAsciiOct(): Bool
功能:判断 Byte 是否是在 Ascii 八进制数字范围内。
返回值:
func isAsciiPunctuation()
public func isAsciiPunctuation(): Bool
功能:判断 Byte 是否是在 Ascii 标点符号范围内。其取值范围为 [21, 2F]、[3A, 40]、[5B, 60] 和 [7B, 7E] 的并集。
返回值:
func isAsciiUpperCase()
public func isAsciiUpperCase(): Bool
功能:判断 Byte 是否是在 Ascii 大写拉丁字母范围内。
返回值:
func isAsciiWhiteSpace()
public func isAsciiWhiteSpace(): Bool
功能:判断 Byte 是否是在 Ascii 空白字符范围内。其取值范围为 [09, 0D] 和 {20} 的并集。
返回值:
func toAsciiLowerCase()
public func toAsciiLowerCase(): Byte
功能:将 Byte 换为对应的 Ascii 小写字符 Byte,如果无法转换则保持现状。
返回值:
func toAsciiUpperCase()
public func toAsciiUpperCase(): Byte
功能:将 Byte 换为对应的 Ascii 大写字符 Byte,如果无法转换则保持现状。
返回值:
interface CType
sealed interface CType
功能:表示支持与 C 语言互操作的接口。
CType 接口是一个语言内置的空接口,它是 CType 约束的具体实现,所有 C 互操作支持的类型都隐式地实现了该接口,因此所有 C 互操作支持的类型都可以作为 CType 类型的子类型使用。
注意:
示例:
@C
struct Data {}
@C
func foo() {}
main() {
var c: CType = Data() // ok
c = 0 // ok
c = true // ok
c = CString(CPointer<UInt8>()) // ok
c = CPointer<Int8>() // ok
c = foo // ok
}
interface Collection<T>
public interface Collection<T> <: Iterable<T> {
prop size: Int64
func isEmpty(): Bool
func toArray(): Array<T>
}
功能:该接口用来表示集合,通常容器类型应该实现该接口。
父类型:
- Iterable<T>
prop size
prop size: Int64
功能:获取当前集合的大小,即集合中元素的个数。
类型:Int64
func isEmpty()
func isEmpty(): Bool
功能:判断当前集合是否为空。
返回值:
- Bool - 如果为空返回 true,否则返回 false。
func toArray()
func toArray(): Array<T>
功能:将当前集合转为数组类型。
返回值:
- Array<T> - 转换得到的数组。
interface Comparable<T>
public interface Comparable<T> <: Equatable<T> & Less<T> & Greater<T> & LessOrEqual<T> & GreaterOrEqual<T> {
func compare(that: T): Ordering
operator func <(rhs: T): Bool
operator func <=(rhs: T): Bool
operator func ==(rhs: T): Bool
operator func >(rhs: T): Bool
operator func >=(rhs: T): Bool
}
功能:该接口表示比较运算,是等于、不等于、小于、大于、小于等于、大于等于接口的集合体。
该接口中提供运算符 ==、!=、<、<=、>、>= 重载的默认实现,默认实现根据 compare 函数的返回值来确定其返回值。例如:如果 a.compare(b) 的返回值为 EQ,则 a == b 返回 true,否则返回 false。
父类型:
- Equatable<T>
- Less<T>
- Greater<T>
- LessOrEqual<T>
- GreaterOrEqual<T>
func compare(T)
func compare(that: T): Ordering
功能:判断当前 T 类型实例与参数指向的 T 类型实例的大小关系。
参数:
- that: T - 待与当前实例比较的另一个实例。
返回值:
operator func <(T)
operator func <(rhs: T): Bool
功能:判断当前 T 类型实例是否小于参数指向的 T 类型实例,该函数是此接口的一个默认实现函数。
参数:
- rhs: T - 待与当前实例比较的另一个实例。
返回值:
- Bool - 如果小于,返回 true,否则返回 false。
operator func <=(T)
operator func <=(rhs: T): Bool
功能:判断当前 T 类型实例是否小于等于参数指向的 T 类型实例,该函数是此接口的一个默认实现函数。
参数:
- rhs: T - 待与当前实例比较的另一个实例。
返回值:
- Bool - 如果小于等于,返回 true,否则返回 false。
operator func ==(T)
operator func ==(rhs: T): Bool
功能:判断两个实例是否相等,该函数是此接口的一个默认实现函数。
参数:
- rhs: T - 待比较的另一个实例。
返回值:
- Bool - 如果相等,返回 true,否则返回 false。
operator func >(T)
operator func >(rhs: T): Bool
功能:判断当前 T 类型实例是否大于参数指向的 T 类型实例,该函数是此接口的一个默认实现函数。
参数:
- rhs: T - 待与当前实例比较的另一个实例。
返回值:
- Bool - 如果大于,返回 true,否则返回 false。
operator func >=(T)
operator func >=(rhs: T): Bool
功能:判断当前 T 类型实例是否大于等于参数指向的 T 类型实例,该函数是此接口的一个默认实现函数。
参数:
- rhs: T - 待与当前实例比较的另一个实例。
返回值:
- Bool - 如果大于等于,返回 true,否则返回 false。
interface Countable<T>
public interface Countable<T> {
func next(right: Int64): T
func position(): Int64
}
功能:该接口表示类型可数。
可数类型的每一个实例都对应一个位置信息(Int64 值),可以通过往后数数得到其他的该类型实例。
func next(Int64)
func next(right: Int64): T
功能:获取当前实例向右移动 right 后对应位置的 T 类型实例。
参数:
- right: Int64 - 往右数的个数。
返回值:
- T - 向右移动
right后对应位置的T类型实例。
func position()
func position(): Int64
功能:获取当前可数实例的位置信息,即将当前实例转为 Int64 类型。
返回值:
extend Float64
extend Float64
功能:拓展了 Float64 类型作为左操作数和 Duration 类型作为右操作数的乘法运算。
operator func *(Duration)
public operator func *(r: Duration): Duration
功能:实现 Float64 类型和 Duration 类型的乘法,即 Float64 * Duration 运算。
参数:
返回值:
异常:
- ArithmeticException - 当相乘后的结果超出 Duration 的表示范围时,抛出异常。
extend Int64
extend Int64
功能:拓展了 Int64 类型作为左操作数和 Duration 类型作为右操作数的乘法运算。
operator func *(Duration)
public operator func *(r: Duration): Duration
功能:实现 Int64 类型和 Duration 类型的乘法,即 Int64 * Duration 运算。
例如 2 * Duration.second 返回表示时间间隔为 2 秒的 Duration 实例。
参数:
- r: Duration - 乘法的右操作数。
返回值:
异常:
- ArithmeticException - 当相乘后的结果超出 Duration 的表示范围时,抛出异常。
interface Equal<T>
public interface Equal<T> {
operator func ==(rhs: T): Bool
}
功能:该接口用于支持判等操作。
operator func ==(T)
operator func ==(rhs: T): Bool
功能:判断两个实例是否相等。
参数:
- rhs: T - 待比较的另一个实例。
返回值:
- Bool - 如果相等,返回 true,否则返回 false。
interface Equatable<T>
public interface Equatable<T> <: Equal<T> & NotEqual<T> {
operator func !=(rhs: T): Bool
}
功能:该接口是判等和判不等两个接口的集合体。
该接口中提供运算符 != 重载的默认实现,默认实现根据 == 运算的返回值来确定其返回值。例如:如果 a == b 的返回值为 true,则 a != b 返回 false,否则返回 true。
已为部分仓颉类型实现该接口,包括:Unit、Bool 、Rune、Int64、Int32、Int16、Int8、UIntNative、UInt64、UInt32、UInt16、UInt8、Float64、Float32、Float16、String、Array、Box、ArrayList、HashSet。
父类型:
operator func !=(T)
operator func !=(rhs: T): Bool
功能:判断两个实例是否不相等,该函数是此接口的一个默认实现函数。
参数:
- rhs: T - 待比较的另一个实例。
返回值:
- Bool - 如果不相等,返回 true,否则返回 false。
interface GreaterOrEqual<T>
public interface GreaterOrEqual<T> {
operator func >=(rhs: T): Bool
}
功能:该接口表示大于等于计算。
operator func >=(T)
operator func >=(rhs: T): Bool
功能:判断当前 T 类型实例是否大于等于参数指向的 T 类型实例。
参数:
- rhs: T - 待与当前实例比较的另一个实例。
返回值:
- Bool - 如果大于等于,返回 true,否则返回 false。
interface Greater<T>
public interface Greater<T> {
operator func >(rhs: T): Bool
}
功能:该接口表示大于计算。
operator func >(T)
operator func >(rhs: T): Bool
功能:判断当前 T 类型实例是否大于参数指向的 T 类型实例。
参数:
- rhs: T - 待与当前实例比较的另一个实例。
返回值:
- Bool - 如果大于,返回 true,否则返回 false。
interface Hashable
public interface Hashable {
func hashCode(): Int64
}
功能:该接口用于计算哈希值。
已为部分仓颉类型实现该接口,包括:Bool、Rune、IntNative、Int64、Int32、Int16、Int8、UIntNative、UInt64、UInt32、UInt16、UInt8、Float64、Float32、Float16、String、Box。
func hashCode()
func hashCode(): Int64
功能:获得实例类型的哈希值。
返回值:
- Int64 - 返回实例类型的哈希值。
interface Hasher
public interface Hasher {
func finish(): Int64
mut func reset(): Unit
mut func write(value: Bool): Unit
mut func write(value: Rune): Unit
mut func write(value: Int8): Unit
mut func write(value: Int16): Unit
mut func write(value: Int32): Unit
mut func write(value: Int64): Unit
mut func write(value: UInt8): Unit
mut func write(value: UInt16): Unit
mut func write(value: UInt32): Unit
mut func write(value: UInt64): Unit
mut func write(value: Float16): Unit
mut func write(value: Float32): Unit
mut func write(value: Float64): Unit
mut func write(value: String): Unit
}
功能:该接口用于处理哈希组合运算。
可以使用一系列 write 函数传入不同数据类型实例,并计算它们的组合哈希值。
func finish()
func finish(): Int64
功能:获取哈希运算的结果。
返回值:
- Int64 - 经过计算后的哈希值。
func reset()
mut func reset(): Unit
功能:重置哈希值到 0。
func write(Bool)
mut func write(value: Bool): Unit
功能:把想要哈希运算的 Bool 值传入,然后进行哈希组合运算。
参数:
- value: Bool - 待运算的值。
func write(Float16)
mut func write(value: Float16): Unit
功能:通过该函数把想要哈希运算的 Float16 值传入,然后进行哈希组合运算。
参数:
- value: Float16 - 待运算的值。
func write(Float32)
mut func write(value: Float32): Unit
功能:通过该函数把想要哈希运算的 Float32 值传入,然后进行哈希组合运算。
参数:
- value: Float32 - 待运算的值。
func write(Float64)
mut func write(value: Float64): Unit
功能:通过该函数把想要哈希运算的 Float64 值传入,然后进行哈希组合运算。
参数:
- value: Float64 - 待运算的值。
func write(Int16)
mut func write(value: Int16): Unit
功能:通过该函数把想要哈希运算的 Int16 值传入,然后进行哈希组合运算。
参数:
- value: Int16 - 待运算的值。
func write(Int32)
mut func write(value: Int32): Unit
功能:通过该函数把想要哈希运算的 Int32 值传入,然后进行哈希组合运算。
参数:
- value: Int32 - 待运算的值。
func write(Int64)
mut func write(value: Int64): Unit
功能:通过该函数把想要哈希运算的 Int64 值传入,然后进行哈希组合运算。
参数:
- value: Int64 - 待运算的值。
func write(Int8)
mut func write(value: Int8): Unit
功能:通过该函数把想要哈希运算的 Int8 值传入,然后进行哈希组合运算。
参数:
- value: Int8 - 待运算的值。
func write(Rune)
mut func write(value: Rune): Unit
功能:通过该函数把想要哈希运算的 Rune 值传入,然后进行哈希组合运算。
参数:
- value: Rune - 待运算的值。
func write(String)
mut func write(value: String): Unit
功能:通过该函数把想要哈希运算的 String 值传入,然后进行哈希组合运算。
参数:
- value: String - 待运算的值。
func write(UInt16)
mut func write(value: UInt16): Unit
功能:通过该函数把想要哈希运算的 UInt16 值传入,然后进行哈希组合运算。
参数:
- value: UInt16 - 待运算的值。
func write(UInt32)
mut func write(value: UInt32): Unit
功能:通过该函数把想要哈希运算的 UInt32 值传入,然后进行哈希组合运算。
参数:
- value: UInt32 - 待运算的值。
func write(UInt64)
mut func write(value: UInt64): Unit
功能:通过该函数把想要哈希运算的 UInt64 值传入,然后进行哈希组合运算。
参数:
- value: UInt64 - 待运算的值。
func write(UInt8)
mut func write(value: UInt8): Unit
功能:通过该函数把想要哈希运算的 UInt8 值传入,然后进行哈希组合运算。
参数:
- value: UInt8 - 待运算的值。
interface Iterable<E>
public interface Iterable<E> {
func iterator(): Iterator<E>
}
功能:该接口表示可迭代,实现了该接口的类型(通常为容器类型)可以在 for-in 语句中实现迭代,也可以获取其对应的迭代器类型实例,调用 next 函数实现迭代。
本包已经为 Array、ArrayList、HashMap 等基础容器类型实现了该接口,用户可以为其他类型实现该接口,使之支持迭代遍历的功能。
func iterator()
func iterator(): Iterator<E>
功能:获取迭代器。
返回值:
- Iterator<E> - 迭代器。
interface LessOrEqual<T>
public interface LessOrEqual<T> {
operator func <=(rhs: T): Bool
}
功能:该接口表示小于等于计算。
operator func <=(T)
operator func <=(rhs: T): Bool
功能:判断当前 T 类型实例是否小于等于参数指向的 T 类型实例。
参数:
- rhs: T - 待与当前实例比较的另一个实例。
返回值:
- Bool - 如果小于等于,返回 true,否则返回 false。
interface Less<T>
public interface Less<T> {
operator func <(rhs: T): Bool
}
功能:该接口表示小于计算。
operator func <(T)
operator func <(rhs: T): Bool
功能:判断当前 T 类型实例是否小于参数指向的 T 类型实例。
参数:
- rhs: T - 待与当前实例比较的另一个实例。
返回值:
- Bool - 如果小于,返回 true,否则返回 false。
interface NotEqual<T>
public interface NotEqual<T> {
operator func !=(rhs: T): Bool
}
功能:该接口用于支持判不等操作。
operator func !=(T)
operator func !=(rhs: T): Bool
功能:判断两个实例是否不相等。
参数:
- rhs: T - 待比较的另一个实例。
返回值:
- Bool - 如果不相等,返回 true,否则返回 false。
interface Resource
public interface Resource {
func close(): Unit
func isClosed(): Bool
}
功能:该接口用于资源管理,通常用于内存、句柄等资源的关闭和释放。
实现了该接口的类型可以在 try-with-resource 语法上下文中实现自动资源释放。
func isClosed()
func isClosed(): Bool
功能:判断资源是否已经关闭。
返回值:
- Bool - 如果已经关闭返回 true,否则返回 false。
func close()
func close(): Unit
功能:关闭资源。
interface ThreadContext
public interface ThreadContext {
func end(): Unit
func hasEnded(): Bool
}
功能:仓颉线程上下文接口。
用户创建 thread 时,除了缺省 spawn 表达式入参,也可以通过传入不同 ThreadContext 类型的实例,选择不同的线程上下文,然后一定程度上控制并发行为。
目前不允许用户自行实现 ThreadContext 接口,仓颉语言根据使用场景,提供了 MainThreadContext, 具体定义可在终端框架库中查阅。
注意:
在 cjvm 后端,
spawn传入 ThreadContext 类型的参数时,无任何作用。
func end()
func end(): Unit
功能:结束方法,用于向当前 context 发送结束请求。
func hasEnded()
func hasEnded(): Bool
功能:检查方法,用于检查当前 context 是否已结束。
返回值:
- Bool - 如果结束返回 true,否则返回 false。
interface ToString
public interface ToString {
func toString(): String
}
功能:该接口用来提供具体类型的字符串表示。
func toString()
func toString(): String
功能:获取实例类型的字符串表示。
返回值:
- String - 返回实例类型的字符串表示。
类
class ArrayIterator<T>
public class ArrayIterator<T> <: Iterator<T> {
public init(data: Array<T>)
}
功能:数组迭代器,迭代功能详述见 Iterable 和 Iterator 说明。
父类型:
- Iterator<T>
init(Array<T>)
public init(data: Array<T>)
功能:给定一个 Array 数组实例,创建其对应的迭代器,用来迭代遍历该数组实例中全部对象。
参数:
- data: Array<T> - 数组实例。
func next()
public func next(): Option<T>
功能:返回数组迭代器中的下一个值。
返回值:
示例:
main() {
var arr: Array<Int64> = [1, 2, 3, 4]
var arrIterator: ArrayIterator<Int64> = ArrayIterator(arr)
var num: Option<Int64>
while (true) {
num = arrIterator.next()
if (num.isNone()) {
break
}
println(num.getOrDefault({=> -1}))
}
}
运行结果:
1
2
3
4
class Box<T>
public class Box<T> {
public var value: T
public init(v: T)
}
功能:Box 类型提供了为其他类型添加一层 class 封装的能力。
如果 T 类型本身不具备引用能力,如 struct 类型,封装后 Box<T> 类型将可被引用。
var value
public var value: T
功能:获取或修改被包装的值。
类型:T
init(T)
public init(v: T)
功能:给定 T 类型实例,构造对应的 Box<T> 实例。
参数:
- v: T - 任意类型实例。
extend<T> Box<T> <: Comparable<Box<T>> where T <: Comparable<T>
extend<T> Box<T> <: Comparable<Box<T>> where T <: Comparable<T>
功能:为 Box<T> 类扩展 Comparable<Box<T>> 接口,提供比较大小的能力。
Box<T> 实例的大小关系与其封装的 T 实例大小关系相同。
父类型:
- Comparable<Box<T>>
func compare(Box<T>)
public func compare(that: Box<T>): Ordering
功能:判断当前 Box 实例与另一个 Box 实例的大小关系。
参数:
返回值:
示例:
struct Data <: Comparable<Data> {
var a: Int64 = 0
var b: Int64 = 0
public init(a: Int64, b: Int64) {
this.a = a
this.b = b
}
public func compare(d: Data) {
let tValue: Int64 = this.a + this.b
let dValue: Int64 = d.a + d.b
if (tValue > dValue) {
return Ordering.GT
} else if (tValue == dValue) {
return Ordering.EQ
} else {
return Ordering.LT
}
}
}
main() {
var data1: Box<Data> = Box<Data>(Data(12, 12))
var data2: Box<Data> = Box<Data>(Data(7, 12))
println(data1.compare(data2))
}
运行结果:
Ordering.GT
operator func !=(Box<T>)
public operator func !=(that: Box<T>): Bool
功能:比较 Box 对象是否不相等。
参数:
返回值:
operator func <(Box<T>)
public operator func <(that: Box<T>): Bool
功能:比较 Box 对象的大小。
参数:
返回值:
operator func <=(Box<T>)
public operator func <=(that: Box<T>): Bool
功能:比较 Box 对象的大小。
参数:
返回值:
operator func ==(Box<T>)
public operator func ==(that: Box<T>): Bool
功能:比较 Box 对象是否相等。
参数:
返回值:
operator func >(Box<T>)
public operator func >(that: Box<T>): Bool
功能:比较 Box 对象的大小。
参数:
返回值:
operator func >=(Box<T>)
public operator func >=(that: Box<T>): Bool
功能:比较 Box 对象的大小。
参数:
返回值:
extend<T> Box<T> <: Hashable where T <: Hashable
extend<T> Box<T> <: Hashable where T <: Hashable
功能:为 Box<T> 类扩展 Hashable 接口,提供比较大小的能力。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取 Box 对象的哈希值。
实际上该值为 Box 中封装的 T 类型实例的哈希值。
返回值:
extend<T> Box<T> <: ToString where T <: ToString
extend<T> Box<T> <: ToString where T <: ToString
功能:为 Box<T> 类型扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:获取 Box 对象的字符串表示,字符串内容为当前实例封装的 T 类型实例的字符串表示。
返回值:
- String - 转换后的字符串。
class Future<T>
public class Future<T>
功能:Future<T> 实例代表一个仓颉线程任务,可用于获取仓颉线程的计算结果,向仓颉线程发送取消信号。
spawn 表达式的返回类型是 Future<T>,其中 T 的类型取决于 spawn 表达式中的闭包的返回值类型。
prop thread
public prop thread: Thread
功能:获得对应仓颉线程的 Thread 实例。
类型:Thread
func cancel()
public func cancel(): Unit
功能:给当前 Future 实例对应的仓颉线程发送取消请求。该方法不会立即停止线程执行,仅发送请求,相应地,Thread 类的函数 hasPendingCancellation 可用于检查线程是否存在取消请求,开发者可以通过该检查来自行决定是否提前终止线程以及如何终止线程。
示例:
main(): Unit {
/* 创建线程 */
let future = spawn {
while (true) {
if (Thread.currentThread.hasPendingCancellation) {
return 0
}
}
return 1
}
/* 向线程发送取消请求 */
future.cancel()
let res = future.get()
println(res)
}
运行结果:
0
func get()
public func get(): T
功能:阻塞当前线程,等待并获取当前 Future<T> 对象对应的线程的结果。
返回值:
- T - 当前 Future<T> 实例代表的线程运行结束后的返回值。
示例:
main(): Int64 {
let fut: Future<Int64> = spawn {
=>
sleep(1000 * Duration.millisecond) /* 睡眠 1 秒 */
return 1
}
/* 等待线程完成 */
let result: Int64 = fut.get()
println(result)
return 0
}
运行结果:
1
func get(Duration)
public func get(timeout: Duration): T
功能:阻塞当前线程,等待指定时长并获取当前 Future<T> 对象对应的线程的返回值。
需指定等待的超时时间,如果相应的线程在指定时间内未完成执行,则该函数将抛出异常TimeoutException。如果 timeout <= Duration.Zero,等同于 get(),即不限制等待时长。如果线程抛出异常退出执行,在 get 调用处将继续抛出该异常。
参数:
- timeout: Duration - 等待时间。
返回值:
- T - 返回指定时长后仓颉线程执行结果。
异常:
- TimeoutException - 如果相应的线程在指定时间内未完成执行,则该函数将抛出此异常。
示例:
main(): Int64 {
let fut: Future<Int64> = spawn {
=>
sleep(1000 * Duration.millisecond) /* 睡眠 1 秒 */
return 1
}
let result: Int64 = fut.get(2000 * Duration.millisecond)
/* 最大等待时间为 2 秒, 超过该时间抛出 TimeoutException */
println(result)
return 0
}
运行结果:
1
func tryGet()
public func tryGet(): Option<T>
功能:尝试获取执行结果,不会阻塞当前线程。如果相应的线程未完成,则该函数返回 None。
返回值:
- Option<T> - 如果当前仓颉线程未完成返回
None,否则返回执行结果。
示例:
main(): Int64 {
let fut: Future<Int64> = spawn {
=>
sleep(1000 * Duration.millisecond) /* 睡眠 1 秒 */
return 1
}
/* 主线程等待 4 秒,保证创建线程已经完成 */
sleep(4000 * Duration.millisecond)
/* 尝试获取创建线程的运行结果 */
let result: Option<Int64> = fut.tryGet()
println(result)
return 0
}
运行结果:
Some(1)
class Iterator<T>
public abstract class Iterator<T> <: Iterable<T>
功能:该类表示迭代器,提供 next 方法支持对容器内的成员进行迭代遍历。
父类型:
- Iterable<T>
func iterator()
public func iterator() : Iterator<T>
功能:返回迭代器自身。
返回值:
- Iterator<T> - 迭代器自身。
func next()
public func next(): Option<T>
功能:获取迭代过程中的下一个元素。
返回值:
- Option<T> - 迭代过程中的下一个元素。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
var iter = arr.iterator() /* 获取容器的迭代器对象 */
while (true) { /* 使用迭代器进行遍历 */
match (iter.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
1
2
3
4
5
extend<T> Iterator<T>
extend<T> Iterator<T>
功能:扩展 Iterator<T> 类型。
迭代器的方法主要包含中间操作和终止操作。中间操作(如 skip()、map())会产生一个新的迭代器。而终止操作(如 count()、all())会根据迭代器产生的元素计算结果,而不产生新的迭代器。每种迭代器方法都会消耗迭代器中不同数量的元素,详见各方法描述。
func all((T) -> Bool)
public func all(predicate: (T)-> Bool): Bool
功能:判断迭代器所有元素是否都满足条件。此方法会重复获取并消耗迭代器中元素直到某个元素不满足条件。
参数:
- predicate: (T) -> Bool - 给定的条件。
返回值:
- Bool - 元素是否都满足条件。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取容器的迭代器对象 */
var iter = arr.iterator()
var flag: Bool = iter.all({v: Int64 => v > 0})
println(flag)
return 0
}
运行结果:
true
func any((T) -> Bool)
public func any(predicate: (T)-> Bool): Bool
功能:判断迭代器是否存在任意一个满足条件的元素。此方法会重复获取并消耗迭代器中元素直到某个元素满足条件。
参数:
- predicate: (T) -> Bool - 给定的条件。
返回值:
- Bool - 是否存在任意满足条件的元素。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取容器的迭代器对象 */
var iter = arr.iterator()
var flag: Bool = iter.any({v: Int64 => v > 4})
println(flag)
return 0
}
运行结果:
true
func at(Int64)
public func at(n: Int64): Option<T>
功能:获取当前迭代器第 n 个元素,n 从 0 开始计数。此方法会消耗指定元素前的所有元素(包括指定元素)。
参数:
- n: Int64 - 给定的元素序号,序号从 0 开始。
返回值:
- Option<T> - 返回对应位置元素,若 n 大于剩余元素数量则返回 None。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取容器的迭代器对象 */
var iter = arr.iterator()
var num: Option<Int64> = iter.at(2)
println(num)
return 0
}
运行结果:
Some(3)
func concat(Iterator<T>)
public func concat(other: Iterator<T>): Iterator<T>
功能:串联两个迭代器,当前迭代器在先,参数表示的迭代器在后。
参数:
- other: Iterator<T> - 要串联在后面的迭代器。
返回值:
- Iterator<T> - 返回串联后的新迭代器。
示例:
main(): Int64 {
var arr1: Array<Int64> = [1, 2]
var arr2: Array<Int64> = [3, 4]
/* 获取容器的迭代器对象 */
var iter1 = arr1.iterator()
var iter2 = arr2.iterator()
/* 合并两个迭代器 */
var iter = iter1.concat(iter2)
/* 使用迭代器进行遍历 */
while (true) {
match (iter.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
1
2
3
4
func count()
public func count(): Int64
功能:统计当前迭代器包含元素数量。此方法会消耗迭代器中所有元素来计算迭代器中的元素数量。
注意:
该方法会消耗迭代器,即使用该方法后迭代器内不再包含任何元素。
返回值:
- Int64 - 返回迭代器包含元素数量。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2]
/* 获取容器的迭代器对象 */
var iter = arr.iterator()
let len: Int64 = iter.count()
println(len)
/* 使用迭代器进行遍历,但是count消耗了迭代器中的元素,因此不会打印 */
while (true) {
match (iter.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
2
func enumerate()
public func enumerate(): Iterator<(Int64, T)>
功能:用于获取带索引的迭代器。
返回值:
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2]
/* 获取容器的迭代器对象 */
var iter = arr.iterator()
var iter1 = iter.enumerate()
/* 使用迭代器进行遍历 */
while (true) {
match (iter1.next()) {
case Some(i) =>
print(i[0].toString() + ' ')
print(i[1])
println()
case None => break
}
}
return 0
}
运行结果:
0 1
1 2
func filter((T) -> Bool)
public func filter(predicate: (T)-> Bool): Iterator<T>
功能:筛选出满足条件的元素。
参数:
- predicate: (T) -> Bool - 给定的条件,条件为
true的元素会按顺序出现在返回的迭代器里。
返回值:
- Iterator<T> - 返回一个新迭代器。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取过滤后的迭代器对象 */
var iter = arr.iterator()
var iter1 = iter.filter({value: Int64 => value > 2})
/* 使用迭代器进行遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
3
4
5
func filterMap<R>((T) -> Option<R>)
public func filterMap<R>(transform: (T) -> Option<R>): Iterator<R>
功能:同时进行筛选操作和映射操作,返回一个新的迭代器。
参数:
- transform: (T) -> Option<T> - 给定的映射函数。函数返回值为 Some 对应 filter 的 predicate 为 true,反之表示 false。
返回值:
- Iterator<R> - 返回一个新迭代器。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取过滤后的迭代器对象,对元素进行过滤和映射,映射需返回Option类型 */
var iter = arr.iterator()
var iter1 = iter.filterMap({
value: Int64 => if (value > 2) {
return Some(value + 1)
} else {
return None<Int64>
}
})
/* 使用迭代器进行遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
4
5
6
func first()
public func first(): Option<T>
功能:获取当前迭代器的头部元素。此方法会获取并消耗第一个元素。
返回值:
- Option<T> - 返回头部元素,若为空则返回 None。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取迭代器对象 */
var iter = arr.iterator()
var head: Option<Int64> = iter.first()
println(head)
return 0
}
运行结果:
Some(1)
func flatMap<R>((T) -> Iterator<R>)
public func flatMap<R>(transform: (T) -> Iterator<R>): Iterator<R>
功能:创建一个带 flatten 功能的映射。
参数:
- transform: (T) -> Iterable<R> - 给定的映射函数。
返回值:
示例:
main(): Int64 {
var arr: Array<Array<Int64>> = [[1], [2], [3], [4, 5]]
/* 获取带flatten功能的迭代器对象 */
var iter = arr.iterator()
var iter1 = iter.flatMap({value => value.iterator()})
/* 使用迭代器进行展开遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
1
2
3
4
5
func fold<R>(R, (R, T) -> R)
public func fold<R>(initial: R, operation: (R, T)->R): R
功能:使用指定初始值,从左向右计算。此方法会消耗迭代器中的所有元素。
参数:
- initial: R - 给定的 R 类型的初始值。
- operation: (R, T) -> R - 给定的计算函数。
返回值:
- R - 返回最终计算得到的值。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取迭代器对象,对数组元素进行求和 */
var iter = arr.iterator()
var sum: Int64 = iter.fold(0, {total, value => total + value})
println(sum)
return 0
}
运行结果:
15
func forEach((T) -> Unit)
public func forEach(action: (T)-> Unit): Unit
功能:遍历当前迭代器所有元素,对每个元素执行给定的操作。此方法会消耗迭代器中的所有元素。
参数:
- action: (T) -> Unit - 给定的操作函数。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
var iter = arr.iterator()
iter.forEach({value => println(value)})
return 0
}
运行结果:
1
2
3
4
5
func inspect((T) -> Unit)
public func inspect(action: (T) -> Unit): Iterator<T>
功能:迭代器每次调用 next() 对当前元素执行额外操作(不会消耗迭代器中元素)。
参数:
- action: (T) -> Unit - 给定的操作函数。
返回值:
- Iterator<T> - 返回一个新迭代器。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2]
/* 获取迭代器对象,并为next函数附加额外操作 */
var iter = arr.iterator()
var iter1 = iter.inspect({value => println("Logging: Processing ${value}")})
/* 使用迭代器进行展开遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println("Processing ${i} !")
case None => break
}
}
return 0
}
运行结果:
Logging: Processing 1
Processing 1 !
Logging: Processing 2
Processing 2 !
func intersperse(T)
public func intersperse(separator: T): Iterator<T>
功能:迭代器每两个元素之间插入一个给定的新元素。
参数:
- separator: T - 给定的元素。
返回值:
- Iterator<T> - 返回一个新迭代器。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2]
/* 获取迭代器对象,每两个元素之间插入一个0 */
var iter = arr.iterator()
var iter1 = iter.intersperse(0)
/* 使用迭代器进行展开遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
1
0
2
func isEmpty()
public func isEmpty(): Bool
功能:判断当前迭代器是否为空。此方法会调用 next() ,根据其返回值判断当前迭代器是否为空。因此如果当前迭代器不为空,则会消耗一个元素。
返回值:
- Bool - 返回当前迭代器是否为空。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2]
/* 获取迭代器对象 */
var iter = arr.iterator()
/* 判断迭代器中是否有元素,如果有会消耗一个元素 */
println(iter.isEmpty())
/* 使用迭代器进行展开遍历 */
while (true) {
match (iter.next()) {
case Some(i) => println(i)
case None => break
}
}
println(iter.isEmpty())
return 0
}
运行结果:
false
2
true
func last()
public func last(): Option<T>
功能:获取当前迭代器尾部元素。此方法会获取并消耗迭代器中的所有元素,并返回最后一个元素。
返回值:
- Option<T> - 返回尾部元素,若为空则返回 None。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2]
/* 获取迭代器对象 */
var iter = arr.iterator()
println(iter.last())
return 0
}
运行结果:
Some(2)
func map<R>((T) -> R)
public func map<R>(transform: (T)-> R): Iterator<R>
功能:创建一个映射。
参数:
- transform: (T) ->R - 给定的映射函数。
返回值:
- Iterator<R> - 返回一个映射。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4]
/* 获取迭代器对象,并对元素进行映射,获取新的迭代器对象 */
var iter = arr.iterator()
var iter1 = iter.map({value => value * 2})
/* 使用迭代器进行展开遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
2
4
6
8
func none((T) -> Bool)
public func none(predicate: (T)-> Bool): Bool
功能:判断当前迭代器中所有元素是否都不满足条件。此方法会重复获取并消耗迭代器中元素直到某个元素满足条件。
参数:
- predicate: (T) -> Bool - 给定的条件。
返回值:
- Bool - 当前迭代器中元素是否都不满足条件。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4]
/* 获取迭代器对象,并对元素进行映射,获取新的迭代器对象 */
var iter1 = arr.iterator()
var iter2 = arr.iterator()
/* 存在元素大于2,返回false */
var flag1: Bool = iter1.none({value => value > 2})
println(flag1)
/* 不存在元素大于5,返回true */
var flag2: Bool = iter2.none({value => value > 5})
println(flag2)
return 0
}
运行结果:
false
true
func reduce((T, T) -> T)
public func reduce(operation: (T, T) -> T): Option<T>
功能:使用第一个元素作为初始值,从左向右计算。此方法会消耗迭代器中的所有元素。
参数:
- operation: (T, T) -> T - 给定的计算函数。
返回值:
- Option<T> - 返回计算结果。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取迭代器对象,对数组元素进行求和 */
var iter = arr.iterator()
var sum: Option<Int64> = iter.reduce({total, value => total + value})
println(sum)
return 0
}
运行结果:
Some(15)
func skip(Int64)
public func skip(count: Int64): Iterator<T>
功能:从前往后从当前迭代器跳过特定个数。
当 count 小于 0 时,抛出异常。当 count 等于 0 时,相当没有跳过任何元素,返回原迭代器。当 count 大于0并且count小于迭代器的大小时,跳过 count 个元素后,返回含有剩下的元素的新迭代器。当 count 大于等于迭代器的大小时,跳过所有元素,返回空迭代器。
参数:
- count: Int64 - 要跳过的个数。
返回值:
- Iterator<T> - 返回一个跳过指定数量元素的迭代器。
异常:
- IllegalArgumentException - 当 count < 0 时,抛出异常。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取迭代器对象,跳过前两个元素 */
var iter = arr.iterator()
var iter1 = iter.skip(2)
/* 使用迭代器进行展开遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
3
4
5
func step(Int64)
public func step(count: Int64): Iterator<T>
功能:迭代器每次调用 next() 跳过特定个数。
当 count 小于等于 0 时,抛出异常。当 count 大于 0 时,每次调用 next() 跳过 count 次,直到迭代器为空。
参数:
- count: Int64 - 每次调用 next() 要跳过的个数。
返回值:
- Iterator<T> - 返回一个新迭代器,这个迭代器每次调用 next() 会跳过特定个数。
异常:
- IllegalArgumentException - 当 count <= 0 时,抛出异常。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取迭代器对象,每次调用 next() 会跳过两个元素 */
var iter = arr.iterator()
var iter1 = iter.step(2)
/* 使用迭代器进行展开遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
1
3
5
func take(Int64)
public func take(count: Int64): Iterator<T>
功能:从当前迭代器取出特定个数。
从前往后取出当前迭代器特定个数的元素。当 count 小于 0 时,抛出异常。当 count 等于 0 时,不取元素,返回空迭代器。当 count 大于 0 小于迭代器的大小时,取前 count 个元素,返回新迭代器。当 count 大于等于迭代器的大小时,取所有元素,返回原迭代器。
参数:
- count: Int64 - 要取出的个数。
返回值:
- Iterator<T> - 返回一个取出指定数量元素的迭代器。
异常:
- IllegalArgumentException - 当 count < 0 时,抛出异常。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4, 5]
/* 获取迭代器对象,取出前三个元素 */
var iter = arr.iterator()
var iter1 = iter.take(3)
/* 使用迭代器进行展开遍历 */
while (true) {
match (iter1.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
1
2
3
func zip<R>(Iterator<R>)
public func zip<R>(it: Iterator<R>): Iterator<(T, R)>
功能:将两个迭代器合并成一个(长度取决于短的那个迭代器)。
参数:
- it: Iterator<R> - 要合并的其中一个迭代器。
返回值:
- Iterator<(T, R)> - 返回一个新迭代器。
示例:
main(): Int64 {
var arr1: Array<Int64> = [1, 2, 3, 4]
var arr2: Array<Int64> = [4, 5, 6]
/* 获取迭代器对象并合并,新迭代器中的元素为对应索引位置元素的元组 */
var iter1 = arr1.iterator()
var iter2 = arr2.iterator()
var iter = iter1.zip(iter2)
/* 使用迭代器进行遍历,长度取决于较短的迭代器 */
while (true) {
match (iter.next()) {
case Some(i) => println("The current element is (${i[0]}, ${i[1]}) ")
case None => break
}
}
return 0
}
运行结果:
The current element is (1, 4)
The current element is (2, 5)
The current element is (3, 6)
extend<T> Iterator<T> where T <: Comparable<T>
extend<T> Iterator<T> where T <: Comparable<T>
功能:为 Iterator<T> 类型扩展 Comparable<T> 接口,支持比较操作。
func max()
public func max(): Option<T>
功能:筛选最大的元素。此方法会消耗迭代器中的所有元素。
返回值:
- Option<T> - 返回最大的元素,若为空则返回 None。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4]
/* 获取迭代器对象,使用 max() 求最大值 */
var iter = arr.iterator()
match(iter.max()) {
case Some(i)=> println(i)
case None=> println("None!")
}
return 0
}
运行结果:
4
func min()
public func min(): Option<T>
功能:筛选最小的元素。此方法会消耗迭代器中的所有元素。
返回值:
- Option<T> - 返回最小的元素,若为空则返回 None。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4]
/* 获取迭代器对象,使用 min() 求最小值 */
var iter = arr.iterator()
match(iter.min()) {
case Some(i)=> println(i)
case None=> println("None!")
}
return 0
}
运行结果:
1
extend<T> Iterator<T> where T <: Equatable<T>
extend<T> Iterator<T> where T <: Equatable<T>
功能:为 Iterator<T> 类型扩展 扩展 Equatable<T> 接口,支持判等操作。
func contains(T)
public func contains(element: T): Bool
功能:遍历所有元素,判断是否包含指定元素。此方法会重复获取并消耗迭代器中元素直到某个元素与参数 element 相等。
参数:
- element: T - 要查找的元素。
返回值:
- Bool - 是否包含指定元素。
示例:
main(): Int64 {
var arr: Array<Int64> = [1, 2, 3, 4]
/* 获取迭代器对象,查找是否包含元素 3 */
var iter = arr.iterator()
println(iter.contains(3))
/* 使用迭代器进行遍历,输出剩余元素 */
while (true) {
match (iter.next()) {
case Some(i) => println(i)
case None => break
}
}
return 0
}
运行结果:
true
4
class Object
public open class Object <: Any {
public const init()
}
功能:Object 是所有 class 的父类,所有 class 都默认继承它。Object 类中不包含任何成员,即 Object 是一个“空”的类。
父类型:
init()
public const init()
功能:构造一个 object 实例。
class RangeIterator<T> <: Iterator<T> where T <: Countable<T> & Comparable<T> & Equatable<T>
public class RangeIterator<T> <: Iterator<T> where T <: Countable<T> & Comparable<T> & Equatable<T>
功能:Range 类型的迭代器,迭代功能详述见 Iterable 和 Iterator 接口说明。
父类型:
- Iterator<T>
func next()
public func next(): Option<T>
功能:获取 Range 迭代器中的下一个值。
返回值:
class StackTraceElement
public open class StackTraceElement {
public let declaringClass: String
public let methodName: String
public let fileName: String
public let lineNumber: Int64
public init(declaringClass: String, methodName: String, fileName: String, lineNumber: Int64)
}
功能:表示一个异常堆栈的具体信息,包括异常发生的类名、函数名、文件名、行号。
let declaringClass
public let declaringClass: String
功能:获取异常发生的类名。
类型:String
let fileName
public let fileName: String
功能:获取异常发生的文件名。
类型:String
let lineNumber
public let lineNumber: Int64
功能:获取异常发生的行号。
类型:Int64
let methodName
public let methodName: String
功能:获取异常发生的函数名。
类型:String
init(String, String, String, Int64)
public init(declaringClass: String, methodName: String, fileName: String, lineNumber: Int64)
功能:构造一个异常堆栈实例,指定类名、函数名、文件名、行号。
参数:
- declaringClass: String - 类名。
- methodName: String - 函数名。
- fileName: String - 文件名。
- lineNumber: Int64 - 行号。
class StringBuilder
public class StringBuilder <: ToString {
public init()
public init(str: String)
public init(r: Rune, n: Int64)
public init(value: Array<Rune>)
public init(capacity: Int64)
}
功能:该类主要用于字符串的构建。
StringBuilder 在字符串的构建上效率高于 String:
- 在功能上支持传入多个类型的值,该类将自动将其转换为 String 类型对象,并追加到构造的字符串中。
- 在性能上使用动态扩容算法,减少内存申请频率,构造字符串的速度更快,占用内存资源通常更少。
注意:
StringBuilder 仅支持 UTF-8 编码的字符数据。
父类型:
prop capacity
public prop capacity: Int64
功能:获取 StringBuilder 实例此时能容纳字符串的长度,该值会随扩容的发生而变大。
类型:Int64
prop size
public prop size: Int64
功能:获取 StringBuilder 实例中字符串长度。
类型:Int64
init()
public init()
功能:构造一个初始容量为 32 的空 StringBuilder 实例。
init(Array<Rune>)
public init(value: Array<Rune>)
功能:使用参数 value 指定的字符数组初始化一个 StringBuilder 实例,该实例的初始容量为 value 大小,初始内容为 value 包含的字符内容。
参数:
- value: Array<Rune> - 初始化 StringBuilder 实例的字符数组。
init(Int64)
public init(capacity: Int64)
功能:使用参数 capacity 指定的容量初始化一个空 StringBuilder 实例,该实例的初始容量为 value 大小,初始内容为若干 \0 字符。
参数:
- capacity: Int64 - 初始化 StringBuilder 的字节容量,取值范围为 (0, Int64.Max]。
异常:
- IllegalArgumentException - 当参数
capacity的值小于等于 0 时,抛出异常。
init(Rune, Int64)
public init(r: Rune, n: Int64)
功能:使用 n 个 r 字符初始化 StringBuilder 实例,该实例的初始容量为 n,初始内容为 n 个 r 字符。
参数:
- r: Rune - 初始化 StringBuilder 实例的字符。
- n: Int64 - 字符
r的数量,取值范围为 [0, Int64.Max]。
异常:
- IllegalArgumentException - 当参数
n小于 0 时,抛出异常。
init(String)
public init(str: String)
功能:根据指定初始字符串构造 StringBuilder 实例,该实例的初始容量为指定字符串的大小,初始内容为指定字符串。
参数:
- str: String - 初始化 StringBuilder 实例的字符串。
func append(Array<Rune>)
public func append(runeArr: Array<Rune>): Unit
功能:在 StringBuilder 末尾插入一个 Rune 数组中所有字符。
参数:
- runeArr: Array<Rune> - 插入的
Rune数组。
func append<T>(Array<T>) where T <: ToString
public func append<T>(val: Array<T>): Unit where T <: ToString
功能:在 StringBuilder 末尾插入参数 val 指定的 Array<T> 的字符串表示,类型 T 需要实现 ToString 接口。
参数:
func append(Bool)
public func append(b: Bool): Unit
功能:在 StringBuilder 末尾插入参数 b 的字符串表示。
参数:
func append(CString)
public func append(cstr: CString): Unit
功能:在 StringBuilder 末尾插入参数 cstr 指定 CString 中的内容。
参数:
func append(Float16)
public func append(n: Float16): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(Float32)
public func append(n: Float32): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(Float64)
public func append(n: Float64): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(Int16)
public func append(n: Int16): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(Int32)
public func append(n: Int32): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(Int64)
public func append(n: Int64): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(Int8)
public func append(n: Int8): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(Rune)
public func append(r: Rune): Unit
功能:在 StringBuilder 末尾插入参数 r 指定的字符。
参数:
- r: Rune - 插入的字符。
func append(String)
public func append(str: String): Unit
功能:在 StringBuilder 末尾插入参数 str 指定的字符串。
参数:
- str: String - 插入的字符串。
func append(StringBuilder)
public func append(sb: StringBuilder): Unit
功能:在 StringBuilder 末尾插入参数 sb 指定的 StringBuilder 中的内容。
参数:
- sb: StringBuilder - 插入的 StringBuilder 实例。
func append<T>(T) where T <: ToString
public func append<T>(v: T): Unit where T <: ToString
功能:在 StringBuilder 末尾插入参数 v 指定 T 类型的字符串表示,类型 T 需要实现 ToString 接口。
参数:
- v: T - 插入的
T类型实例。
func append(UInt16)
public func append(n: UInt16): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(UInt32)
public func append(n: UInt32): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(UInt64)
public func append(n: UInt64): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func append(UInt8)
public func append(n: UInt8): Unit
功能:在 StringBuilder 末尾插入参数 n 的字符串表示。
参数:
func appendFromUtf8(Array<Byte>)
public func appendFromUtf8(arr: Array<Byte>): Unit
功能:在 StringBuilder 末尾插入参数 arr 指向的字节数组。
该函数要求参数 arr 符合 UTF-8 编码,如果不符合,将抛出异常。
参数:
异常:
- IllegalArgumentException - 当字节数组不符合 utf8 编码规则时,抛出异常。
func appendFromUtf8Unchecked(Array<Byte>)
public unsafe func appendFromUtf8Unchecked(arr: Array<Byte>): Unit
功能:在 StringBuilder 末尾插入参数 arr 指向的字节数组。
相较于 appendFromUtf8 函数,它并没有针对于字节数组进行 UTF-8 相关规则的检查,所以它所构建的字符串并不一定保证是合法的,甚至出现非预期的异常,如果不是某些场景下的速度考虑,请优先使用安全的 appendFromUtf8 函数。
参数:
func reserve(Int64)
public func reserve(additional: Int64): Unit
功能:将 StringBuilder 扩容 additional 大小。
当 additional 小于等于零,或剩余容量大于等于 additional 时,不发生扩容;当剩余容量小于 additional 时,扩容至当前容量的 1.5 倍(向下取整)与 size + additional 的最大值。
参数:
- additional: Int64 - 指定 StringBuilder 的扩容大小。
func reset(Option<Int64>)
public func reset(capacity!: Option<Int64> = None): Unit
功能:清空当前 StringBuilder,并将容量重置为 capacity 指定的值。
参数:
- capacity!: Option<Int64> - 重置后 StringBuilder 实例的容量大小,取值范围为
None和 (Some(0),Some(Int64.Max)],默认值None表示采用默认大小容量(32)。
异常:
- IllegalArgumentException - 当参数
capacity的值小于等于 0 时,抛出异常。
func toString()
public func toString(): String
功能:获取 StringBuilder 实例中的字符串。
注意:
该函数不会将字符串数据进行拷贝。
返回值:
- String - StringBuilder 实例中的字符串。
class Thread
public class Thread
功能:获取线程 ID 及名字、查询线程是否存在取消请求、注册线程未处理异常的处理函数等。
该类型实例无法通过构造得到,仅能通过 Future 对象的 thread 属性或是 Thread 类的 currentThread 静态属性获取。
static prop currentThread
public static prop currentThread: Thread
功能:获取当前执行线程的 Thread 对象。
类型:Thread
prop hasPendingCancellation
public prop hasPendingCancellation: Bool
功能:线程是否存在取消请求,即是否通过 future.cancel() 发送过取消请求,常见使用方为 Thread.currentThread.hasPendingCancellation。
类型:Bool
prop id
public prop id: Int64
功能:获取当前执行线程的标识,以 Int64 表示,所有存活的线程都有不同标识,但不保证当线程执行结束后复用它的标识。
类型:Int64
prop name
public mut prop name: String
功能:获取或设置线程的名称,获取设置都具有原子性。
类型:String
static func handleUncaughtExceptionBy((Thread, Exception) -> Unit)
public static func handleUncaughtExceptionBy(exHandler: (Thread, Exception) -> Unit): Unit
功能:注册线程未处理异常的处理函数。
当某一线程因异常而提前终止后,如果全局的未处理异常函数被注册,那么将调用该函数并结束线程,在该函数内抛出异常时,将向终端打印提示信息并结束线程,但不会打印异常调用栈信息;如果没有注册全局异常处理函数,那么默认会向终端打印异常调用栈信息。
多次注册处理函数时,后续的注册函数将覆盖之前的处理函数。
当有多个线程同时因异常而终止时,处理函数将被并发执行,因而开发者需要在处理函数中确保并发正确性。
处理函数的参数第一个参数类型为 Thread,是发生异常的线程,第二个参数类型为 Exception,是线程未处理的异常。
参数:
class ThreadLocal<T>
public class ThreadLocal<T>
功能:该类表示仓颉线程局部变量。
和普通变量相比,线程局部变量有不同的访问语义。当多个线程共享使用同一线程局部变量时,每个线程都有各自的一份值拷贝。线程对变量的访问会读写线程本地的值,而不会影响其他线程中变量的值。
func get()
public func get(): ?T
功能:获得仓颉线程局部变量的值。
返回值:
- ?T - 如果当前线程局部变量不为空值,返回该值,如果为空值,返回
None。
func set(?T)
public func set(value: ?T): Unit
功能:通过 value 设置仓颉线程局部变量的值,如果传入 None,该局部变量的值将被删除,在线程后续操作中将无法获取。
参数:
- value: ?T - 需要设置的局部变量的值。
枚举
enum AnnotationKind
public enum AnnotationKind {
| Type
| Parameter
| Init
| MemberProperty
| MemberFunction
| MemberVariable
| EnumConstructor
| GlobalFunction
| GlobalVariable
| Extension
| ...
}
功能:表示自定义注解希望支持的位置。
EnumConstructor
EnumConstructor
功能:枚举构造器声明。
Extension
Extension
功能:扩展声明。
Init
Init
功能:构造函数声明。
GlobalFunction
GlobalFunction
功能:全局函数声明。
GlobalVariable
GlobalVariable
功能:全局变量声明。
MemberFunction
MemberFunction
功能:成员函数声明。
MemberProperty
MemberProperty
功能:成员属性声明。
MemberVariable
MemberVariable
功能:成员变量声明。
Parameter
Parameter
功能:成员函数/构造函数中的参数(不包括枚举构造器的参数)。
Type
Type
功能:类型声明(class、struct、enum、interface)。
enum Endian
public enum Endian {
| Big
| Little
}
功能:枚举类型 Endian 表示运行平台的端序,分为大端序和小端序。
Big
Big
功能:表示大端序。
Little
Little
功能:表示小端序。
static prop Platform
public static prop Platform: Endian
功能:获取所在运行平台的端序。
类型:Endian
异常:
- UnsupportedException - 当所运行平台返回的端序无法识别时,抛出异常。
示例:
main() {
let e = Endian.Platform
match (e) {
case Big => println("BigEndian")
case Little => println("LittleEndian")
}
}
运行结果:
LittleEndian
enum Option<T>
public enum Option<T> {
| Some(T)
| None
}
功能:Option<T> 是对 T 类型的封装,表示可能有值也可能无值。
它包含两个构造器:Some 和 None。其中,Some 会携带一个参数,表示有值;None 不带参数,表示无值。当需要表示某个类型可能有值,也可能没有值的时候,可选择使用 Option 类型。
Option 类型的另一种写法是在类型名前加 ?,即对于任意类型 Type,?Type 等价于 Option<Type>。
None
None
功能:构造一个不带参数的 Option<T> 实例,表示无值。
Some(T)
Some(T)
功能:构造一个携带参数的 Option<T> 实例,表示有值。
func filter((T)->Bool)
public func filter(predicate: (T) -> Bool): Option<T>
功能:提供 Option 类型的“过滤”功能。
参数:
- predicate: (T) -> Bool - 过滤函数。
返回值:
func flatMap<R>((T) -> Option<R>)
public func flatMap<R>(transform: (T) -> Option<R>): Option<R>
功能:提供从 Option<T> 类型到 Option<R> 类型的映射函数,如果当前实例值是 Some,执行 transform 函数,并且返回结果,否则返回 None。
参数:
- transform: (T) -> Option<R> - 映射函数。
返回值:
func getOrDefault(() -> T)
public func getOrDefault(other: () -> T): T
功能:获得值或返回默认值。如果 Option 值是 Some,则返回类型为 T 的实例,如果 Option 值是 None,则调用入参,返回类型 T 的值。
参数:
- other: () -> T - 默认函数,如果当前实例的值是 None,调用该函数得到类型为
T的实例,并将其返回。
返回值:
示例:
main() {
var value1: Option<Int64> = Some(2)
println(value1.getOrDefault({=> 0}))
var value2: Option<Int64> = None
println(value2.getOrDefault({=> 0}))
}
运行结果:
2
0
func getOrThrow(() -> Exception)
public func getOrThrow(exception: ()->Exception): T
功能:获得值或抛出指定异常。
参数:
返回值:
- T - 如果当前实例值是 Some<T>,返回类型为
T的实例。
异常:
func getOrThrow()
public func getOrThrow(): T
功能:获得值或抛出异常。
返回值:
- T - 如果当前实例值是 Some<T>,返回类型为
T的实例。
异常:
- NoneValueException - 如果当前实例是 None,抛出异常。
func isNone()
public func isNone(): Bool
功能:判断当前实例值是否为 None。
返回值:
func isSome()
public func isSome(): Bool
功能:判断当前实例值是否为 Some。
返回值:
func map<R>((T)->R)
public func map<R>(transform: (T)-> R): Option<R>
功能:提供从 Option<T> 类型到 Option<R> 类型的映射函数,如果当前实例值是 Some,执行 transform 函数,并且返回 Some 封装的结果,否则返回 None。
参数:
- transform: (T)-> R - 映射函数。
返回值:
extend<T> Option<T> <: Equatable<Option<T>> where T <: Equatable<T>
extend<T> Option<T> <: Equatable<Option<T>> where T <: Equatable<T>
功能:为 Option<T> 枚举扩展 Equatable<Option<T>> 接口,支持判等操作。
父类型:
operator func !=(Option<T>)
public operator func !=(that: Option<T>): Bool
功能:判断当前实例与参数指向的 Option<T> 实例是否不等。
参数:
返回值:
- Bool - 如果不相等,则返回 true,否则返回 false。
operator func ==(Option<T>)
public operator func ==(that: Option<T>): Bool
功能:判断当前实例与参数指向的 Option<T> 实例是否相等。
如果两者同为 None,则相等;如果两者为 Some(v1) 和 Some(v2),且 v1 和 v2 相等,则相等。
参数:
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
extend<T> Option<T> <: Hashable where T <: Hashable
extend<T> Option<T> <: Hashable where T <: Hashable
Some<T> 的哈希值等于 T 的值对应的哈希值,None 的哈希值等于 Int64(0)。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值。
返回值:
- Int64 - 哈希值。
extend<T> Option<T> <: ToString where T <: ToString
extend<T> Option<T> <: ToString where T <: ToString
功能:为 Option<T> 枚举实现 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将 Option 转换为可输出的字符串,字符串内容为 "Some(${T.toString()})" 或 "None"。
返回值:
- String - 转化后的字符串。
extend<T> Option<Option<T>>
extend<T> Option<Option<T>>
功能:为 Option<Option<T>> 类型扩展实现某些功能。
func flatten()
public func flatten(): Option<T>
功能:将 Option<Option<T>> 类型展开,如果当前实例是 Some(Option<T>.Some(v)), 展开后的结果为 Some(v)。
返回值:
enum Ordering
public enum Ordering {
| LT
| GT
| EQ
}
功能:Ordering 表示比较大小的结果,它包含三种情况:小于,大于和等于。
EQ
EQ
功能:构造一个 Ordering 实例,表示等于。
GT
GT
功能:构造一个 Ordering 实例,表示大于。
LT
LT
功能:构造一个 Ordering 实例,表示小于。
extend Ordering <: Comparable
extend Ordering <: Comparable<Ordering>
功能:为 Ordering 类型其扩展 Comparable<Ordering> 接口,支持比较操作。
父类型:
func compare(Ordering)
public func compare(that: Ordering): Ordering
功能:判断当前 Ordering 实例与参数指定的 Ordering 实例的大小关系。
Ordering 枚举的大小关系为:GT > EQ > LT。
参数:
返回值:
- Ordering - 如果大于,返回 GT;如果等于,返回 EQ;如果小于,返回 LT。
extend Ordering <: Hashable
extend Ordering <: Hashable
功能:为 Ordering 类型其扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode
public func hashCode(): Int64
功能:获取哈希值,GT 的哈希值是 3,EQ 的哈希值是 2,LT 的哈希值是 1。
返回值:
- Int64 - 哈希值。
extend Ordering <: ToString
extend Ordering <: ToString
功能:为 Ordering 类型其扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将 Ordering 转换为可输出的字符串。
转换结果如下:
返回值:
- String - 转化后的字符串。
结构体
struct Array<T>
public struct Array<T> {
public const init()
public init(size: Int64, repeat!: T)
public init(size: Int64, initElement: (Int64) -> T)
}
功能:仓颉数组类型,用来表示单一类型的元素构成的有序序列。
T 表示数组的元素类型,T 可以是任意类型。
prop first
public prop first: Option<T>
功能:获取当前数组的第一个元素,如果当前数组为空,返回 None。
类型:Option<T>
prop last
public prop last: Option<T>
功能:获取当前数组的最后一个元素,如果当前数组为空,返回 None。
类型:Option<T>
init()
public const init()
功能:构造一个空数组。
init(Int64, (Int64) -> T)
public init(size: Int64, initElement: (Int64) -> T)
功能:创建指定长度的数组,其中元素根据初始化函数计算获取。
即:将 [0, size) 范围内的值分别传入初始化函数 initElement,执行得到数组对应下标的元素。
参数:
异常:
- NegativeArraySizeException - 当 size 小于 0,抛出异常。
init(Int64, T)
public init(size: Int64, repeat!: T)
功能:构造一个指定长度的数组,其中元素都用指定初始值进行初始化。
注意:
该构造函数不会拷贝 repeat, 如果 repeat 是一个引用类型,构造后数组的每一个元素都将指向相同的引用。
参数:
异常:
- NegativeArraySizeException - 当 size 小于 0,抛出异常。
func clone()
public func clone(): Array<T>
功能:克隆数组,将对数组数据进行深拷贝。
返回值:
- Array<T> - 克隆得到的新数组。
func clone(Range<Int64>)
public func clone(range: Range<Int64>) : Array<T>
功能:克隆数组的指定区间。
注意:
参数:
返回值:
- Array<T> - 克隆得到的新数组。
异常:
- IndexOutOfBoundsException - range 超出数组范围时,抛出异常。
示例:
main() {
let arr = [0, 1, 2, 3, 4, 5]
let new = arr.clone(1..4)
println(new)
}
运行结果:
[1, 2, 3]
func concat(Array<T>)
public func concat(other: Array<T>): Array<T>
功能:该函数将创建一个新的数组,数组内容是当前数组后面串联 other 指向的数组。
参数:
- other: Array<T> - 串联到当前数组末尾的数组。
返回值:
- Array<T> - 串联得到的新数组。
示例:
main() {
let arr = [0, 1, 2, 3, 4, 5]
let new = arr.concat([6, 7, 8, 9, 10])
println(new)
}
运行结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
func copyTo(Array<T>)
public func copyTo(dst: Array<T>): Unit
功能:将当前数组的全部元素拷贝到目标数组 dst 中。
拷贝长度为当前数组的长度,从目标数组的起始位置开始写入,要求当前数组的长度不大于目标数组的长度。
参数:
- dst: Array<T> - 目标数组。
异常:
- IllegalArgumentException - 当前数组的长度大于目标数组的长度。
func copyTo(Array<T>, Int64, Int64, Int64)
public func copyTo(dst: Array<T>, srcStart: Int64, dstStart: Int64, copyLen: Int64): Unit
功能:将当前数组中的一段数据拷贝到目标数组中。
参数:
- dst: Array<T> - 目标数组。
- srcStart: Int64 - 从 this 数组的 srcStart 下标开始拷贝,取值范围为 [0, this.size)。
- dstStart: Int64 - 从目标数组的 dstStart 下标开始写入,取值范围为 [0, dst.size)。
- copyLen: Int64 - 拷贝数组的长度,取值要求为 copyLen + srcStart < this.size,copyLen + dstStart < dst.size。
异常:
- IllegalArgumentException - copyLen 小于 0 则抛出此异常。
- IndexOutOfBoundsException - 如果参数不满足上述取值范围,抛出此异常。
示例:
main() {
let arr = [0, 1, 2, 3, 4, 5]
let new = [0, 0, 0, 0, 0, 0]
arr.copyTo(new, 2, 2, 4)
println(new)
}
运行结果:
[0, 0, 2, 3, 4, 5]
func fill(T)
public func fill(value: T): Unit
功能:将当前数组内所有元素都替换成指定的 value。
参数:
- value: T - 修改的目标值。
示例:
main() {
let arr = [0, 1, 2]
arr[1..3].fill(-1)
println(arr)
}
运行结果:
[0, -1, -1]
func get(Int64)
public func get(index: Int64): Option<T>
功能:获取数组中下标 index 对应的元素。
该函数结果将用 Option 封装,如果 index 越界,将返回 None。
也可以通过 [] 操作符获取数组指定下标的元素,该接口将在 index 越界时抛出异常。
参数:
- index: Int64 - 要获取的值的下标。
返回值:
- Option<T> - 当前数组中下标 index 对应的值。
示例:
main() {
let arr = [0, 1, 2]
let num = arr.get(0)
println(num)
}
运行结果:
Some(0)
func map<R>((T)->R)
public func map<R>(transform: (T)->R): Array<R>
功能:将当前数组内所有 T 类型元素根据 transform 映射为 R 类型的元素,组成新的数组。
参数:
- transform: (T)->R - 映射函数。
返回值:
- Array<R> - 原数组中所有元素映射后得到的元素组成的新数组。
示例:
main(): Int64 {
let arr = [0, 1, 2]
let arr1 = arr.map({value => value + 1})
println(arr1)
return 0
}
运行结果:
[1, 2, 3]
func repeat(Int64)
public func repeat(n: Int64): Array<T>
功能:重复当前数组若干次,得到新数组。
参数:
- n: Int64 - 重复次数。
返回值:
- Array<T> - 重复当前数组 n 次得到的新数组。
异常:
- IllegalArgumentException - 参数 n 小于等于 0。
示例:
main(): Int64 {
let arr = [0, 1, 2]
var arr1 = arr.repeat(2)
println(arr1)
return 0
}
运行结果:
[0, 1, 2, 0, 1, 2]
func reverse()
public func reverse(): Unit
功能:反转数组,将数组中元素的顺序进行反转。
示例:
main() {
let arr = [0, 1, 2, 3, 4, 5]
arr.reverse()
println(arr)
}
运行结果:
[5, 4, 3, 2, 1, 0]
func slice(Int64, Int64)
public func slice(start: Int64, len: Int64): Array<T>
功能:获取数组切片。
注意:
切片不会对数组数据进行拷贝,是对原数据特定区间的引用。
参数:
返回值:
- Array<T> - 返回切片后的数组。
异常:
- IndexOutOfBoundsException - 如果参数不符合上述取值范围,抛出异常。
示例:
class Rectangle <: ToString {
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func toString(): String {
return "width: ${this.width}, height: ${this.height}"
}
}
main(): Int64 {
let arr = [Rectangle(1, 2), Rectangle(3, 4), Rectangle(5, 6)]
let arr1 = arr.slice(1, 2)
println(arr1)
/* 由于 slice() 是对原数组的引用,在新数组上修改,原数组引用类型的元素也会变化 */
arr1[0].width = 5
println(arr)
return 0
}
运行结果:
[width: 3, height: 4, width: 5, height: 6]
[width: 1, height: 2, width: 5, height: 4, width: 5, height: 6]
func splitAt(Int64)
public func splitAt(mid: Int64): (Array<T>, Array<T>)
功能:从指定位置 mid 处分割数组。
得到的两个数组是原数组的切片,取值范围为 [0, mid), [mid, this.size)。
参数:
- mid: Int64 - 分割的位置,取值范围为 [0, this.size]。
返回值:
异常:
- IllegalArgumentException - mid 小于 0 或大于 this.size。
func swap(Int64, Int64)
public func swap(index1: Int64, index2: Int64): Unit
功能:交换指定位置的两个元素。
如果 index1 和 index2 指向同一个位置,将不做交换。
参数:
- index1: Int64 - 需要交换的两个元素的下标之一,取值范围为 [0, this.size)。
- index2: Int64 - 需要交换的两个元素的下标之一,取值范围为 [0, this.size)。
异常:
- IllegalArgumentException - index1 / index2 小于 0 或大于等于 this.size。
示例:
main(): Int64 {
let arr = [1, 2, 3, 4]
arr.swap(1, 2)
println(arr)
return 0
}
运行结果:
[1, 3, 2, 4]
operator func [](Int64)
public operator func [](index: Int64): T
功能:获取数组下标 index 对应的值。
该函数中如果 index 越界,将抛出异常。
也可以通过 get 函数获取数组指定下标的元素,get 函数将在 index 越界时返回 None。
参数:
返回值:
- T - 数组中下标 index 对应的值。
异常:
- IndexOutOfBoundsException - 如果 index 小于 0,或大于等于数组长度,抛出异常。
operator func [](Int64, T)
public operator func [](index: Int64, value!: T): Unit
功能:修改数组中下标 index 对应的值。
参数:
异常:
- IndexOutOfBoundsException - 如果 index 小于 0,或大于等于数组长度,抛出异常。
operator func [](Range<Int64>)
public operator func [](range: Range<Int64>): Array<T>
功能:根据给定区间获取数组切片。
注意:
参数:
返回值:
- Array<T> - 数组切片。
异常:
- IllegalArgumentException - 如果 range 的步长不等于 1,抛出异常。
- IndexOutOfBoundsException - 如果 range 表示的数组范围无效,抛出异常。
示例:
main() {
let arr = [0, 1, 2, 3, 4, 5]
let slice = arr[1..4]
arr[3] = 10
println(slice)
}
运行结果:
[1, 2, 10]
operator func [](Range<Int64>, Array<T>)
public operator func [](range: Range<Int64>, value!: Array<T>): Unit
功能:用指定的数组对本数组一个连续范围的元素赋值。
range 表示的区见的长度和目标数组 value 的大小需相等。
注意:
参数:
异常:
- IllegalArgumentException - 如果 range 的步长不等于 1,或 range 长度不等于 value 长度,抛出异常。
- IndexOutOfBoundsException - 如果 range 表示的数组范围无效,抛出异常。
示例:
main() {
let arr = [0, 1, 2, 3, 4, 5]
arr[1..3] = [10, 11]
println(arr)
}
运行结果:
[0, 10, 11, 3, 4, 5]
extend<T> Array<T> <: Collection<T>
extend<T> Array<T> <: Collection<T>
功能:为 Array<T> 类型实现 Collection 接口。
父类型:
- Collection<T>
prop size
public prop size: Int64
功能:获取元素数量。
类型:Int64
func isEmpty()
public func isEmpty(): Bool
功能:判断数组是否为空。
返回值:
- Bool - 如果数组为空,返回 true,否则,返回 false。
func iterator()
public func iterator(): Iterator<T>
功能:获取当前数组的迭代器,用于遍历数组。
返回值:
- Iterator<T> - 当前数组的迭代器。
func toArray()
public func toArray(): Array<T>
功能:根据当前 Array 实例拷贝一个新的 Array 实例。
返回值:
extend<T> Array<T> <: Equatable<Array<T>> where T <: Equatable<T>
extend<T> Array<T> <: Equatable<Array<T>> where T <: Equatable<T>
功能:为 Array<T> 类型扩展 Equatable<Array<T>> 接口实现,支持判等操作。
父类型:
func contains(T)
public func contains(element: T): Bool
功能:查找当前数组是否包含指定元素。
参数:
- element: T - 需要查找的目标元素。
返回值:
- Bool - 如果存在,则返回 true,否则返回 false。
示例:
main(): Int64 {
let arr = [1, 2, 3, 4]
println(arr.contains(1))
return 0
}
运行结果:
true
func indexOf(Array<T>)
public func indexOf(elements: Array<T>): Option<Int64>
功能:返回数组中子数组 elements 出现的第一个位置,如果数组中不包含此数组,返回 None。
注意:
当 T 的类型是 Int64 时,此函数的变长参数语法糖版本可能会和
public func indexOf(element: T, fromIndex: Int64): Option<Int64>产生歧义,根据优先级,当参数数量是 2 个时,会优先调用public func indexOf(element: T, fromIndex: Int64): Option<Int64>。
参数:
- elements: Array<T> - 需要定位的目标数组。
返回值:
示例:
main(): Int64 {
let arr = [1, 2, 3, 4]
let subArr = [2, 3]
println(arr.indexOf(subArr))
return 0
}
运行结果:
Some(1)
func indexOf(Array<T>, Int64)
public func indexOf(elements: Array<T>, fromIndex: Int64): Option<Int64>
功能:返回数组中在 fromIndex之后,子数组elements 出现的第一个位置,未找到返回 None。
函数会对 fromIndex 范围进行检查,fromIndex 小于 0 时,将会从第 0 位开始搜索,当 fromIndex 大于等于本数组的大小时,结果为 None。
参数:
返回值:
示例:
main(): Int64 {
let arr = [1, 2, 3, 4, 2, 3]
let subArr = [2, 3]
println(arr.indexOf(subArr, 3))
return 0
}
运行结果:
Some(4)
func indexOf(T)
public func indexOf(element: T): Option<Int64>
功能:获取数组中 element 出现的第一个位置,如果数组中不包含此元素,返回 None。
参数:
- element: T - 需要定位的元素。
返回值:
func indexOf(T, Int64)
public func indexOf(element: T, fromIndex: Int64): Option<Int64>
功能:返回数组中在 fromIndex之后, element 出现的第一个位置,未找到返回 None。
函数会从下标 fromIndex 开始查找,fromIndex 小于 0 时,将会从第 0 位开始搜索,当 fromIndex 大于等于本数组的大小时,结果为 None。
参数:
- element: T - 需要定位的元素。
- fromIndex: Int64 - 查找的起始位置。
返回值:
示例:
main(): Int64 {
let arr = [1, 2, 3, 4, 2, 3]
let subArr = [2, 3]
println(arr.lastIndexOf(subArr, 3))
return 0
}
运行结果:
Some(4)
func lastIndexOf(Array<T>)
public func lastIndexOf(elements: Array<T>): Option<Int64>
功能:返回数组中子数组 elements 出现的最后一个位置,如果数组中不存在此子数组,返回 None。
参数:
- elements: Array<T> - 需要定位的目标数组。
返回值:
func lastIndexOf(Array<T>, Int64)
public func lastIndexOf(elements: Array<T>, fromIndex: Int64): Option<Int64>
功能:从 fromIndex 开始向后搜索,返回数组中子数组 elements 出现的最后一个位置,如果数组中不存在此子数组,返回 None。
函数会对 fromIndex 范围进行检查,fromIndex 小于 0 时,将会从第 0 位开始搜索,当 fromIndex 大于等于本数组的大小时,结果为 None。
参数:
返回值:
func lastIndexOf(T)
public func lastIndexOf(element: T): Option<Int64>
功能:返回数组中 element 出现的最后一个位置,如果数组中不存在此元素,返回 None。
参数:
- element: T - 需要定位的目标元素。
返回值:
func lastIndexOf(T, Int64)
public func lastIndexOf(element: T, fromIndex: Int64): Option<Int64>
功能:从 fromIndex 开始向后搜索,返回数组中 element 出现的最后一个位置,如果数组中不存在此元素,返回 None。
函数会对 fromIndex 范围进行检查,fromIndex 小于 0 时,将会从第 0 位开始搜索,当 fromIndex 大于等于本数组的大小时,结果为 None。
参数:
- element: T - 需要定位的目标元素。
- fromIndex: Int64 - 搜索开始的位置。
返回值:
func removePrefix(Array<T>)
public func removePrefix(prefix: Array<T>): Array<T>
功能:删除前缀。
如果当前数组开头与 prefix 完全匹配,删除其前缀。返回值为当前数组删除前缀后得到的切片。
参数:
- prefix: Array<T> - 待删除的前缀。
返回值:
- Array<T> - 删除前缀后得到的原数组切片。
示例:
main(): Int64 {
let arr = [1, 2, 1, 2, 3].removePrefix([1, 2])
println(arr)
return 0
}
运行结果:
[1, 2, 3]
func removeSuffix(Array<T>)
public func removeSuffix(suffix: Array<T>): Array<T>
功能:删除后缀。
如果当前数组结尾与 suffix 完全匹配,删除其后缀。返回值为当前数组删除后缀后得到的切片。
参数:
- suffix: Array<T> - 待删除的后缀。
返回值:
- Array<T> - 删除后缀后得到的原数组切片。
示例:
main(): Int64 {
let arr = [1, 2, 3, 2, 3].removeSuffix([2, 3])
println(arr)
return 0
}
运行结果:
[1, 2, 3]
func trimEnd(Array<T>)
public func trimEnd(set: Array<T>): Array<T>
功能:修剪当前数组,从尾开始删除在指定集合 set 中的元素,直到第一个不在 set 中的元素为止,并返回当前数组的切片。
参数:
- set: Array<T> - 待删除的元素的集合。
返回值:
- Array<T> - 修剪后的数组切片。
示例:
main(): Int64 {
let arr = [2, 1, 2, 2, 3].trimEnd([2, 3])
println(arr)
return 0
}
运行结果:
[2, 1]
func trimEnd((T)->Bool)
public func trimEnd(predicate: (T)->Bool): Array<T>
功能:修剪当前数组,从尾开始删除符合过滤条件的函数,直到第一个不符合的元素为止,并返回当前数组的切片。
参数:
- predicate: (T)->Bool - 过滤条件。
返回值:
- Array<T> - 修剪后的数组切片。
func trimStart(Array<T>)
public func trimStart(set: Array<T>): Array<T>
功能:修剪当前数组,从头开始删除在指定集合 set 中的元素,直到第一个不在 set 中的元素为止,并返回当前数组的切片。
参数:
- set: Array<T> - 待删除的元素的集合。
返回值:
- Array<T> - 修剪后的数组切片。
示例:
main(): Int64 {
let arr = [1, 2, 1, 3, 1].trimStart([1, 2])
println(arr)
return 0
}
运行结果:
[3, 1]
func trimStart((T)->Bool)
public func trimStart(predicate: (T)->Bool): Array<T>
功能:修剪当前数组,从头开始删除符合过滤条件的函数,直到第一个不符合的元素为止,并返回当前数组的切片。
参数:
- predicate: (T)->Bool - 过滤条件。
返回值:
- Array<T> - 修剪后的数组切片。
operator func !=(Array<T>)
public operator const func !=(that: Array<T>): Bool
功能:判断当前实例与指定 Array<T> 实例是否不等。
参数:
返回值:
- Bool - 如果不相等,则返回 true;相等则返回 false。
operator func ==(Array<T>)
public operator const func ==(that: Array<T>): Bool
功能:判断当前实例与指定 Array<T> 实例是否相等。
两个 Array<T> 相等指的是其中的每个元素都相等。
参数:
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
extend<T> Array<T> where T <: ToString
extend<T> Array<T> <: ToString where T <: ToString
功能:为 Array<T> 类型扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将数组转换为可输出的字符串。
字符串形如 "[1, 2, 3, 4, 5]"
返回值:
- String - 转化后的字符串。
extend<T> Array<Array<T>>
extend<T> Array<Array<T>>
功能:为二维数组进行扩展,提供将其展开为一维数组的方法。
func flatten()
public func flatten(): Array<T>
功能:将当前二维数组展开为一维数组。
例如将 [[1, 2], [3, 4]] 展开为 [1, 2, 3, 4]。
返回值:
- Array<T> - 展开后的一维数组。
示例:
main(): Int64 {
let arr = [[1, 2], [3, 4]].flatten()
println(arr)
return 0
}
运行结果:
[1, 2, 3, 4]
struct CPointerHandle<T> where T <: CType
public struct CPointerHandle<T> where T <: CType {
public let array: Array<T>
public let pointer: CPointer<T>
public init()
public init(ptr: CPointer<T>, arr: Array<T>)
}
功能:表示 Array 数组的原始指针,该类型中的泛型参数应该满足 CType 约束。
let array
public let array: Array<T>
功能:原始指针对应的 Array 数组实例。
类型:Array<T>
let pointer
public let pointer: CPointer<T>
功能:获取指定 Array 数组对应的原始指针。
类型:CPointer<T>
init() (deprecated)
public init()
功能:构造一个默认 CPointerHandle 实例,其中原始指针为空指针,仓颉数组为空数组。
注意:
未来版本即将废弃不再使用,可使用 acquireArrayRawData 函数构造 CPointerHandle 实例。
init(CPointer<T>, Array<T>) (deprecated)
public init(ptr: CPointer<T>, arr: Array<T>)
功能:通过传入的 CPointer 和 Array 初始化一个 CPointerHandle。
参数:
注意:
未来版本即将废弃不再使用,可使用 acquireArrayRawData 函数构造 CPointerHandle 实例。
struct CPointerResource<T> where T <: CType
public struct CPointerResource<T> <: Resource where T <: CType {
public let value: CPointer<T>
}
功能:该结构体表示 CPointer 对应的资源管理类型,其实例可以通过 CPointer 的成员函数 asResource 获取。
父类型:
let value
public let value: CPointer<T>
功能:表示当前实例管理的 CPointer<T> 类型实例。
类型:CPointer<T>
func close()
public func close(): Unit
功能:释放其管理的 CPointer<T> 实例指向的内容。
func isClosed()
public func isClosed(): Bool
功能:判断该指针内容是否已被释放。
返回值:
- Bool - 返回 true 为已释放。
struct CStringResource
public struct CStringResource <: Resource {
public let value: CString
}
功能:该结构体表示 CString 对应的资源管理类型,其实例可以通过 CString 的成员函数 asResource 获取。
父类型:
let value
public let value: CString
功能:表示当前实例管理的 CString 资源。
类型:CString
func close()
public func close(): Unit
功能:释放当前实例管理的 CString 类型实例指向的内容。
func isClosed()
public func isClosed(): Bool
功能:判断该字符串是否被释放。
返回值:
- Bool - 返回 true 为已释放。
struct DefaultHasher
public struct DefaultHasher <: Hasher {
public init(res!: Int64 = 0)
}
功能:该结构体提供了默认哈希算法实现。
可以使用一系列 write 函数传入不同数据类型实例,并计算它们的组合哈希值。
父类型:
init(Int64)
public init(res!: Int64 = 0)
功能:构造函数,创建一个 DefaultHasher。
参数:
- res!: Int64 - 初始哈希值,默认为 0。
func finish()
public func finish(): Int64
功能:获取哈希运算的结果。
返回值:
- Int64 - 哈希运算的结果。
func reset()
public mut func reset(): Unit
功能:重置哈希值为 0。
func write(Bool)
public mut func write(value: Bool): Unit
功能:通过该函数把想要哈希运算的 Bool 值传入,然后进行哈希组合运算。
参数:
- value: Bool - 待运算的值。
func write(Float16)
public mut func write(value: Float16): Unit
功能:通过该函数把想要哈希运算的 Float16 值传入,然后进行哈希组合运算。
参数:
- value: Float16 - 待运算的值。
func write(Float32)
public mut func write(value: Float32): Unit
功能:通过该函数把想要哈希运算的 Float32 值传入,然后进行哈希组合运算。
参数:
- value: Float32 - 待运算的值。
func write(Float64)
public mut func write(value: Float64): Unit
功能:通过该函数把想要哈希运算的 Float64 值传入,然后进行哈希组合运算。
参数:
- value: Float64 - 待运算的值。
func write(Int16)
public mut func write(value: Int16): Unit
功能:通过该函数把想要哈希运算的 Int16 值传入,然后进行哈希组合运算。
参数:
- value: Int16 - 待运算的值。
func write(Int32)
public mut func write(value: Int32): Unit
功能:通过该函数把想要哈希运算的 Int32 值传入,然后进行哈希组合运算。
参数:
- value: Int32 - 待运算的值。
func write(Int64)
public mut func write(value: Int64): Unit
功能:通过该函数把想要哈希运算的 Int64 值传入,然后进行哈希组合运算。
参数:
- value: Int64 - 待运算的值。
func write(Int8)
public mut func write(value: Int8): Unit
功能:通过该函数把想要哈希运算的 Int8 值传入,然后进行哈希组合运算。
参数:
- value: Int8 - 待运算的值。
func write(Rune)
public mut func write(value: Rune): Unit
功能:通过该函数把想要哈希运算的 Rune 值传入,然后进行哈希组合运算。
参数:
- value: Rune - 待运算的值。
func write(String)
public mut func write(value: String): Unit
功能:通过该函数把想要哈希运算的 String 值传入,然后进行哈希组合运算。
参数:
- value: String - 待运算的值。
func write(UInt16)
public mut func write(value: UInt16): Unit
功能:通过该函数把想要哈希运算的 UInt16 值传入,然后进行哈希组合运算。
参数:
- value: UInt16 - 待运算的值。
func write(UInt32)
public mut func write(value: UInt32): Unit
功能:通过该函数把想要哈希运算的 UInt32 值传入,然后进行哈希组合运算。
参数:
- value: UInt32 - 待运算的值。
func write(UInt64)
public mut func write(value: UInt64): Unit
功能:通过该函数把想要哈希运算的 UInt64 值传入,然后进行哈希组合运算。
参数:
- value: UInt64 - 待运算的值。
func write(UInt8)
public mut func write(value: UInt8): Unit
功能:通过该函数把想要哈希运算的 UInt8 值传入,然后进行哈希组合运算。
参数:
- value: UInt8 - 待运算的值。
struct Duration
public struct Duration <: ToString & Hashable & Comparable<Duration> {
public static const Max: Duration = Duration(0x7FFF_FFFF_FFFF_FFFF, 999999999)
public static const Min: Duration = Duration(-0x8000_0000_0000_0000, 0)
public static const Zero: Duration = Duration(0, 0)
public static const day: Duration = Duration(24 * 60 * 60, 0)
public static const hour: Duration = Duration(60 * 60, 0)
public static const microsecond: Duration = Duration(0, 1000u32)
public static const millisecond: Duration = Duration(0, 1000000u32)
public static const minute: Duration = Duration(60, 0)
public static const nanosecond: Duration = Duration(0, 1)
public static const second: Duration = Duration(1, 0)
}
功能:Duration 表示时间间隔,是一个描述一段时间的时间类型,提供了常用的静态实例,以及计算、比较等功能。
说明:
父类型:
static const Max
public static const Max: Duration = Duration(0x7FFF_FFFF_FFFF_FFFF, 999999999)
功能:表示最大时间间隔的 Duration 实例。
类型:Duration
static const Min
public static const Min: Duration = Duration(-0x8000_0000_0000_0000, 0)
功能:表示最小时间间隔的 Duration 实例。
类型:Duration
static const Zero
public static const Zero: Duration = Duration(0, 0)
功能:表示 0 纳秒时间间隔的 Duration 实例。
类型:Duration
static const day
public static const day: Duration = Duration(24 * 60 * 60, 0)
功能:表示 1 天时间间隔的 Duration 实例。
类型:Duration
static const hour
public static const hour: Duration = Duration(60 * 60, 0)
功能:表示 1 小时时间间隔的 Duration 实例。
类型:Duration
static const microsecond
public static const microsecond: Duration = Duration(0, 1000u32)
功能:表示 1 微秒时间间隔的 Duration 实例。
类型:Duration
static const millisecond
public static const millisecond: Duration = Duration(0, 1000000u32)
功能:表示 1 毫秒时间间隔的 Duration 实例。
类型:Duration
static const minute
public static const minute: Duration = Duration(60, 0)
功能:表示 1 分钟时间间隔的 Duration 实例。
类型:Duration
static const nanosecond
public static const nanosecond: Duration = Duration(0, 1)
功能:表示 1 纳秒时间间隔的 Duration 实例。
类型:Duration
static const second
public static const second: Duration = Duration(1, 0)
功能:表示 1 秒时间间隔的 Duration 实例。
类型:Duration
func abs()
public func abs(): Duration
功能:返回一个新的 Duration 实例,其值大小为当前 Duration 实例绝对值。
返回值:
异常:
- ArithmeticException - 如果当前 Duration 实例等于 Duration.Min,会因为取绝对值超出 Duration 表示范围而抛出异常。
func compare(Duration)
public func compare(rhs: Duration): Ordering
功能:比较当前 Duration 实例与另一个 Duration 实例的关系,如果大于,返回 Ordering.GT;如果等于,返回 Ordering.EQ;如果小于,返回 Ordering.LT。
参数:
返回值:
func hashCode()
public func hashCode(): Int64
功能:获得当前 Duration 实例的哈希值。
返回值:
func toDays()
public func toDays(): Int64
功能:获得当前 Duration 实例以天为单位的整数大小。
返回值:
func toHours()
public func toHours(): Int64
功能:获得当前 Duration 实例以小时为单位的整数大小。
返回值:
func toMicroseconds()
public func toMicroseconds(): Int64
功能:获得当前 Duration 实例以微秒为单位的整数大小。
返回值:
异常:
- ArithmeticException - 当 Duration 实例以微秒为单位的大小超过 Int64 表示范围时,抛出异常。
func toMilliseconds()
public func toMilliseconds(): Int64
功能:获得当前 Duration 实例以毫秒为单位的整数大小。
返回值:
异常:
- ArithmeticException - 当 Duration 实例以毫秒为单位的大小超过 Int64 表示范围时,抛出异常。
func toMinutes()
public func toMinutes(): Int64
功能:获得当前 Duration 实例以分钟为单位的整数大小。
返回值:
func toNanoseconds()
public func toNanoseconds(): Int64
功能:获得当前 Duration 实例以纳秒为单位的整数大小,向绝对值小的方向取整。
返回值:
异常:
- ArithmeticException - 当 Duration 实例以“纳秒”为单位的大小超过 Int64 表示范围时,抛出异常。
func toSeconds()
public func toSeconds(): Int64
功能:获得当前 Duration 实例以秒为单位的整数大小。
返回值:
func toString()
public func toString(): String
功能:获得当前 Duration 实例的字符串表示,格式形如:"1d2h3m4s5ms6us7ns",表示“1天2小时3分钟4秒5毫秒6微秒7纳秒”。某个单位下数值为 0 时此项会被省略,特别地,当所有单位下数值都为 0 时,返回 "0s"。
返回值:
operator func !=(Duration)
public operator func !=(r: Duration): Bool
功能:判断当前 Duration 实例是否不等于 r。
参数:
返回值:
operator func *(Float64)
public operator func *(r: Float64): Duration
功能:实现 Duration 类型与 Float64 类型的乘法,即 Duration * Float64 运算。
参数:
- r: Float64 - 乘法的右操作数。
返回值:
异常:
- ArithmeticException - 当相乘后的结果超出 Duration 的表示范围时,抛出异常。
operator func *(Int64)
public operator func *(r: Int64): Duration
功能:实现 Duration 类型与 Int64 类型的乘法,即 Duration * Int64 运算。
参数:
- r: Int64 - 乘法的右操作数。
返回值:
异常:
- ArithmeticException - 当相乘后的结果超出 Duration 的表示范围时,抛出异常。
operator func +(Duration)
public operator func +(r: Duration): Duration
功能:实现 Duration 类型之间的加法,即 Duration + Duration 运算。
参数:
- r: Duration - 加法的右操作数。
返回值:
异常:
- ArithmeticException - 当相加后的结果超出 Duration 的表示范围时,抛出异常。
operator func -(Duration)
public operator func -(r: Duration): Duration
功能:实现 Duration 类型之间的减法,即 Duration - Duration 运算。
参数:
- r: Duration - 减法的右操作数。
返回值:
异常:
- ArithmeticException - 当相减后的结果超出 Duration 的表示范围时,抛出异常。
operator func /(Duration)
public operator func /(r: Duration): Float64
功能:实现 Duration 类型与 Duration 类型的除法,即 Duration / Duration 运算。
参数:
- r: Duration - 除数。
返回值:
异常:
- IllegalArgumentException - 当
r等于 Duration.Zero 时,抛出异常。
operator func /(Float64)
public operator func /(r: Float64): Duration
功能:实现 Duration 类型与 Float64 类型的除法,即 Duration / Float64 运算。
参数:
- r: Float64 - 除数。
返回值:
异常:
- IllegalArgumentException - 当
r等于 0 时,抛出异常。 - ArithmeticException - 当相除后的结果超出 Duration 的表示范围时,抛出异常。
operator func /(Int64)
public operator func /(r: Int64): Duration
功能:实现 Duration 类型与 Int64 类型的除法,即 Duration / Int64 运算。
参数:
- r: Int64 - 除数。
返回值:
异常:
- IllegalArgumentException - 当
r等于 0 时,抛出异常。 - ArithmeticException - 当相除后的结果超出 Duration 的表示范围时,抛出异常。
operator func <(Duration)
public operator func <(r: Duration): Bool
功能:判断当前 Duration 实例是否小于 r。
参数:
返回值:
operator func <=(Duration)
public operator func <=(r: Duration): Bool
功能:判断当前 Duration 实例是否小于等于 r。
参数:
返回值:
operator func ==(Duration)
public operator func ==(r: Duration): Bool
功能:判断当前 Duration 实例是否等于 r。
参数:
返回值:
operator func >(Duration)
public operator func >(r: Duration): Bool
功能:判断当前 Duration 实例是否大于 r。
参数:
返回值:
operator func >=(Duration)
public operator func >=(r: Duration): Bool
功能:判断当前 Duration 实例是否大于等于 r。
参数:
返回值:
struct LibC
public struct LibC
功能:提供了仓颉中较为高频使用的 C 接口,如申请、释放堆上 CType 实例。
static func free<T>(CPointer<T>) where T <: CType
public static unsafe func free<T>(p: CPointer<T>): Unit where T <: CType
功能:释放指针 p 指向的堆内存。
参数:
- p: CPointer<T> - 表示需要被释放的内存地址。
static func free(CString)
public static unsafe func free(cstr: CString): Unit
功能:释放 C 风格字符串。
参数:
- cstr: CString - 需要释放的 C 风格字符串。
static func mallocCString(String)
public static unsafe func mallocCString(str: String): CString
功能:通过 String 申请与之字符内容相同的 C 风格字符串。
构造的 C 风格字符串将以 '\0' 结束。当异常场景如系统内存不足时,返回字符串指针可能为空,故使用前需要进行空指针检查。
参数:
- str: String - 根据该仓颉字符串构造 C 字符串。
返回值:
- CString - 新构造的 C 风格字符串。
异常:
- IllegalMemoryException - 内存不足时,抛出异常。
示例:
main() {
var str = unsafe { LibC.mallocCString("I like Cangjie") }
println(str)
unsafe { LibC.free(str) }
}
运行结果:
I like Cangjie
static func malloc<T>(Int64) where T <: CType
public static func malloc<T>(count!: Int64 = 1): CPointer<T> where T <: CType
功能:在堆中申请指定个数的 T 实例,并返回其起始指针。
参数:
返回值:
- CPointer<T> - 申请的 T 类型指针。
异常:
- IllegalArgumentException - 入参为负数时,抛出异常。
示例:
main() {
var p = unsafe { LibC.malloc<Int64>(count: 1) }
unsafe { p.write(8) }
let value: Int64 = unsafe { p.read() }
println(value)
unsafe { LibC.free<Int64>(p) }
}
运行结果:
8
struct Range<T> where T <: Countable<T> & Comparable<T> & Equatable<T>
public struct Range<T> <: Iterable<T> where T <: Countable<T> & Comparable<T> & Equatable<T> {
public let end: T
public let hasEnd: Bool
public let hasStart: Bool
public let isClosed: Bool
public let start: T
public let step: Int64
public const init(start: T, end: T, step: Int64, hasStart: Bool, hasEnd: Bool, isClosed: Bool)
}
功能:该类是区间类型,用于表示一个拥有固定范围和步长的 T 的序列,要求 T 是可数的,有序的。
区间类型有对应的字面量表示,其格式为:
- 左闭右开区间:
start..end : step,它表示一个从 start 开始,以 step 为步长,到 end(不包含 end)为止的区间。 - 左闭右闭区间:
start..=end : step,它表示一个从 start 开始,以 step 为步长,到 end(包含 end)为止的区间。
注意:
父类型:
- Iterable<T>
let end
public let end: T
功能:表示结束值。
类型:T
let hasEnd
public let hasEnd: Bool
功能:表示是否包含结束值。
类型:Bool
let hasStart
public let hasStart: Bool
功能:表示是否包含开始值。
类型:Bool
let isClosed
public let isClosed: Bool
功能:表示区间开闭情况,为 true 表示左闭右闭,为 false 表示左闭右开。
类型:Bool
let start
public let start: T
功能:表示开始值。
类型:T
let step
public let step: Int64
功能:表示步长。
类型:Int64
init(T, T, Int64, Bool, Bool, Bool)
public const init(start: T, end: T, step: Int64, hasStart: Bool, hasEnd: Bool, isClosed: Bool)
功能:使用该构造函数创建 Range 序列。
参数:
- start: T - 开始值。
- end: T - 结束值。
- step: Int64 - 步长,取值不能为 0。
- hasStart: Bool - 是否有开始值。
- hasEnd: Bool - 是否有结束值。
- isClosed: Bool - true 代表左闭右闭,false 代表左闭右开。
异常:
- IllegalArgumentException - 当 step 等于 0 时, 抛出异常。
func isEmpty()
public const func isEmpty(): Bool
功能:判断该区间是否为空。
返回值:
- Bool - 如果为空,返回 true,否则返回 false。
func iterator()
public func iterator(): Iterator<T>
功能:获取当前区间的迭代器。
返回值:
- Iterator<T> - 当前区间的迭代器。
extend<T> Range<T> <: Equatable<Range<T>> where T <: Countable<T> & Comparable<T> & Equatable<T>
extend<T> Range<T> <: Equatable<Range<T>> where T <: Countable<T> & Comparable<T> & Equatable<T>
功能:为 Range<T> 类型扩展 Equatable<Range<T>> 接口。
父类型:
operator func ==(Range<T>)
public operator func ==(that: Range<T>): Bool
功能:判断两个 Range 实例是否相等。
两个 Range 实例相等指的是它们表示同一个区间,即 start、end、step、isClosed 值相等。
参数:
返回值:
- Bool - true 代表相等,false 代表不相等。
extend<T> Range<T> <: Hashable where T <: Hashable & Countable<T> & Comparable<T> & Equatable<T>
extend<T> Range<T> <: Hashable where T <: Hashable & Countable<T> & Comparable<T> & Equatable<T>
功能:为 Range 类型扩展 Hashable 接口,支持计算哈希值。
父类型:
func hashCode()
public func hashCode(): Int64
功能:获取哈希值,该值为 start、end、step、isClosed 的组合哈希运算结果。
返回值:
- Int64 - 哈希值。
struct String
public struct String <: Collection<Byte> & Equatable<String> & Comparable<String> & Hashable & ToString {
public static const empty: String = String()
public const init()
public init(value: Array<Rune>)
public init(value: Collection<Rune>)
}
功能:该结构体表示仓颉字符串,提供了构造、查找、拼接等一系列字符串操作。
注意:
String类型仅支持 UTF-8 编码。- 出于
String对象内存开销方面的优化,String的长度被限制在4GB大小,即String的最大长度不超过 UInt32 的最大值。
父类型:
static const empty
public static const empty: String = String()
功能:创建一个空的字符串并返回。
类型:String
prop size
public prop size: Int64
功能:获取字符串 UTF-8 编码后的字节长度。
类型:Int64
init()
public const init()
功能:构造一个空的字符串。
init(Array<Rune>)
public init(value: Array<Rune>)
功能:根据字符数组构造一个字符串,字符串内容为数组中的所有字符。
参数:
- value: Array<Rune> - 根据该字符数组构造字符串。
异常:
- IllegalArgumentException - 当试图构造长度超过 UInt32 的最大值 的字符串时,抛出异常。
init(Collection<Rune>)
public init(value: Collection<Rune>)
功能:据字符集合构造一个字符串,字符串内容为集合中的所有字符。
参数:
- value: Collection<Rune> - 根据该字符集合构造字符串。
异常:
- IllegalArgumentException - 当试图构造长度超过 UInt32 的最大值 的字符串时,抛出异常。
static func checkUtf8Encoding(Array<UInt8>)
public static func checkUtf8Encoding(data: Array<UInt8>): Bool
功能:检查一个 Byte 数组是否符合 UTF-8 编码。
参数:
返回值:
- Bool - 如果 Byte 数组符合 UTF-8 编码返回 true,否则返回 false。
static func fromUtf8(Array<UInt8>)
public static func fromUtf8(utf8Data: Array<UInt8>): String
功能:根据 UTF-8 编码的字节数组构造一个字符串。
参数:
返回值:
- String - 构造的字符串。
异常:
- IllegalArgumentException - 入参不符合 utf-8 序列规则,或者试图构造长度超过 UInt32 的最大值 的字符串时,抛出异常。
static func fromUtf8Unchecked(Array<UInt8>)
public static unsafe func fromUtf8Unchecked(utf8Data: Array<UInt8>): String
功能:根据字节数组构造一个字符串。
相较于 fromUtf8 函数,它并没有针对于字节数组进行 UTF-8 相关规则的检查,所以它所构建的字符串并不一定保证是合法的,甚至出现非预期的异常,如果不是某些场景下的性能考虑,请优先使用安全的 fromUtf8 函数。
参数:
返回值:
- String - 构造的字符串。
异常:
- IllegalArgumentException - 当试图构造长度超过 UInt32 的最大值 的字符串时,抛出异常。
static func join(Array<String>, String)
public static func join(strArray: Array<String>, delimiter!: String = String.empty): String
功能:连接字符串列表中的所有字符串,以指定分隔符分隔。
参数:
- strArray: Array<String> - 需要被连接的字符串数组,当数组为空时,返回空字符串。
- delimiter!: String - 用于连接的中间字符串,其默认值为 String.empty。
返回值:
- String - 连接后的新字符串。
异常:
- IllegalArgumentException - 当试图构造长度超过 UInt32 的最大值 的字符串时,抛出异常。
示例:
main() {
var arr = ["I", "like", "Cangjie"]
var str = String.join(arr, delimiter: " ")
println(str)
}
运行结果:
I like Cangjie
static func withRawData(Array<UInt8>)
public static unsafe func withRawData(rawData: Array<UInt8>): String
功能:根据字节数组构造一个字符串。
相较于 fromUtf8Unchecked 函数,它没有做数组的拷贝,直接用传入的数组构造了字符串。
注意:
用户应该保证:
- rawData 在字符串构造后永远不会被修改。
- rawData 符合 UTF-8 编码。
否则程序行为是未定义的。 如果不是某些场景下的性能考虑,请优先使用安全的 fromUtf8 函数。
参数:
返回值:
- String - 构造的字符串。
异常:
- IllegalArgumentException - 当试图构造长度超过 UInt32 的最大值 的字符串时,抛出异常。
func clone()
public func clone(): String
功能:返回原字符串的拷贝。
返回值:
- String - 拷贝得到的新字符串。
func compare(String)
public func compare(str: String): Ordering
功能:按字典序比较当前字符串和参数指定的字符串。
参数:
- str: String - 被比较的字符串。
返回值:
- Ordering - 返回 enum 值 Ordering 表示结果,Ordering.GT 表示当前字符串字典序大于 str 字符串,Ordering.LT 表示当前字符串字典序小于 str 字符串,Ordering.EQ 表示两个字符串字典序相等。
异常:
- IllegalArgumentException - 如果两个字符串的原始数据中存在无效的 UTF-8 编码,抛出异常。
func contains(String)
public func contains(str: String): Bool
功能:判断原字符串中是否包含字符串 str。
参数:
- str: String - 待搜索的字符串。
返回值:
- Bool - 如果字符串 str 在原字符串中,返回 true,否则返回 false。特别地,如果 str 字符串长度为 0,返回 true。
func count(String)
public func count(str: String): Int64
功能:返回子字符串 str 在原字符串中出现的次数。
参数:
- str: String - 被搜索的子字符串。
返回值:
- Int64 - 出现的次数,当 str 为空字符串时,返回原字符串中 Rune 的数量加一。
func endsWith(String)
public func endsWith(suffix: String): Bool
功能:判断原字符串是否以 suffix 字符串为后缀结尾。
参数:
- suffix: String - 被判断的后缀字符串。
返回值:
- Bool - 如果字符串 str 是原字符串的后缀,返回 true,否则返回 false,特别地,如果 str 字符串长度为 0,返回 true。
func equalsIgnoreAsciiCase(String): Bool
public func equalsIgnoreAsciiCase(that: String): Bool
功能:判断当前字符串和指定字符串是否相等,忽略大小写。
参数:
- that: String - 待比较的字符串。
返回值:
- Bool - 如果当前字符串与待比较字符串相等,返回 true,否则返回 false。
func get(Int64)
public func get(index: Int64): Option<Byte>
功能:返回字符串下标 index 对应的 UTF-8 编码字节值。
参数:
- index: Int64 - 要获取的字节值的下标。
返回值:
func hashCode()
public func hashCode(): Int64
功能:获取字符串的哈希值。
返回值:
- Int64 - 返回字符串的哈希值。
func indexOf(Byte)
public func indexOf(b: Byte): Option<Int64>
功能:获取指定字节 b 第一次出现的在原字符串内的索引。
参数:
- b: Byte - 待搜索的字节。
返回值:
func indexOf(Byte, Int64)
public func indexOf(b: Byte, fromIndex: Int64): Option<Int64>
功能:从原字符串指定索引开始搜索,获取指定字节第一次出现的在原字符串内的索引。
参数:
返回值:
- Option<Int64> - 如果搜索成功,返回指定字节第一次出现的索引,否则返回
None。特别地,当 fromIndex 小于零,效果同 0,当 fromIndex 大于等于原字符串长度,返回 Option<Int64>.None。
func indexOf(String)
public func indexOf(str: String): Option<Int64>
功能:返回指定字符串 str 在原字符串中第一次出现的起始索引。
参数:
- str: String - 待搜索的字符串。
返回值:
func indexOf(String, Int64)
public func indexOf(str: String, fromIndex: Int64): Option<Int64>
功能:从原字符串 fromIndex 索引开始搜索,获取指定字符串 str 第一次出现的在原字符串的起始索引。
参数:
返回值:
- Option<Int64> - 如果搜索成功,返回 str 第一次出现的索引,否则返回 None。特别地,当 str 是空字符串时,如果fromIndex 大于 0,返回 None,否则返回 Some(0)。当 fromIndex 小于零,效果同 0,当 fromIndex 大于等于原字符串长度返回 None。
func isAscii()
public func isAscii(): Bool
功能:判断字符串是否是一个 Ascii 字符串,如果字符串为空或没有 Ascii 以外的字符,则返回 true。
返回值:
- Bool - 是则返回 true,不是则返回 false。
func isAsciiBlank()
public func isAsciiBlank(): Bool
功能:判断字符串是否为空或者字符串中的所有 Rune 都是 ascii 码的空白字符(包括:0x09、0x10、0x11、0x12、0x13、0x20)。
返回值:
- Bool - 如果是返回 true,否则返回 false。
func isEmpty()
public func isEmpty(): Bool
功能:判断原字符串是否为空字符串。
返回值:
- Bool - 如果为空返回 true,否则返回 false。
func iterator()
public func iterator(): Iterator<Byte>
功能:获取字符串的 UTF-8 编码字节迭代器,可用于支持 for-in 循环。
返回值:
示例:
main() {
var str = "abc"
/* 迭代器元素为每个字符的 utf-8 编码 */
for (i in str) {
println(i)
}
}
运行结果:
97
98
99
func lastIndexOf(Byte)
public func lastIndexOf(b: Byte): Option<Int64>
功能:返回指定字节 b 最后一次出现的在原字符串内的索引。
参数:
- b: Byte - 待搜索的字节。
返回值:
func lastIndexOf(Byte, Int64)
public func lastIndexOf(b: Byte, fromIndex: Int64): Option<Int64>
功能:从原字符串 fromIndex 索引开始搜索,返回指定 UTF-8 编码字节 b 最后一次出现的在原字符串内的索引。
参数:
返回值:
- Option<Int64> - 如果搜索成功,返回指定字节最后一次出现的索引,否则返回
None。特别地,当 fromIndex 小于零,效果同 0,当 fromIndex 大于等于原字符串长度,返回None。
func lastIndexOf(String)
public func lastIndexOf(str: String): Option<Int64>
功能:返回指定字符串 str 最后一次出现的在原字符串的起始索引。
参数:
- str: String - 待搜索的字符串。
返回值:
func lastIndexOf(String, Int64)
public func lastIndexOf(str: String, fromIndex: Int64): Option<Int64>
功能:从原字符串指定索引开始搜索,获取指定字符串 str 最后一次出现的在原字符串的起始索引。
参数:
返回值:
- Option<Int64> - 如果这个字符串在位置 fromIndex 及其之后没有出现,则返回
None。特别地,当 str 是空字符串时,如果 fromIndex 大于 0,返回None,否则返回Some(0),当 fromIndex 小于零,效果同 0,当 fromIndex 大于等于原字符串长度返回None。
func lazySplit(String, Bool)
public func lazySplit(str: String, removeEmpty!: Bool = false): Iterator<String>
功能:对原字符串按照字符串 str 分隔符分割,该函数不立即对字符串进行分割,而是返回迭代器,使用迭代器进行遍历时再实际执行分隔操作。
当 str 未出现在原字符串中,返回大小为 1 的字符串迭代器,唯一的元素为原字符串。
参数:
返回值:
示例:
main() {
var str = "I like Cangjie"
var iter = str.lazySplit(" ")
while (true) {
match (iter.next()) {
case Some(i) => println(i)
case None => break
}
}
}
运行结果:
I
like
Cangjie
func lazySplit(String, Int64, Bool)
public func lazySplit(str: String, maxSplits: Int64, removeEmpty!: Bool = false): Iterator<String>
功能:对原字符串按照字符串 str 分隔符分割,该函数不立即对字符串进行分割,而是返回迭代器,使用迭代器进行遍历时再实际执行分隔操作。
- 当 maxSplit 为 0 时,返回空的字符串迭代器;
- 当 maxSplit 为 1 时,返回大小为 1 的字符串迭代器,唯一的元素为原字符串;
- 当 maxSplit 为负数时,直接返回分割后的字符串迭代器;
- 当 maxSplit 大于完整分割出来的子字符串数量时,返回完整分割的字符串迭代器;
- 当 str 未出现在原字符串中,返回大小为 1 的字符串迭代器,唯一的元素为原字符串;
- 当 str 为空时,对每个字符进行分割;当原字符串和分隔符都为空时,返回空字符串迭代器。
参数:
- str: String - 字符串分隔符。
- maxSplits: Int64 - 最多分割为 maxSplit 个子字符串。
- removeEmpty!: Bool - 移除分割结果中的空字符串,默认值为 false。
返回值:
func lines()
public func lines(): Iterator<String>
功能:获取字符串的行迭代器,每行都由换行符进行分隔,换行符是 \n \r \r\n 之一,结果中每行不包括换行符。
返回值:
示例:
main() {
var str = "I\rlike\nCangjie\r"
var iter = str.lines()
while (true) {
match (iter.next()) {
case Some(i) => println(i)
case None => break
}
}
}
运行结果:
I
like
Cangjie
func padEnd(Int64, String)
public func padEnd(totalWidth: Int64, padding!: String = " "): String
功能:按指定长度左对齐原字符串,如果原字符串长度小于指定长度,在其右侧添加指定字符串。
当指定长度小于字符串长度时,返回字符串本身,不会发生截断;当指定长度大于字符串长度时,在右侧添加 padding 字符串,当 padding 长度大于 1 时,返回字符串的长度可能大于指定长度。
参数:
返回值:
- String - 填充后的字符串。
异常:
- IllegalArgumentException - 如果 totalWidth 小于 0,抛出异常。
func padStart(Int64, String)
public func padStart(totalWidth: Int64, padding!: String = " "): String
功能:按指定长度右对齐原字符串,如果原字符串长度小于指定长度,在其左侧添加指定字符串。
当指定长度小于字符串长度时,返回字符串本身,不会发生截断;当指定长度大于字符串长度时,在左侧添加 padding 字符串,当 padding 长度大于 1 时,返回字符串的长度可能大于指定长度。
参数:
返回值:
- String - 填充后的字符串。
异常:
- IllegalArgumentException - 如果 totalWidth 小于 0,抛出异常。
func rawData()
public unsafe func rawData(): Array<Byte>
功能:获取字符串的 UTF-8 编码的原始字节数组。
注意:
用户不应该对获取的数组进行修改,这将破坏字符串的不可变性。
返回值:
func removePrefix(String)
public func removePrefix(prefix: String): String
功能:去除字符串的 prefix 前缀。
参数:
- prefix: String - 待去除的前缀。
返回值:
- String - 去除前缀后得到的新字符串。
func removeSuffix(String)
public func removeSuffix(suffix: String): String
功能:去除字符串的 suffix 后缀。
参数:
- suffix: String - 待去除的后缀。
返回值:
- String - 去除后缀后得到的新字符串。
func replace(String, String)
public func replace(old: String, new: String): String
功能:使用新字符串替换原字符串中旧字符串。
参数:
返回值:
- String - 替换后的新字符串。
异常:
- OutOfMemoryError - 如果此函数分配内存时产生错误,抛出异常。
func runes()
public func runes(): Iterator<Rune>
功能:获取字符串的 Rune 迭代器。
返回值:
- Iterator<Rune> - 字符串的 Rune 迭代器。
异常:
- IllegalArgumentException - 使用
for-in或者next()方法遍历迭代器时,如果读取到非法字符,抛出异常。
func split(String, Bool)
public func split(str: String, removeEmpty!: Bool = false): Array<String>
功能:对原字符串按照字符串 str 分隔符分割,指定是否删除空串。
当 str 未出现在原字符串中,返回长度为 1 的字符串数组,唯一的元素为原字符串。
参数:
返回值:
func split(String, Int64, Bool)
public func split(str: String, maxSplits: Int64, removeEmpty!: Bool = false): Array<String>
功能:对原字符串按照字符串 str 分隔符分割,指定最多分隔子串数,以及是否删除空串。
- 当 maxSplit 为 0 时,返回空的字符串数组;
- 当 maxSplit 为 1 时,返回长度为 1 的字符串数组,唯一的元素为原字符串;
- 当 maxSplit 为负数时,返回完整分割后的字符串数组;
- 当 maxSplit 大于完整分割出来的子字符串数量时,返回完整分割的字符串数组;
- 当 str 未出现在原字符串中,返回长度为 1 的字符串数组,唯一的元素为原字符串;
- 当 str 为空时,对每个字符进行分割;当原字符串和分隔符都为空时,返回空字符串数组。
参数:
- str: String - 字符串分隔符。
- maxSplits: Int64 - 最多分割为 maxSplit 个子字符串。
- removeEmpty!: Bool - 移除分割结果中的空字符串,默认值为 false。
返回值:
func startsWith(String)
public func startsWith(prefix: String): Bool
功能:判断原字符串是否以 prefix 字符串为前缀。
参数:
- prefix: String - 被判断的前缀字符串。
返回值:
- Bool - 如果字符串 str 是原字符串的前缀,返回 true,否则返回 false,特别地,如果 str 字符串长度为 0,返回 true。
func toArray()
public func toArray(): Array<Byte>
功能:获取字符串的 UTF-8 编码的字节数组。
返回值:
func toAsciiLower()
public func toAsciiLower(): String
功能:将该字符串中所有 Ascii 大写字母转化为 Ascii 小写字母。
返回值:
- String - 转换后的新字符串。
func toAsciiTitle()
public func toAsciiTitle(): String
功能:将该字符串标题化。
该函数只转换 Ascii 英文字符,当该英文字符是字符串中第一个字符或者该字符的前一个字符不是英文字符,则该字符大写,其他英文字符小写。
返回值:
- String - 转换后的新字符串。
func toAsciiUpper()
public func toAsciiUpper(): String
功能:将该字符串中所有 Ascii 小写字母转化为 Ascii 大写字母。
返回值:
- String - 转换后的新字符串。
func toRuneArray()
public func toRuneArray(): Array<Rune>
功能:获取字符串的 Rune 数组。如果原字符串为空字符串,则返回空数组。
返回值:
- Array<Rune> - 字符串的 Rune 数组。
func toString()
public func toString(): String
功能:获得字符串本身。
返回值:
- String - 返回字符串本身。
func trimAscii()
public func trimAscii(): String
功能:去除原字符串开头结尾以 whitespace 字符组成的子字符串。
whitespace 的 unicode 码点范围为 [0009, 000D] 和 [0020]。
返回值:
- String - 转换后的新字符串。
func trimAsciiEnd()
public func trimAsciiEnd(): String
功能:去除原字符串结尾以 whitespace 字符组成的子字符串。
返回值:
- String - 转换后的新字符串。
func trimAsciiStart()
public func trimAsciiStart(): String
功能:去除原字符串开头以 whitespace 字符组成的子字符串。
返回值:
- String - 转换后的新字符串。
func trimEnd((Rune)->Bool)
public func trimEnd(predicate: (Rune)->Bool): String
功能:修剪当前字符串,从尾开始删除符合过滤条件的 Rune 字符,直到第一个不符合过滤条件的 Rune 字符为止。
参数:
返回值:
- String - 修剪后得到的新字符串。
示例:
main() {
var str = "14122"
var subStr = str.trimEnd({c => c == r'2'})
println(subStr)
}
运行结果:
141
func trimEnd(Array<Rune>)
public func trimEnd(set: Array<Rune>): String
功能:修剪当前字符串,从尾开始删除在 set 中的 Rune 字符,直到第一个不在 set 中的 Rune 字符为止。
参数:
返回值:
- String - 修剪后得到的新字符串。
示例:
main() {
var str = "14122"
var subStr = str.trimEnd([r'1', r'2'])
println(subStr)
}
运行结果:
14
func trimEnd(String)
public func trimEnd(set: String): String
功能:修剪当前字符串,从尾开始删除在 set 中的 Rune 字符,直到第一个不在 set 中的 Rune 字符为止。
参数:
- set: String - 待删除的字符的集合。
返回值:
- String - 修剪后得到的新字符串。
示例:
main() {
var str = "14122"
var subStr = str.trimEnd("12")
println(subStr)
}
运行结果:
14
func trimStart((Rune)->Bool)
public func trimStart(predicate: (Rune)->Bool): String
功能:修剪当前字符串,从头开始删除符合过滤条件的 Rune 字符,直到第一个不符合过滤条件的 Rune 字符为止。
参数:
返回值:
- String - 修剪后得到的新字符串。
func trimStart(Array<Rune>)
public func trimStart(set: Array<Rune>): String
功能:修剪当前字符串,从头开始删除在 set 中的 Rune 字符,直到第一个不在 set 中的 Rune 字符为止。
例如 "12241".trimStart([r'1', r'2']) = "41"。
参数:
返回值:
- String - 修剪后得到的新字符串。
func trimStart(String)
public func trimStart(set: String): String
功能:修剪当前字符串,从头开始删除在 set 中的 Rune 字符,直到第一个不在 set 中的 Rune 字符为止。
例如 "12241".trimStart("12") = "41"。
参数:
- set: String - 待删除的字符的集合。
返回值:
- String - 修剪后得到的新字符串。
operator func !=(String)
public const operator func !=(right: String): Bool
功能:判断两个字符串是否不相等。
参数:
返回值:
- Bool - 不相等返回 true,相等返回 false。
operator func *(Int64)
public const operator func *(count: Int64): String
功能:原字符串重复 count 次。
参数:
- count: Int64 - 原字符串重复的次数。
返回值:
异常:
- IllegalArgumentException - 当试图构造长度超过 UInt32 的最大值 的字符串时,抛出异常。
operator func +(String)
public const operator func +(right: String): String
功能:两个字符串相加,将 right 字符串拼接在原字符串的末尾。
参数:
- right: String - 待追加的字符串。
返回值:
- String - 返回拼接后的字符串。
异常:
- IllegalArgumentException - 当试图构造长度超过 UInt32 的最大值 的字符串时,抛出异常。
operator func <(String)
public const operator func <(right: String): Bool
功能:判断两个字符串大小。
参数:
- right: String - 待比较的字符串。
返回值:
- Bool - 原字符串字典序小于 right 时,返回 true,否则返回 false。
operator func <=(String)
public const operator func <=(right: String): Bool
功能:判断两个字符串大小。
参数:
- right: String - 待比较的字符串。
返回值:
- Bool - 原字符串字典序小于或等于 right 时,返回 true,否则返回 false。
operator func ==(String)
public const operator func ==(right: String): Bool
功能:判断两个字符串是否相等。
参数:
- right: String - 待比较的字符串。
返回值:
- Bool - 相等返回 true,不相等返回 false。
operator func >(String)
public const operator func >(right: String): Bool
功能:判断两个字符串大小。
参数:
- right: String - 待比较的字符串。
返回值:
- Bool - 原字符串字典序大于 right 时,返回 true,否则返回 false。
operator func >=(String)
public const operator func >=(right: String): Bool
功能:判断两个字符串大小。
参数:
- right: String - 待比较的字符串。
返回值:
- Bool - 原字符串字典序大于或等于 right 时,返回 true,否则返回 false。
operator func [](Int64)
public const operator func [](index: Int64): Byte
功能:返回指定索引 index 处的 UTF-8 编码字节。
参数:
- index: Int64 - 要获取 UTF-8 编码字节的下标。
返回值:
- Byte - 获取得到下标对应的 UTF-8 编码字节。
异常:
- IndexOutOfBoundsException - 如果 index 小于 0 或大于等于字符串长度,抛出异常。
operator func [](Range<Int64>)
public const operator func [](range: Range<Int64>): String
功能:根据给定区间获取当前字符串的切片。
注意:
参数:
返回值:
- String - 字符串切片。
异常:
- IndexOutOfBoundsException - 如果切片范围超过原字符串边界,抛出异常。
- IllegalArgumentException - 如果 range.step 不等于 1 或者范围起止点不是字符边界,抛出异常。
异常类
class ArithmeticException
public open class ArithmeticException <: Exception {
public init()
public init(message: String)
}
功能:算术异常类,发生算术异常时使用。
父类型:
init()
public init()
功能:构造一个默认的 ArithmeticException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 ArithmeticException 实例。
参数:
- message: String - 异常提示信息。
func getClassName()
protected open override func getClassName(): String
功能:获得类名。
返回值:
- String - 类名字符串。
class Error
public open class Error <: ToString
功能:Error 是所有错误类的基类。该类不可被继承,不可初始化,但是可以被捕获到。
父类型:
prop message
public open prop message: String
功能:获取错误信息。
类型:String
func getClassName()
protected open func getClassName(): String
功能:获得类名。
返回值:
- String - 类名。
func getStackTrace()
public func getStackTrace(): Array<StackTraceElement>
功能:获取堆栈信息,每一条堆栈信息用一个 StackTraceElement 实例表示,最终返回一个 StackTraceElement 的数组。
返回值:
- Array<StackTraceElement> - 堆栈信息数组。
func getStackTraceMessage()
public open func getStackTraceMessage(): String
功能:获取堆栈信息。
返回值:
- String - 堆栈信息。
func printStackTrace()
public open func printStackTrace(): Unit
功能:向控制台打印堆栈信息。
func toString()
public open func toString(): String
功能:获取当前 Error 实例的字符串值,包括类名和错误信息。
返回值:
- String - 错误信息字符串。
class Exception
public open class Exception <: ToString {
public init()
public init(message: String)
}
功能:Exception 是所有异常类的父类。
支持构造一个异常类,设置、获取异常信息,转换为字符串,获取、打印堆栈,设置异常名(用于字符串表示)。
父类型:
prop message
public open prop message: String
功能:获取异常信息。
类型:String
init()
public init()
功能:构造一个默认的 Exception 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 Exception 实例。
参数:
- message: String - 异常提示信息。
func getClassName()
protected open func getClassName(): String
功能:获得类名。
返回值:
- String - 类名。
func getStackTrace()
public func getStackTrace(): Array<StackTraceElement>
功能:获取堆栈信息,每一条堆栈信息用一个 StackTraceElement 实例表示,最终返回一个 StackTraceElement 的数组。
返回值:
- Array<StackTraceElement> - 堆栈信息数组。
func printStackTrace()
public func printStackTrace(): Unit
功能:向控制台打印堆栈信息。
func toString()
public open func toString(): String
功能:获取当前 Exception 实例的字符串值,包括类名和异常信息。
返回值:
- String - 异常字符串。
class IllegalArgumentException
public open class IllegalArgumentException <: Exception {
public init()
public init(message: String)
}
功能:表示参数非法的异常类。
父类型:
init()
public init()
功能:构造一个默认的 IllegalArgumentException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 IllegalArgumentException 实例。
参数:
- message: String - 异常提示信息。
func getClassName()
protected override open func getClassName(): String
功能:获得类名。
返回值:
- String - 类名。
class IllegalFormatException
public open class IllegalFormatException <: IllegalArgumentException {
public init()
public init(message: String)
}
功能:表示变量的格式无效或不标准时的异常类。
父类型:
init()
public init()
功能:构造一个默认的 IllegalFormatException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 IllegalFormatException 实例。
参数:
- message: String - 异常提示信息。
class IllegalMemoryException
public class IllegalMemoryException <: Exception {
public init()
public init(message: String)
}
功能:表示内存操作错误的异常类。
父类型:
init()
public init()
功能:构造一个默认的 IllegalMemoryException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据指定异常信息构造 IllegalMemoryException 实例。
参数:
- message: String - 异常提示信息。
class IllegalStateException
public class IllegalStateException <: Exception {
public init()
public init(message: String)
}
功能:表示状态非法的异常类。
父类型:
init()
public init()
功能:构造一个默认的 IllegalStateException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 IllegalStateException 实例。
参数:
- message: String - 异常提示信息。
class IncompatiblePackageException
public class IncompatiblePackageException <: Exception {
public init()
public init(message: String)
}
功能:表示包不兼容的异常类。
父类型:
init()
public init()
功能:构造一个默认的 IncompatiblePackageException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 IncompatiblePackageException实例。
参数:
- message: String - 异常提示信息。
class IndexOutOfBoundsException
public class IndexOutOfBoundsException <: Exception {
public init()
public init(message: String)
}
功能:表示索引越界的异常类。
父类型:
init()
public init()
功能:构造一个默认的 IndexOutOfBoundsException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 IndexOutOfBoundsException 实例。
参数:
- message: String - 异常提示信息。
class InternalError
public class InternalError <: Error
功能:表示内部错误的错误类,该类不可初始化,但是可以被捕获到。
父类型:
class NegativeArraySizeException
public class NegativeArraySizeException <: Exception {
public init()
public init(message: String)
}
功能:表示数组大小为负数的异常类。
父类型:
init()
public init()
功能:构造一个默认的 NegativeArraySizeException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 NegativeArraySizeException 实例。
参数:
- message: String - 异常提示信息。
class NoneValueException
public class NoneValueException <: Exception {
public init()
public init(message: String)
}
功能:表示 Option<T> 实例的值为 None 的异常类,通常在 getOrThrow 函数中被抛出。
父类型:
init()
public init()
功能:构造一个默认的 NoneValueException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 NoneValueException 实例。
参数:
- message: String - 异常提示信息。
class OutOfMemoryError
public class OutOfMemoryError <: Error
功能:表示内存不足错误的错误类,该类不可被继承,不可初始化,但是可以被捕获到。
父类型:
class OverflowException
public class OverflowException <: ArithmeticException {
public init()
public init(message: String)
}
功能:表示算术运算溢出的异常类。
父类型:
init()
public init()
功能:构造一个默认的 OverflowException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据指定异常信息构造 OverflowException 实例。
参数:
- message: String - 异常提示信息。
class SpawnException
public class SpawnException <: Exception {
public init()
public init(message: String)
}
功能:线程异常类,表示线程处理过程中发生异常。
父类型:
init()
public init()
功能:构造一个默认的 SpawnException 实例,默认错误信息为空。
init(String)
public init(message: String)
功能:根据异常信息构造一个 SpawnException 实例。
参数:
- message: String - 异常提示信息。
class StackOverflowError
public class StackOverflowError <: Error
功能:表示堆栈溢出错误的错误类,该类不可被继承,不可初始化,但是可以被捕获到。
父类型:
func printStackTrace()
public override func printStackTrace(): Unit
功能:向控制台打印堆栈信息。
class TimeoutException
public class TimeoutException <: Exception {
public init()
public init(message: String)
}
功能:当阻塞操作超时时引发异常。
父类型:
init()
public init()
功能:构造一个默认的 TimeoutException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据指定异常信息构造 TimeoutException 实例。
参数:
- message: String - 异常提示信息。
class UnsupportedException
public class UnsupportedException <: Exception {
public init()
public init(message: String)
}
功能:表示功能未支持的异常类。
父类型:
init()
public init()
功能:构造一个默认的 UnsupportedException 实例,默认异常信息为空。
init(String)
public init(message: String)
功能:根据指定异常信息构造 UnsupportedException 实例。
参数:
- message: String - 异常提示信息。
仓颉并发编程示例
spawn 的使用
主线程和新线程同时尝试打印一些文本。
代码如下:
main(): Int64 {
spawn { =>
for (i in 0..10) {
println("New thread, number = ${i}")
sleep(100 * Duration.millisecond) /* 睡眠 100 毫秒 */
}
}
for (i in 0..5) {
println("Main thread, number = ${i}")
sleep(100 * Duration.millisecond) /* 睡眠 100 毫秒 */
}
return 0
}
运行结果:
Main thread, number = 0
New thread, number = 0
Main thread, number = 1
New thread, number = 1
Main thread, number = 2
New thread, number = 2
Main thread, number = 3
New thread, number = 3
Main thread, number = 4
New thread, number = 4
New thread, number = 5
注意:
上述打印信息仅做参考,实际结果受运行时序影响,呈现随机性。
由于主线程不会等待新线程执行结束,因此程序退出时新线程并未执行结束。
Future 的 get 的使用
主线程等待创建线程执行完再执行。
代码如下:
main(): Int64 {
let fut: Future<Unit> = spawn { =>
for (i in 0..10) {
println("New thread, number = ${i}")
/* 睡眠 100 毫秒 */
sleep(100 * Duration.millisecond)
}
}
/* 等待线程完成 */
fut.get()
for (i in 0..5) {
println("Main thread, number = ${i}")
/* 睡眠 100 毫秒 */
sleep(100 * Duration.millisecond)
}
return 0
}
运行结果:
New thread, number = 0
New thread, number = 1
New thread, number = 2
New thread, number = 3
New thread, number = 4
New thread, number = 5
New thread, number = 6
New thread, number = 7
New thread, number = 8
New thread, number = 9
Main thread, number = 0
Main thread, number = 1
Main thread, number = 2
Main thread, number = 3
Main thread, number = 4
取消仓颉线程
子线程接收主线程发送的取消请求。
main(): Unit {
/* 创建线程 */
let future = spawn {
while (true) {
if (Thread.currentThread.hasPendingCancellation) {
return 0
}
}
return 1
}
/* 发起线程取消请求 */
future.cancel()
let res = future.get()
println(res)
}
运行结果:
0
使用 CString 与 C 代码交互示例
C 代码中分别提供两个函数: getCString 函数,用于返回一个 C 侧的字符串指针; printCString 函数,用于打印来自仓颉侧 CString 。
#include <stdio.h>
char *str = "CString in C code.";
char *getCString() { return str; }
void printCString(char *s) { printf("%s\n", s); }
在仓颉代码中,创建一个 CString 对象,传递给 C 侧打印。并且获取 C 侧字符串,在仓颉侧打印:
示例:
foreign func getCString(): CString
foreign func printCString(s: CString): Unit
main() {
// 仓颉侧构造 CString 实例,传递到 C 侧
unsafe {
let s: CString = LibC.mallocCString("CString in Cangjie code.")
printCString(s)
LibC.free(s)
}
unsafe {
// C 侧申请字符串指针,传递到仓颉侧成为 CString 实例,再转换为仓颉字符串 String 类型
let cs = getCString()
println(cs.toString())
}
// 在 try-with-resource 语法上下文中使用 CStringResource 自动管理 CString 内存
let cs = unsafe { LibC.mallocCString("CString in Cangjie code.") }
try (csr = cs.asResource()) {
unsafe { printCString(csr.value) }
}
0
}
运行结果:
CString in Cangjie code.
CString in C code.
CString in Cangjie code.
说明:
编译方式:先将 C 代码编译成静态库或动态库,然后编译仓颉代码并链接 C 库。 假设 C 文件为 test.c,仓颉文件为 test.cj,编译过程如下:
- 使用 gcc 命令
gcc -fPIC -shared test.c -o libtest.so,编出 C 库libtest.so。- 使用 cjc 命令
cjc -L . -l test test.cj,编出可执行文件main。
std.argopt
功能介绍
argopt 包提供从命令行参数字符串解析出参数名和参数值的相关能力。
命令行参数是在命令行中传递给程序的参数,它们用于指定程序的配置或行为。例如,一个命令行程序可能有一个参数来指定它要处理的文件的名称,或者一个参数来指定使用的数据库。这些参数通常会被解析并传递给程序的代码,以便程序可以根据这些参数正确地执行其功能。
命令行参数:通常以是否由 - 为前缀区分,可以分为选项和非选项。
- 选项:以
-为前缀。- 短选项:以单个
-为前缀且仅含单个字符的选项。 - 长选项:以
--为前缀的选项,一般包含多个字符。 - 短前缀长选项:以单个
-为前缀但包含多个字符的选项。 - 短选项组合:以
-为前缀,将多个短选项以任意顺序组合的选项。
- 短选项:以单个
- 非选项:不以
-为前缀。
注意:
单独的 "--" 后面出现的所有参数也会被视作非选项,如 "-f -- a -b --cde"中,"a"、 "-b"、 "--cde" 都是非选项。
API 列表
函数
| 函数名 | 功能 |
|---|---|
| parseArguments | 根据给定的输入和规格,解析出对应的参数。 |
类
| 类名 | 功能 |
|---|---|
| ArgOpt (deprecated) | Argopt 用于解析命令行参数,并提供了获取解析结果的功能。 |
枚举
| 枚举名 | 功能 |
|---|---|
| ArgumentMode | 参数模式。 |
| ArgumentSpec | 参数规格。 |
结构体
| 结构体名 | 功能 |
|---|---|
| ParsedArguments | 参数解析结果。 |
异常类
| 异常类名 | 功能 |
|---|---|
| ArgumentParseException | 解析出错时抛出此异常。 |
函数
func parseArguments(Array<String>, Array<ArgumentSpec>)
public func parseArguments(args: Array<String>, specs: Array<ArgumentSpec>): ParsedArguments
功能:根据提供的参数规范 specs 解析命令行参数 args,返回一个结构化的对象,包含解析后的选项和非选项参数。
该函数将 args 中的每个参数与 specs 中定义的选项进行匹配。对于匹配成功的选项,它会将选项名称和对应的值加入到 options 中,未匹配的参数会被当作非选项参数处理,并添加到 nonOptions 中。此外,当解析到 -- 时,将提前终止选项扫描,其后的所有参数都将被视作非选项。
该函数支持 短选项、长选项、短前缀长选项、短选项组合、非选项、非法选项 的解析处理。
specs 的每个 ArgumentSpec 持有的 ArgumentMode 决定了参数的处理方式。
-
对于长选项,根据不同的 ArgumentMode 仅可以处理以下格式:
- RequiredValue:
--option=valueor--option value - OptionalValue:
--option=valueor--option - NoValue:
--option
- RequiredValue:
-
对于短选项,根据不同的 ArgumentMode 仅可以处理以下格式:
- RequiredValue:
-ovor-o v - OptionalValue:
-ovor-o - NoValue:
-o
- RequiredValue:
对于短选项组合的场景:
- 当解析到第一个非 NoValue 的选项时:
- 如果该选项为 OptionalValue,紧随选项后的内容若存在,则会被作为该选项的值来解析。
- 如果该选项为 RequiredValue,紧随选项后的内容会被作为该选项的值来解析。
- 如果一组短选项可以组合成长选项的字面值,那么视为长选项而非短选项组合,如 -abc 同时已定义了
abc的长选项和abc三个短选项,会被视作长选项解析。
如果 ArgumentSpec 提供了 lambda 回调函数,该回调会在解析成功后被调用,处理解析到的参数值。
如果传入的 args 存在对同一选项多次赋值的情况,则以最后一次的值作为该选项的值。
参数:
-
specs: Array<ArgumentSpec> - 参数的规范。
返回值:
- ParsedArguments - 参数解析的结果。
异常:
-
ArgumentParseException - 当参数解析失败或解析到
非法选项时,抛出异常。 -
IllegalArgumentException - 当定义了相同
name的 ArgumentSpec 时,抛出异常。
类
class Argopt (deprecated)
public class ArgOpt {
public init(shortArgFormat: String)
public init(longArgList: Array<String>)
public init(shortArgFormat: String, longArgList: Array<String>)
public init(args: Array<String>, shortArgFormat: String, longArgList: Array<String>)
}
功能:用于解析命令行参数,并提供了获取解析结果的功能。
一个命令行参数是由前缀符号、参数名及参数值组成。
其中, "-" 表示短参(短命令行参数)的前缀,"--" 表示长参(长命令行参数)的前缀。可解析的短参参数名只能是字母,可解析长参参数名字符串需满足:以字母开头,参数名中不能包含 "="。
例如:"-a123" 和 "--target=abc.txt" 为两个命令行参数,"a" 为短参名,"target" 为长参名。而 "-123" 和 "--tar=get=abc.txt" 则是错误的命令行参数。
该类允许用户指定参数名和参数字符串,并提供根据参数名解析字符串的方法。
用户指定短参名和长参名时格式如下:
- 短参名字符串的参数,格式为:"a:",规范为:一位字母和 ":" 的组合,例如:"ab:",该例仅解析 "b" 作为短参名。
- 长参名字符串数组参数,字符串格式为:"--testA=" 或 "testA=",规范为:"--" + 长参参数名 + "="(前缀"--"可省略)。
根据参数名解析命令行参数时,若命令行参数格式正确且有对应的参数名,可正确解析并被用户获取,否则不会解析。
例如:参数名为 "a:b:",命令行参数为 "-a123 -cofo",将解析出参数名为 "a",参数值为 "123" 的命令行参数。"-cofo" 则不会解析。
注意:
未来版本即将废弃,使用 parseArguments 代替。
init(Array<String>)
public init(longArgList: Array<String>)
功能:构造 ArgOpt 实例,并从列表的字符串中解析长参名。
参数:
异常:
- IllegalArgumentException - 当字符串数组中的长参名字符串不符合规范,或字符串不符合 UTF-8 编码,或不存在该 Unicode 字符时,抛出异常。
init(Array<String>, String, Array<String>)
public init(args: Array<String>, shortArgFormat: String, longArgList: Array<String>)
功能:构造 ArgOpt 实例,并从短参名字符串中解析短参名,从列表的字符串中解析长参名。若解析成功,则依据解析出的参数名从参数 args 指定的命令行参数中解析参数名的对应取值。
参数:
- args: Array<String> - 待解析的命令行参数字符串数组。
- shortArgFormat: String - 包含短参名的字符串。
- longArgList: Array<String> - 包含长参名的字符串数组。
异常:
- IllegalArgumentException - 当短参名字符串不符合规范,或字符串数组中的长参名字符串不符合规范,或字符串不符合 UTF-8 编码,或不存在该 Unicode 字符时,抛出异常。
init(String)
public init(shortArgFormat: String)
功能:构造 ArgOpt 实例,并从短参名字符串中解析短参名。
参数:
- shortArgFormat: String - 包含短参名的字符串。
异常:
- IllegalArgumentException - 当短参名字符串不符合规范,或字符串不符合 UTF-8 编码,或不存在该 Unicode 字符时,抛出异常。
init(String, Array<String>)
public init(shortArgFormat: String, longArgList: Array<String>)
功能:构造 ArgOpt 实例,并从短参名字符串中解析短参名,从列表的字符串中解析长参名。
参数:
异常:
- IllegalArgumentException - 当短参名字符串不符合规范,或字符串数组中的长参名字符串不符合规范,或字符串不符合 UTF-8 编码,或不存在该 Unicode 字符时,抛出异常。
func getArg(String)
public func getArg(arg: String): Option<String>
功能:返回参数 arg 指定参数的解析值。
参数:
- arg: String - 前缀和参数名组成的字符串(可省略前缀)。
返回值:
func getArgumentsMap()
public func getArgumentsMap(): HashMap<String, String>
功能:获取所有已解析的参数名和参数值,以哈希表的形式返回。
返回值:
func getUnparseArgs()
public func getUnparseArgs(): Array<String>
功能:返回未被解析的命令行参数。
返回值:
枚举
enum ArgumentMode
public enum ArgumentMode <: ToString & Equatable<ArgumentMode> {
| NoValue
| RequiredValue
| OptionalValue
}
功能:描述选项的参数模式。
父类型:
NoValue
NoValue
功能:表示选项的值是不存在的。
OptionalValue
OptionalValue
功能:表示选项的值是可选的。
RequiredValue
RequiredValue
功能:表示选项的值是必须的。
func toString()
public func toString(): String
功能:获取参数模式字符串。
返回值:
- String - 参数模式字符串。
operator func ==(ArgumentMode)
public operator func ==(that: ArgumentMode): Bool
功能:比较参数模式是否相同。
参数:
- that: ArgumentMode - 参数模式。
返回值:
- Bool - 相同时返回
true,否则返回false。
enum ArgumentSpec
public enum ArgumentSpec {
| Short(Rune, ArgumentMode)
| Short(Rune, ArgumentMode, (String) -> Unit)
| Long(String, ArgumentMode)
| Long(String, ArgumentMode, (String) -> Unit)
| Full(String, Rune, ArgumentMode)
| Full(String, Rune, ArgumentMode, (String) -> Unit)
| NonOptions((Array<String>) -> Unit)
}
功能:描述参数的规范。
Full(String, Rune, ArgumentMode)
Full(String, Rune, ArgumentMode)
功能:表示同时存在长选项和短选项。
Full(String, Rune, ArgumentMode, (String) -> Unit)
Full(String, Rune, ArgumentMode, (String) -> Unit)
功能:表示同时存在长选项和短选项,并持有一个 lambda 回调函数。
Long(String, ArgumentMode)
Long(String, ArgumentMode)
功能:表示是一个长选项规格。
Long(String, ArgumentMode, (String) -> Unit)
Long(String, ArgumentMode, (String) -> Unit)
功能:表示是一个长选项,同时持有一个 lambda 回调函数。
NonOptions((Array<String>) -> Unit)
NonOptions((Array<String>) -> Unit)
功能:表示是一个非选项。
Short(Rune, ArgumentMode)
Short(Rune, ArgumentMode)
功能:表示是一个短选项。
Short(Rune, ArgumentMode, (String) -> Unit)
Short(Rune, ArgumentMode, (String) -> Unit)
功能:表示是一个短选项,同时持有一个 lambda 回调函数。
结构体
struct ParsedArguments
public struct ParsedArguments {
}
功能:存储参数解析的结果。
prop nonOptions
public prop nonOptions: Array<String>
功能:存储参数解析得到的非选项。
prop options
public prop options: ReadOnlyMap<String, String>
功能:存储参数解析得到的选项。
类型:ReadOnlyMap
异常
class ArgumentParseException
public class ArgumentParseException <: Exception {
public init()
public init(message: String)
}
功能:参数解析异常类。当参数解析出错(如:不识别的选项、缺少值的选项)时,抛出此异常。
父类型:
init()
public init()
功能:构造一个不带异常信息的实例。
init(String)
public init(message: String)
功能:根据异常信息构造异常实例。
参数:
- message: String - 异常信息。
命令行解析
不带回调
示例:
import std.env.*
import std.argopt.*
main(args: Array<String>): Unit {
let argSpecs = [
Short(r'a', NoValue),
Long("test1", RequiredValue),
Full("test2", r'c', OptionalValue)
]
try {
var result = parseArguments(args, argSpecs)
println("Got a: ${result.options.contains('a')}")
println("Test1: ${result.options.get("test1")}")
println("Test2: ${result.options.get("test2")}")
println("c: ${result.options.get('c')}")
println("NonOptions: ${result.nonOptions}")
} catch (e: ArgumentParseException) {
println("Usage: error")
return
}
}
运行结果:
$ cjc main.cj && ./main -a --test1 t1val
Got a: true
Test1: Some(t1val)
Test2: None
c: None
NonOptions: []
$ cjc main.cj && ./main -a --test1
Usage: error
$ cjc main.cj && ./main -a --test1 t1val --test2
Got a: true
Test1: Some(t1val)
Test2: Some()
c: None
NonOptions: []
$ cjc main.cj && ./main -a --test1 t1val --test2 t2val
Got a: true
Test1: Some(t1val)
Test2: Some()
c: None
NonOptions: [t2val]
$ cjc main.cj && ./main -a --test1 t1val -ct2val
Got a: true
Test1: Some(t1val)
Test2: None
c: Some(t2val)
NonOptions: []
带回调
示例:
import std.argopt.*
main(args: Array<String>): Unit {
let argSpecs = [
Short(r'a', NoValue) {_ => println("Got a")},
Long("test1", RequiredValue) {v => println("Got test1: `${v}`")},
Full("test2", r'c', OptionalValue) {v => println("Got test2: `${v}`")},
NonOptions {v => println("Got NonOptions: ${v}")}
]
try {
parseArguments(args, argSpecs)
} catch (e: ArgumentParseException) {
println("Usage: xxxx")
}
}
运行结果:
$ cjc main.cj && ./main -a --test1 t1val --test2 t2val
Got a
Got test1: `t1val`
Got test2: ``
Got NonOptions: [t2val]
长命令行参数解析 (deprecated)
示例:
import std.argopt.*
main() {
let shortArgs: Array<String> = ["--test1=abc", "--test2=123", "--test3 xyz"]
let shortArgName: String = ""
let longArgName: Array<String> = ["--test1=", "test2=", "--test3="]
let ao: ArgOpt = ArgOpt(shortArgs, shortArgName, longArgName)
println(ao.getArg("--test1") ?? "None")
println(ao.getArg("--test2") ?? "None")
println(ao.getArg("--test3") ?? "None")
}
运行结果:
abc
123
None
短命令行参数解析 (deprecated)
示例:
import std.argopt.*
main() {
let shortArgs: Array<String> = ["-a123", "-bofo", "-cccc"]
let shortArgName: String = "a:b:c"
let longArgName: Array<String> = Array<String>()
let ao: ArgOpt = ArgOpt(shortArgs, shortArgName, longArgName)
println(ao.getArg("-a") ?? "None")
println(ao.getArg("-b") ?? "None")
println(ao.getArg("-c") ?? "None")
}
运行结果:
123
ofo
None
std.ast
功能介绍
ast 包主要包含了仓颉源码的语法解析器和仓颉语法树节点,提供语法解析函数。可将仓颉源码的词法单元(Tokens)解析为抽象语法树(Abstract Syntax Tree)节点对象。
仓颉 ast 包提供了 Macro With Context 的相关函数,用于在宏展开时获取展开过程中的上下文相关信息。在嵌套宏场景下,内层宏可以调用库函数 assertParentContext(String) 来保证内层宏调用一定嵌套在特定的外层宏调用中。如果内层宏调用这个函数时没有嵌套在给定的外层宏调用中,该函数将抛出一个错误。同时,函数 insideParentContext(String) 也用于检查内层宏调用是否嵌套在特定的外层宏调用中,但是返回一个布尔值。Macro With Context 的相关函数只能作为函数被直接调用,不能赋值给变量,不能作为实参或返回值使用。
Macro With Context 相关函数如下:
- assertParentContext(String)
- getChildMessages(String)
- insideParentContext(String)
- setItem(String, Bool)
- setItem(String, Int64)
- setItem(String, String)
- setItem(String, Tokens)
API 列表
函数
| 函数名 | 功能 |
|---|---|
| assertParentContext(String) | 检查当前宏调用是否在特定的宏调用内。若检查不符合预期,编译器出现一个错误提示。 |
| cangjieLex(String) | 将字符串转换为 Tokens 类型。 |
| cangjieLex(String, Bool) | 将字符串转换为 Tokens 类型。 |
| compareTokens(Tokens, Tokens) | 用于比较两个 Tokens 是否一致。 |
| diagReport(DiagReportLevel, Tokens, String, String) | 报错接口,在编译过程的宏展开阶段输出错误提示信息,支持 WARNING 和 ERROR 两个等级的报错。 |
| getChildMessages(String) | 获取特定内层宏发送的信息。 |
| getTokenKind(UInt16) | 将词法单元种类序号转化为 TokenKind。 |
| insideParentContext(String) | 检查当前宏调用是否在特定的宏调用内,返回一个布尔值。 |
| parseDecl(Tokens, String) | 用于解析一组词法单元,获取一个 Decl 类型的节点。 |
| parseDeclFragment(Tokens, Int64) | 用于解析一组词法单元,获取一个 Decl 类型的节点和继续解析节点的索引。 |
| parseExpr(Tokens) | 用于解析一组词法单元,获取一个 Expr 类型的节点。 |
| parseExprFragment(Tokens, Int64) | 用于解析一组词法单元,获取一个 Expr 类型的节点和继续解析节点的索引。 |
| parsePattern(Tokens) | 用于解析一组词法单元,获取一个 Pattern 类型的节点。 |
| parsePatternFragment(Tokens, Int64) | 用于解析一组词法单元,获取一个 Pattern 类型的节点和继续解析节点的索引。 |
| parseProgram(Tokens) | 用于解析单个仓颉文件的源码,获取一个 Program 类型的节点。 |
| parseType(Tokens) | 用于解析一组词法单元,获取一个 TypeNode 类型的节点。 |
| parseTypeFragment(Tokens, Int64) | 用于解析一组词法单元,获取一个 TypeNode 类型的节点和继续解析节点的索引。 |
| setItem(String, Bool) | 内层宏通过该接口发送 Bool 类型的信息到外层宏。 |
| setItem(String, Int64) | 内层宏通过该接口发送 Int64 类型的信息到外层宏。 |
| setItem(String, String) | 内层宏通过该接口发送 String 类型的信息到外层宏。 |
| setItem(String, Tokens) | 内层宏通过该接口发送 Tokens 类型的信息到外层宏。 |
接口
类
| 类名 | 功能 |
|---|---|
| Annotation | 表示编译器内置的注解节点。 |
| Argument | 表示函数调用的实参节点。 |
| ArrayLiteral | 表示 Array 字面量节点。 |
| AsExpr | 表示一个类型检查表达式。 |
| AssignExpr | 表示赋值表达式节点。 |
| BinaryExpr | 表示一个二元操作表达式节点。 |
| Block | 表示块节点。 |
| Body | 表示 Class 类型、 Struct 类型、 Interface 类型以及扩展中由 {} 和内部的一组声明节点组成的结构。 |
| CallExpr | 表示函数调用节点节点。 |
| ClassDecl | 类定义节点。 |
| ConstPattern | 表示常量模式节点。 |
| Constructor | 表示 enum 类型中的 Constructor 节点。 |
| Decl | 所有声明节点的父类,继承自 Node 节点,提供了所有声明节点的通用接口。 |
| DoWhileExpr | 表示 do-while 表达式。 |
| EnumDecl | 表示一个 Enum 定义节点。 |
| EnumPattern | 表示 enum 模式节点。 |
| ExceptTypePattern | 表示一个用于异常模式状态下的节点。 |
| Expr | 所有表达式节点的父类,继承自 Node 节点。 |
| ExtendDecl | 表示一个扩展定义节点。 |
| ForInExpr | 表示 for-in 表达式。 |
| FuncDecl | 表示一个函数定义节点。 |
| FuncParam | 表示函数参数节点,包括非命名参数和命名参数。 |
| FuncType | 表示函数类型节点。 |
| GenericConstraint | 表示一个泛型约束节点。 |
| GenericParam | 表示一个类型形参节点。 |
| IfExpr | 表示条件表达式。 |
| ImportContent | 表示包导入节点中的导入项。 |
| ImportList | 表示包导入节点。 |
| IncOrDecExpr | 表示包含自增操作符(++)或自减操作符(--)的表达式。 |
| InterfaceDecl | 表示接口定义节点。 |
| IsExpr | 表示一个类型检查表达式。 |
| JumpExpr | 表示循环表达式的循环体中的 break 和 continue。 |
| LambdaExpr | 表示 Lambda 表达式,是一个匿名的函数。 |
| LetPatternExpr | 表示 let 声明的解构匹配节点。 |
| LitConstExpr | 表示一个常量表达式节点。 |
| MacroDecl | 表示一个宏定义节点。 |
| MacroExpandDecl | 表示宏调用节点。 |
| MacroExpandExpr | 表示宏调用节点。 |
| MacroExpandParam | 表示宏调用节点。 |
| MacroMessage | 记录内层宏发送的信息。 |
| MainDecl | 表示一个 main 函数定义节点。 |
| MatchCase | 表示 match 表达式中的一个 case 节点。 |
| MatchExpr | 表示模式匹配表达式实现模式匹配。 |
| MemberAccess | 表示成员访问表达式。 |
| Modifier | 表示该定义具备某些特性,通常放在定义处的最前端。 |
| Node | 所有仓颉语法树节点的父类。 |
| OptionalExpr | 表示一个带有问号操作符的表达式节点。 |
| PackageHeader | 表示包声明节点。 |
| ParenExpr | 表示一个括号表达式节点,是指使用圆括号括起来的表达式。 |
| ParenType | 表示括号类型节点。 |
| Pattern | 所有模式匹配节点的父类,继承自 Node 节点。 |
| PrefixType | 表示带问号的前缀类型节点。 |
| PrimaryCtorDecl | 表示一个主构造函数节点。 |
| PrimitiveType | 表示一个基本类型节点。 |
| PrimitiveTypeExpr | 表示基本类型表达式节点。 |
| Program | 表示一个仓颉源码文件节点。 |
| PropDecl | 表示一个属性定义节点。 |
| QualifiedType | 表示一个用户自定义成员类型。 |
| QuoteExpr | 表示 quote 表达式节点。 |
| QuoteToken | 表示 quote 表达式节点内任意合法的 token。 |
| RangeExpr | 表示包含区间操作符的表达式。 |
| RefExpr | 表示一个使用自定义类型节点相关的表达式节点。 |
| RefType | 表示一个用户自定义类型节点。 |
| ReturnExpr | 表示 return 表达式节点。 |
| SpawnExpr | 表示 Spawn 表达式。 |
| StructDecl | 表示一个 Struct 节点。 |
| SubscriptExpr | 表示索引访问表达式。 |
| SynchronizedExpr | 表示 synchronized 表达式。 |
| ThisType | 表示 This 类型节点。 |
| ThrowExpr | 表示 throw 表达式节点。 |
| Tokens | 对 Token 序列进行封装的类型。 |
| TokensIterator | 实现 Tokens 的迭代器功能。 |
| TrailingClosureExpr | 表示尾随 Lambda 节点。 |
| TryExpr | 表示 try 表达式节点。 |
| TupleLiteral | 表示元组字面量节点。 |
| TuplePattern | 表示 Tuple 模式节点。 |
| TupleType | 表示元组类型节点。 |
| TypeAliasDecl | 表示类型别名节点。 |
| TypeConvExpr | 表示类型转换表达式。 |
| TypeNode | 所有类型节点的父类,继承自 Node。 |
| TypePattern | 表示类型模式节点。 |
| UnaryExpr | 表示一个一元操作表达式节点。 |
| VArrayExpr | 表示 VArray 的实例节点。 |
| VArrayType | 表示 VArray 类型节点。 |
| VarDecl | 表示变量定义节点。 |
| VarOrEnumPattern | 表示当模式的标识符为 Enum 构造器时的节点。 |
| VarPattern | 表示绑定模式节点。 |
| Visitor | 一个抽象类,其内部默认定义了访问不同类型 AST 节点访问(visit)函数。 |
| WhileExpr | 表示 while 表达式。 |
| WildcardExpr | 表示通配符表达式节点。 |
| WildcardPattern | 表示通配符模式节点。 |
枚举
| 枚举名 | 功能 |
|---|---|
| DiagReportLevel | 表示报错接口的信息等级,支持 ERROR 和 WARNING 两种格式。 |
| ImportKind | 表示导入语句的类型,包括单导入、别名导入、全导入和多导入四种类型。 |
| TokenKind | 表示仓颉编译内部所有的词法结构,包括符号、关键字、标识符、换行等。 |
结构体
异常类
| 异常类名 | 功能 |
|---|---|
| ASTException | ast 库的异常类,在 ast 库调用过程中发生异常时使用。 |
| MacroContextException | ast 库的上下文宏异常类,在上下文宏的相关接口中发生异常时使用。 |
| ParseASTException | ast 库的解析异常类,在节点解析过程中发生异常时使用。 |
函数
func assertParentContext(String)
public func assertParentContext(parentMacroName: String): Unit
功能:检查当前宏调用是否在特定的宏调用内。若检查不符合预期,编译器出现一个错误提示。
注意:
该函数只能作为函数被直接调用,不能作为赋值给变量,不能作为实参或返回值使用。
参数:
- parentMacroName: String - 待检查的外层宏调用的名字。
func cangjieLex(String)
public func cangjieLex(code: String): Tokens
功能:将字符串转换为 Tokens 对象。
参数:
- code: String - 待词法解析的字符串。
返回值:
异常:
- IllegalMemoryException - 当申请内存失败时,抛出异常。
- IllegalArgumentException - 当输入的 code 无法被正确的解析为 Tokens 时,抛出异常。
func cangjieLex(String, Bool)
public func cangjieLex(code: String, truncated: Bool): Tokens
功能:将字符串转换为 Tokens 对象。
参数:
返回值:
异常:
- IllegalMemoryException - 当申请内存失败,抛出异常时,抛出异常。
- IllegalArgumentException - 当输入的 code 无法被正确的解析为 Tokens 时,抛出异常。
func compareTokens(Tokens, Tokens)
public func compareTokens(tokens1: Tokens, tokens2: Tokens): Bool
功能:用于比较两个Tokens是否一致。
参数:
返回值:
func diagReport(DiagReportLevel, Tokens, String, String)
public func diagReport(level: DiagReportLevel, tokens: Tokens, message: String, hint: String): Unit
功能:报错接口,在编译过程的宏展开阶段输出错误提示信息,支持 WARNING 和 ERROR 两个等级的报错。
注意:
参数:
- level: DiagReportLevel - 报错信息等级。
- tokens: Tokens - 报错信息中所引用源码内容对应的 Tokens。
- message: String - 报错的主信息。
- hint: String - 辅助提示信息。
异常:
-
ASTException - 当输入的 Tokens 存在以下错误时,抛出异常。
func getChildMessages(String)
public func getChildMessages(children:String): ArrayList<MacroMessage>
功能:获取特定内层宏发送的信息。
注意:
该函数只能作为函数被直接调用,不能作为赋值给变量,不能作为实参或返回值使用。
参数:
- children: String - 待接收信息的内层宏名称。
返回值:
- ArrayList<MacroMessage> - 返回一组 MacroMessage 的对象。
func getTokenKind(UInt16)
public func getTokenKind(no: UInt16): TokenKind
功能:将词法单元种类序号转化为 TokenKind。
参数:
- no: UInt16 - 需要转换的序号。
返回值:
注意:
当前 SINGLE_QUOTED_STRING_LITERAL 和 STRING_LITERAL 共用序号 147,输入序号 147 只能获得 STRING_LITERAL,其他 TokenKind 无共用序号情况。
func insideParentContext(String)
public func insideParentContext(parentMacroName: String): Bool
功能:检查当前宏调用是否在特定的宏调用内,返回一个布尔值。
注意:
- 在嵌套宏场景下,内层宏也可以通过发送键/值对的方式与外层宏通信。当内层宏执行时,通过调用标准库函数 setItem 向外层宏发送信息;随后,当外层宏执行时,调用标准库函数 getChildMessages 接收每一个内层宏发送的信息(一组键/值对映射)。
- 该函数只能作为函数被直接调用,不能作为赋值给变量,不能作为实参或返回值使用。
参数:
- parentMacroName: String - 待检查的外层宏调用的名字。
返回值:
- Bool - 若当前宏嵌套在特定的宏调用内,返回 true。
func parseDecl(Tokens, String)
public func parseDecl(input: Tokens, astKind!: String = ""): Decl
功能:用于解析一组词法单元,获取一个 Decl 类型的节点。
注意:
该函数不支持解析 FuncParam 类型。
参数:
- input: Tokens - 待解析源码的词法单元。
- astKind!: String - 用于指定解析特定的节点类型,有效支持的值为:
PrimaryCtorDecl和PropMemberDecl。PrimaryCtorDecl: 解析主构造函数。PropMemberDecl: 解析prop声明的getter和setter函数。
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 Decl 节点时,抛出异常,异常中包含报错提示信息。
示例:
-
以下代码展示
astKind设为PropMemberDecl的案例。在这个参数下,可以使用parseDecl解析prop的getter和setter函数,解析结果为FuncDecl类型(如果不设置astKind,则会因为没有func关键字而无法解析)。import std.ast.* main() { let getter = quote( get() { _val } ) let setter = quote( set(v) { _val = v }) let getterDecl = parseDecl(getter, astKind: "PropMemberDecl") let setterDecl = parseDecl(setter, astKind: "PropMemberDecl") println((getterDecl as FuncDecl).getOrThrow().block.toTokens()) println((setterDecl as FuncDecl).getOrThrow().block.toTokens()) }运行结果:
{ _val } { _val = v } -
以下代码展示
astKind设为PrimaryCtorDecl的案例。在这个参数下,可以使用parseDecl解析主构造函数节点,解析结果为PrimaryCtorDecl类型(如果不设置astKind,则会因为没有func关键字而无法解析)。import std.ast.* main() { let ctor = quote( Point(var x: Int32, var y: Int32) {} ) let ctorDecl = parseDecl(ctor, astKind: "PrimaryCtorDecl") println(ctorDecl is PrimaryCtorDecl) println(ctorDecl.toTokens()) }运行结果:
true Point(var x: Int32, var y: Int32) { }
func parseDeclFragment(Tokens, Int64)
public func parseDeclFragment(input: Tokens, startFrom !: Int64 = 0): (Decl, Int64)
功能:用于解析一组词法单元,获取一个 Decl 类型的节点和继续解析节点的索引。
注意:
该函数不支持解析 FuncParam、 PropDecl、PrimaryCtorDecl 类型。
参数:
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 Decl 节点时,抛出异常,异常中包含报错提示信息。
func parseExpr(Tokens)
public func parseExpr(input: Tokens): Expr
功能:用于解析一组词法单元,获取一个 Expr 类型的节点。
参数:
- input: Tokens - 待解析源码的词法单元。
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 Expr 节点时,抛出异常,异常中包含报错提示信息。
func parseExprFragment(Tokens, Int64)
public func parseExprFragment(input: Tokens, startFrom !: Int64 = 0): (Expr, Int64)
功能:用于解析一组词法单元,获取一个 Expr 类型的节点和继续解析节点的索引。
参数:
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 Expr 节点时,抛出异常,异常中包含报错提示信息。
func parsePattern(Tokens)
public func parsePattern(input: Tokens): Pattern
功能:用于解析一组词法单元,获取一个 Pattern 类型的节点。
参数:
- input: Tokens - 待解析源码的词法单元。
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 Pattern 节点时,抛出异常,异常中包含报错提示信息。
func parsePatternFragment(Tokens, Int64)
public func parsePatternFragment(input: Tokens, startFrom !: Int64 = 0): (Pattern, Int64)
功能:用于解析一组词法单元,获取一个 Pattern 类型的节点和继续解析节点的索引。
参数:
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 Pattern 节点时,抛出异常,异常中包含报错提示信息。
func parseProgram(Tokens)
public func parseProgram(input: Tokens): Program
功能:用于解析单个仓颉文件的源码,获取一个 Program 类型的节点。
参数:
- input: Tokens - 待解析源码的词法单元。
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 Program 节点时,抛出异常,异常中包含报错提示信息。
func parseType(Tokens)
public func parseType(input: Tokens): TypeNode
功能:用于解析一组词法单元,获取一个 TypeNode 类型的节点。
参数:
- input: Tokens - 待解析源码的词法单元。
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 TypeNode 节点时,抛出异常。
func parseTypeFragment(Tokens, Int64)
public func parseTypeFragment(input: Tokens, startFrom !: Int64 = 0): (TypeNode, Int64)
功能:用于解析一组词法单元,获取一个 TypeNode 类型的节点和继续解析节点的索引。
参数:
返回值:
异常:
- ParseASTException - 当输入的 Tokens 类型无法构造为 TypeNode 节点时,抛出异常。
func setItem(String, Bool)
public func setItem(key: String, value: Bool): Unit
功能:内层宏通过该接口发送 Bool 类型的信息到外层宏。
注意:
该函数只能作为函数被直接调用,不能作为赋值给变量,不能作为实参或返回值使用。
参数:
func setItem(String, Int64)
public func setItem(key: String, value: Int64): Unit
功能:内层宏通过该接口发送 Int64 类型的信息到外层宏。
注意:
该函数只能作为函数被直接调用,不能作为赋值给变量,不能作为实参或返回值使用。
参数:
func setItem(String, String)
public func setItem(key: String, value: String): Unit
功能:内层宏通过该接口发送 String 类型的信息到外层宏。
注意:
该函数只能作为函数被直接调用,不能作为赋值给变量,不能作为实参或返回值使用。
参数:
func setItem(String, Tokens)
public func setItem(key: String, value: Tokens): Unit
功能:内层宏通过该接口发送 Tokens 类型的信息到外层宏。
注意:
该函数只能作为函数被直接调用,不能作为赋值给变量,不能作为实参或返回值使用。
参数:
接口
interface ToBytes
public interface ToBytes {
func toBytes(): Array<UInt8>
}
功能:提供对应类型的序列化功能。
func toBytes()
func toBytes(): Array<UInt8>
功能:提供对应类型的序列化功能。
返回值:
interface ToTokens
public interface ToTokens {
func toTokens(): Tokens
}
功能:实现对应类型的实例到 Tokens 类型转换的接口,作为支持 quote 插值操作必须实现的接口。
func toTokens()
func toTokens(): Tokens
功能:实现对应类型的实例到 Tokens 类型的转换。
返回值:
extend Array <: ToTokens
extend<T> Array<T> <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 Array 类型到 Tokens 类型的转换,仅支持数值类型、Rune 类型、Bool 类型、String 类型。
返回值:
extend ArrayList <: ToTokens
extend<T> ArrayList<T> <: ToTokens
功能:实现 ArrayList 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 ArrayList 类型到 Tokens 类型的转换,目前支持的类型有 Decl、Node、Constructor、Argument、FuncParam、MatchCase、Modifier、Annotation、ImportList、Pattern、TypeNode 等。
返回值:
extend Bool <: ToTokens
extend Bool <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
返回值:
extend Float16 <: ToTokens
extend Float16 <: ToTokens
功能:实现 Float16 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 Float16 类型到 Tokens 类型的转换。
返回值:
extend Float32 <: ToTokens
extend Float32 <: ToTokens
功能:实现 Float32 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 Float32 类型到 Tokens 类型的转换。
返回值:
extend Float64 <: ToTokens
extend Float64 <: ToTokens
功能:实现 Float64 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 Float64 类型到 Tokens 类型的转换。
返回值:
extend Int16 <: ToTokens
extend Int16 <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
返回值:
extend Int32 <: ToTokens
extend Int32 <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
返回值:
extend Int64 <: ToTokens
extend Int64 <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
返回值:
extend Int8 <: ToTokens
extend Int8 <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
返回值:
extend Rune <: ToTokens
extend Rune <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
返回值:
extend String <: ToTokens
extend String <: ToTokens
功能:实现 String 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 String 类型到 Tokens 类型的转换。
返回值:
extend Token <: ToTokens
extend Token <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
返回值:
extend Tokens <: ToTokens
extend Tokens <: ToTokens
功能:实现 Tokens 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 Tokens 类型到 Tokens 类型的转换。
返回值:
extend UInt16 <: ToTokens
extend UInt16 <: ToTokens
功能:实现 UInt16 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 UInt16 类型到 Tokens 类型的转换。
返回值:
extend UInt32 <: ToTokens
extend UInt32 <: ToTokens
功能:实现 UInt32 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 UInt32 类型到 Tokens 类型的转换。
返回值:
extend UInt64 <: ToTokens
extend UInt64 <: ToTokens
功能:实现 UInt64 类型到 Tokens 类型的转换。
父类型:
func toTokens()
public func toTokens(): Tokens
功能:实现 UInt64 类型到 Tokens 类型的转换。
返回值:
extend UInt8 <: ToTokens
extend UInt8 <: ToTokens
父类型:
func toTokens()
public func toTokens(): Tokens
返回值:
类
class Annotation
public class Annotation <: Node {
public init()
public init(inputs: Tokens)
}
功能:表示编译器内置的注解节点。
一个 Annotation 节点:@CallingConv[xxx], @Attribute[xxx], @When[condition]等。
父类型:
prop arguments
public mut prop arguments: ArrayList<Argument>
功能:获取或设置 Annotation 中的参数序列,如 @CallingConv[xxx] 中的 xxx。
prop at
public mut prop at: Token
功能:获取或设置 Annotation 节点中的 @ 操作符或 @! 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
@操作符或@!操作符时,抛出异常。
prop attributes
public mut prop attributes: Tokens
功能:获取或设置 Attribute 中设置的属性值,仅用于 @Attribute,如 @Attribute[xxx] 中的 xxx。
类型:Tokens
prop condition
public mut prop condition: Expr
功能:获取或设置条件编译中的条件表达式,用于 @When,如 @When[xxx] 中的 xxx。
类型:Expr
异常:
- ASTException - 当 Annotation 节点中没有条件表达式时,抛出异常。
prop identifier
public mut prop identifier: Token
功能:获取或设置 Annotation 节点的标识符,如 @CallingConv[xxx] 中的 CallingConv。
类型:Token
init()
public init()
功能:构造一个默认的 Annotation 对象。
init(Tokens)
public init(inputs: Tokens)
功能:根据输入的词法单元,构造一个 Annotation 对象。
参数:
- inputs: Tokens - 将要构造 Annotation 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 Annotation 节点时,抛出异常。
class Argument
public class Argument <: Node {
public init()
}
功能:表示函数调用的实参节点。
例如 foo(arg:value) 中的 arg:value。
父类型:
prop colon
public mut prop colon: Token
功能:获取或设置 Argument 节点中的操作符 ":",可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ":" 操作符时,抛出异常。
prop expr
public mut prop expr: Expr
功能:获取或设置 Argument 节点中的表达式,如 arg:value 中的 value。
类型:Expr
prop identifier
public mut prop identifier: Token
功能:获取或设置 Argument 节点中的标识符,如 arg:value 中的 arg,可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当获取和设置的 Token 类型不是 IDENTIFIER 标识符或 Token 的字面量值是空时,抛出异常。
prop keyword
public mut prop keyword: Token
功能:获取或设置 Argument 节点中的关键字 inout,可能为 ILLEGAL 的词法单元。
类型:Token
init()
public init()
功能:构造一个默认的 Argument 对象。
class ArrayLiteral
public class ArrayLiteral <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 Array 字面量节点。
ArrayLiteral 节点:使用格式 [element1, element2, ... , elementN] 表示, 每个 element 是一个表达式。
父类型:
prop elements
public mut prop elements: ArrayList<Expr>
功能:获取或设置 ArrayLiteral 中的表达式列表。
prop lSquare
public mut prop lSquare: Token
功能:获取或设置 ArrayLiteral 中的 "["。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "[" 时,抛出异常。
prop rSquare
public mut prop rSquare: Token
功能:获取或设置 ArrayLiteral 中的 "]"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "]" 时,抛出异常。
init()
public init()
功能:构造一个默认的 ArrayLiteral 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ArrayLiteral 对象。
参数:
- inputs: Tokens - 将要构造 ArrayLiteral 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ArrayLiteral 节点时,抛出异常。
class AsExpr
public class AsExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示一个类型检查表达式。
一个 AsExpr 表达式:e as T,类型为 Option<T>。其中 e 可以是任何类型的表达式,T 可以是任何类型。
父类型:
prop expr
public mut prop expr: Expr
功能:获取或设置 AsExpr 节点中的表达式节点。
类型:Expr
prop keyword
public mut prop keyword: Token
功能:获取或设置 AsExpr 节点中的 as 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
as操作符时,抛出异常。
prop shiftType
public mut prop shiftType: TypeNode
功能:获取或设置 AsExpr 节点中的目标类型。
类型:TypeNode
init()
public init()
功能:构造一个默认的 AsExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 AsExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 AsExpr 节点时,抛出异常。
class AssignExpr
public class AssignExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示赋值表达式节点。
用于将左操作数的值修改为右操作数的值。一个 AssignExpr 节点:a = b。
父类型:
prop assign
public mut prop assign: Token
功能:获取或设置 AssignExpr 节点中的赋值操作符(如 = 等)。
类型:Token
异常:
- ASTException - 当设置的 Token 不是赋值操作符时,抛出异常。
prop leftExpr
public mut prop leftExpr: Expr
功能:获取或设置 AssignExpr 节点中的左操作数。
类型:Expr
prop rightExpr
public mut prop rightExpr: Expr
功能:获取或设置 AssignExpr 节点中的右操作数。
类型:Expr
init()
public init()
功能:构造一个默认的 AssignExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 AssignExpr 对象。
参数:
- inputs: Tokens - 将要构造 AssignExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 AssignExpr 节点时,抛出异常。
class BinaryExpr
public class BinaryExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示一个二元操作表达式节点。
一个 BinaryExpr 节点:a + b, a - b 等。
父类型:
prop leftExpr
public mut prop leftExpr: Expr
功能:获取或设置 BinaryExpr 节点中操作符左侧的表达式节点。
类型:Expr
prop op
public mut prop op: Token
功能:获取或设置 BinaryExpr 节点中的二元操作符。
类型:Token
prop rightExpr
public mut prop rightExpr: Expr
功能:获取或设置 BinaryExpr 节点中操作符右侧的表达式节点。
类型:Expr
init()
public init()
功能:构造一个默认的 BinaryExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 BinaryExpr 对象。
参数:
- inputs: Tokens - 将要构造 BinaryExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 BinaryExpr 节点时,抛出异常。
class Block
public class Block <: Expr {
public init()
}
功能:表示块节点。
Block 由一对匹配的大括号及其中可选的表达式声明序列组成的结构,简称 “块”。
父类型:
prop lBrace
public mut prop lBrace: Token
功能:获取或设置 Block 的 "{"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "{" 时,抛出异常。
prop nodes
public mut prop nodes: ArrayList<Node>
功能:获取或设置 Block 中的表达式或声明序列。
prop rBrace
public mut prop rBrace: Token
功能:获取或设置 Block 的 "}"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "}" 时,抛出异常。
init()
public init()
功能:构造一个默认的 Block 对象。
说明:
Block 节点无法脱离表达式或声明节点单独存在,因此不提供其他的构造函数。
class Body
public class Body <: Node {
public init()
public init(decls: ArrayList<Decl>)
}
功能:表示 Class 类型、 Struct 类型、 Interface 类型以及扩展中由 {} 和内部的一组声明节点组成的结构。
父类型:
prop decls
public mut prop decls: ArrayList<Decl>
功能:获取或设置 Body 内的声明节点集合。
prop lBrace
public mut prop lBrace: Token
功能:获取或设置 { 词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
{词法单元时,抛出异常。
prop rBrace
public mut prop rBrace: Token
功能:获取或设置 } 词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
}词法单元时,抛出异常。
init()
public init()
功能:构造一个默认的 Body 对象。
init(ArrayList<Decl>)
public init(decls: ArrayList<Decl>)
功能:构造一个 Body 对象。
参数:
class CallExpr
public class CallExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示函数调用节点节点。
一个 CallExpr 节点包括一个表达式后面紧跟参数列表,例如 foo(100)。
父类型:
prop arguments
public mut prop arguments: ArrayList<Argument>
功能:获取或设置 CallExpr 节点中函数参数。
prop callFunc
public mut prop callFunc: Expr
功能:获取或设置 CallExpr 节点中的函数调用节点。
类型:Expr
prop lParen
public mut prop lParen: Token
功能:获取或设置 CallExpr 节点中的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 CallExpr 节点中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 CallExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 CallExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 CallExpr 节点时,抛出异常。
class ClassDecl
public class ClassDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:类定义节点。
类的定义使用 class 关键字,定义依次为:可缺省的修饰符、class 关键字、class 名、可选的类型参数、是否指定父类或父接口、可选的泛型约束、类体的定义。
父类型:
prop body
public mut prop body: Body
功能:获取或设置 ClassDecl 节点的类体。
类型:Body
prop superTypeBitAnds
public mut prop superTypeBitAnds: Tokens
功能:获取或设置 ClassDecl 节点的父类或父接口声明中的 & 操作符的词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是
&词法单元序列时,抛出异常。
prop superTypes
public mut prop superTypes: ArrayList<TypeNode>
功能:获取或设置 ClassDecl 节点的父类或者父接口。
prop upperBound
public mut prop upperBound: Token
功能:获取或设置 <: 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
<:操作符时,抛出异常。
init()
public init()
功能:构造一个默认的 ClassDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ClassDecl 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ClassDecl 节点时,抛出异常。
class ConstPattern
public class ConstPattern <: Pattern {
public init()
public init(inputs: Tokens)
}
功能:表示常量模式节点。
常量模式可以是整数字面量、字符字节字面量、浮点数字面量、字符字面量、布尔字面量、字符串字面量等字面量,如 case 1 => 0 中的 1。
父类型:
prop litConstExpr
public mut prop litConstExpr: LitConstExpr
功能:获取或设置 ConstPattern 节点中的字面量表达式。
类型:LitConstExpr
init()
public init()
功能:构造一个默认的 ConstPattern 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ConstPattern 对象。
参数:
- inputs: Tokens - 将要构造 ConstPattern 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ConstPattern 节点时,抛出异常。
class Constructor
public class Constructor <: Node {
public init()
}
功能:表示 enum 类型中的 Constructor 节点。
一个 Constructor 节点:enum TimeUnit { Year | Month(Float32, Float32)} 中的 Year 和 Month(Float32, Float32)。
说明:
Constructor 可以没有参数,也可以有一组不同类型的参数。
父类型:
prop identifier
public mut prop identifier: Token
功能:获取或设置 Constructor 的标识符词法单元。
类型:Token
prop lParen
public mut prop lParen: Token
功能:获取或设置 Constructor 节点中的 "(" 词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 Constructor 节点中的 ")" 词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop typeArguments
public mut prop typeArguments: ArrayList<TypeNode>
功能:获取或设置 Constructor 节点可选的参数类型节点的集合。
init()
public init()
功能:构造一个默认的 Constructor 对象。
class Decl
public open class Decl <: Node
功能:所有声明节点的父类,继承自 Node 节点,提供了所有声明节点的通用接口。
说明:
类定义、接口定义、函数定义、变量定义、枚举定义、结构体定义、扩展定义、类型别名定义、宏定义等都属于 Decl 节点。
父类型:
prop annotations
public mut prop annotations: ArrayList<Annotation>
功能:获取或设置作用于 Decl 节点的注解列表。
类型:ArrayList<Annotation>
prop constraintCommas
public mut prop constraintCommas: Tokens
功能:获取或设置 Decl 节点中的 "," 词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop genericConstraint
public mut prop genericConstraint: ArrayList<GenericConstraint>
功能:获取或设置定义节点的泛型约束,可能为空,如 func foo<T>() where T <: Comparable<T> {} 中的 where T <: Comparable<T>。
类型:ArrayList<GenericConstraint>
prop genericParam
public mut prop genericParam: GenericParam
功能:获取或设置形参列表,类型形参列表由 <> 括起,多个类型形参之间用逗号分隔。
类型:GenericParam
异常:
- ASTException - 当节点未定义类型形参列表时,抛出异常。
prop identifier
public mut open prop identifier: Token
功能:获取或设置定义节点的标识符,如 class foo {} 中的 foo。
类型:Token
prop isGenericDecl
public mut prop isGenericDecl: Bool
功能:判断是否是一个泛型节点。
类型:Bool - 是一个泛型节点为 true;反之为 false。
prop keyword
public mut prop keyword: Token
功能:获取或设置定义节点的关键字。
类型:Token
prop modifiers
public mut prop modifiers: ArrayList<Modifier>
功能:获取或设置修饰节点的修饰符列表。
func getAttrs()
public func getAttrs(): Tokens
功能:获取当前节点的属性(一般通过内置的 Attribute 来设置某个声明设置属性值)。
返回值:
- Tokens - 当前节点的属性。
func hasAttr(String)
public func hasAttr(attr: String): Bool
功能:判断当前节点是否具有某个属性(一般通过内置的 Attribute 来设置某个声明的属性值)。
参数:
- attr: String - 将要判断是否存在于该节点的属性。
返回值:
- Bool - 当前节点具有该属性时,返回 true;反之,返回 false。
class DoWhileExpr
public class DoWhileExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 do-while 表达式。
父类型:
prop block
public mut prop block: Block
功能:获取或设置 DoWhileExpr 中的块表达式。
类型:Block
prop condition
public mut prop condition: Expr
功能:获取或设置关键字 DoWhileExpr 中的条件表达式。
类型:Expr
prop keywordD
public mut prop keywordD: Token
功能:获取或设置 DoWhileExpr 节点中 do 关键字,其中 keywordD 中的 D 为关键字 do 的首字母大写,代表关键字 do 。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
do关键字时,抛出异常。
prop keywordW
public mut prop keywordW: Token
功能:获取或设置 DoWhileExpr 节点中 while 关键字,其中 keywordW 中的 W 为关键字 while 的首字母大写,代表关键字 while 。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
while关键字时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 DoWhileExpr 中 while 关键字之后的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 DoWhileExpr 中 while 关键字之后的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 DoWhileExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 DoWhileExpr 对象。
参数:
- inputs: Tokens - 将要构造 DoWhileExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 DoWhileExpr 节点时,抛出异常。
class EnumDecl
public class EnumDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示一个 Enum 定义节点。
Enum 的定义使用 enum 关键字,定义依次为:可缺省的修饰符、enum 关键字、enum 名、可选的类型参数、是否指定父接口、可选的泛型约束、enum 体的定义。
父类型:
prop constructors
public mut prop constructors: ArrayList<Constructor>
功能:获取或设置 EnumDecl 节点内 constructor 的成员。
类型:ArrayList<Constructor>
prop annotations
public mut prop annotations: ArrayList<Annotation>
功能:获取或设置作用于 EnumDecl 节点的注解列表。
类型:ArrayList<Annotation>
prop decls
public mut prop decls: ArrayList<Decl>
功能:获取或设置 EnumDecl 节点内除 constructor 的其他成员。
prop ellipsis
public mut prop ellipsis: Token
功能:获取或设置 EnumDecl 节点中可选的 ... 词法单元,可能为 ILLEGAL 的词法单元类型。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
...词法单元时,抛出异常。
prop lBrace
public mut prop lBrace: Token
功能:获取或设置 EnumDecl 节点的 { 词法单元类型。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
{词法单元类型时,抛出异常。
prop rBrace
public mut prop rBrace: Token
功能:获取或设置 EnumDecl 节点的 } 词法单元类型。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
}词法单元类型时,抛出异常。
prop superTypeBitAnds
public mut prop superTypeBitAnds: Tokens
功能:获取或设置 EnumDecl 节点的父接口声明中的 & 操作符的词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是
&词法单元序列时,抛出异常。
prop superTypes
public mut prop superTypes: ArrayList<TypeNode>
功能:获取或设置 EnumDecl 节点的父接口。
prop upperBound
public mut prop upperBound: Token
功能:获取或设置 <: 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
<:操作符时,抛出异常。
init()
public init()
功能:构造一个默认的 EnumDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 EnumDecl 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 EnumDecl 节点时,抛出异常。
class EnumPattern
public class EnumPattern <: Pattern {
public init()
public init(inputs: Tokens)
}
功能:表示 enum 模式节点。
用于匹配 enum 的 constructor, 如 case Year(n) => 1 中的 Year(n)。
父类型:
prop commas
public mut prop commas: Tokens
功能:获取或设置 EnumPattern 节点中的 "," 词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop constructor
public mut prop constructor: Expr
功能:获取或设置 EnumPattern 节点中的构造器表达式节点。
类型:Expr
prop lParen
public mut prop lParen: Token
功能:获取或设置 EnumPattern 节点中的 "(" 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop patterns
public mut prop patterns: ArrayList<Pattern>
功能:获取或设置 EnumPattern 节点中有参构造器内的模式节点列表。
prop rParen
public mut prop rParen: Token
功能:获取或设置 EnumPattern 节点中的 ")" 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 EnumPattern 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 EnumPattern 对象。
参数:
- inputs: Tokens - 将要构造 EnumPattern 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 EnumPattern 节点时,抛出异常。
class ExceptTypePattern
public class ExceptTypePattern <: Pattern {
public init()
public init(inputs: Tokens)
}
功能:表示一个用于异常模式状态下的节点。
例如 e: Exception1 | Exception2。
父类型:
prop colon
public mut prop colon: Token
功能:获取或设置 ExceptTypePattern 节点中的 ":" 操作符的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ":" 操作符时,抛出异常。
prop pattern
public mut prop pattern: Pattern
功能:获取或设置 ExceptTypePattern 节点中的模式节点。
类型:Pattern
prop types
public mut prop types: ArrayList<TypeNode>
功能:获取或设置 ExceptTypePattern 节点中有类型列表。
init()
public init()
功能:构造一个默认的 ExceptTypePattern 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ExceptTypePattern 对象。
参数:
- inputs: Tokens - 将要构造 ExceptTypePattern 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ExceptTypePattern 节点时,抛出异常。
class Expr
public open class Expr <: Node
功能:所有表达式节点的父类,继承自 Node 节点。
表达式节点的 toTokens 方法会根据操作符优先级添加括号,例如已有一个 BinaryExpr 节点 a * b, 用户将左表达式内容 a 修改为 a + 1,修改后 toTokens 方法会为左表达式添加括号,toTokens 输出为 (a + 1) * b。
父类型:
class ExtendDecl
public class ExtendDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示一个扩展定义节点。
扩展的定义使用 extend 关键字,扩展定义依次为:extend 关键字、扩展类型、是否指定父接口、可选的泛型约束、扩展体的定义。
父类型:
prop body
public mut prop body: Body
功能:获取或设置 ExtendDecl 节点的类体。
类型:Body
prop extendType
public mut prop extendType: TypeNode
功能:获取或设置被扩展的类型。
类型:TypeNode
prop identifier
public mut override prop identifier: Token
功能:ExtendDecl 节点继承 Decl 节点,但是不支持 identifier 属性,使用时会抛出异常。
类型:Token
异常:
- ASTException - 当使用
identifier属性时,抛出异常。
prop superTypeBitAnds
public mut prop superTypeBitAnds: Tokens
功能:获取或设置 ExtendDecl 节点的父接口声明中的 & 操作符的词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是
&词法单元序列时,抛出异常。
prop superTypes
public mut prop superTypes: ArrayList<TypeNode>
功能:获取或设置 ExtendDecl 节点的父接口。
prop upperBound
public mut prop upperBound: Token
功能:获取或设置 <: 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
<:操作符时,抛出异常。
init()
public init()
功能:构造一个默认的 ExtendDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ExtendDecl 对象。
参数:
- inputs: Tokens - 将要构造 ExtendDecl 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ExtendDecl 节点时,抛出异常。
class ForInExpr
public class ForInExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 for-in 表达式。
ForInExpr 类型中,关键字 for 之后是 Pattern, 此后是一个 in 关键字和表达式节点,最后是一个执行循环体 Block。
父类型:
prop block
public mut prop block: Block
功能:获取或设置 ForInExpr 中的循环体。
类型:Block
prop expr
public mut prop expr: Expr
功能:获取或设置 ForInExpr 中的表达式。
类型:Expr
prop keywordF
public mut prop keywordF: Token
功能:获取或设置 ForInExpr 中的关键字 for。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
for关键字时,抛出异常。
prop keywordI
public mut prop keywordI: Token
功能:获取或设置 ForInExpr 中的关键字 in。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
in关键字时,抛出异常。
prop keywordW
public mut prop keywordW: Token
功能:获取或设置 ForInExpr 中的关键字 where。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
where关键字时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 ForInExpr 中关键字 for 后的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop pattern
public mut prop pattern: Pattern
功能:获取或设置 ForInExpr 中的 Pattern 节点。
类型:Pattern
prop patternGuard
public mut prop patternGuard: Expr
功能:获取或设置 ForInExpr 中的 patternGuard 条件表达式。
类型:Expr
异常:
- ASTException - 当 ForInExpr 节点中不存在
patternGuard表达式时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 ForInExpr 中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 ForInExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ForInExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ForInExpr 节点时,抛出异常。
class FuncDecl
public class FuncDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示一个函数定义节点。
由可选的函数修饰符,关键字 func ,函数名,可选的类型形参列表,函数参数,可缺省的函数返回类型来定义一个函数,函数定义时必须有函数体,函数体是一个块。
父类型:
prop block
public mut prop block: Block
功能:获取或设置 FuncDecl 节点的函数体。
类型:Block
prop colon
public mut prop colon: Token
功能:获取或设置 FuncDecl 节点的冒号。
类型:Token
异常:
- ASTException - 当设置的 Token 不是冒号时,抛出异常。
prop declType
public mut prop declType: TypeNode
功能:获取或设置 FuncDecl 节点的函数返回类型。
类型:TypeNode
异常:
- ASTException - 当 FuncDecl 节点的函数返回类型是一个缺省值时,抛出异常。
prop funcParams
public mut prop funcParams: ArrayList<FuncParam>
功能:获取或设置 FuncDecl 节点的函数参数。
prop lParen
public mut prop lParen: Token
功能:获取或设置 FuncDecl 节点的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop overloadOp
public mut prop overloadOp: Tokens
功能:获取或设置 FuncDecl 节点的重载操作符。
类型:Tokens
prop rParen
public mut prop rParen: Token
功能:获取或设置 FuncDecl 节点的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 FuncDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 FuncDecl 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 FuncDecl 节点时,抛出异常。
func isConst()
public func isConst(): Bool
功能:判断是否是一个 Const 类型的节点。
返回值:
- Bool - 是一个
Const类型的节点返回 true;反之,返回 false。
class FuncParam
public open class FuncParam <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示函数参数节点,包括非命名参数和命名参数。
一个 FuncParam 节点: func foo(a: Int64, b: Float64) {...} 中的 a: Int64 和 b: Float64。
父类型:
prop assign
public mut prop assign: Token
功能:获取或设置具有默认值的函数参数中的 =。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
=时,抛出异常。
prop colon
public mut prop colon: Token
功能:获取或设置置形参中的 ":"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ":" 时,抛出异常。
prop expr
public mut prop expr: Expr
功能:获取或设置具有默认值的函数参数的变量初始化节点。
类型:Expr
异常:
- ASTException - 当函数参数没有进行初始化时,抛出异常。
prop not
public mut prop not: Token
功能:获取或设置命名形参中的 !。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
!时,抛出异常。
prop paramType
public mut prop paramType: TypeNode
功能:获取或设置函数参数的类型。
类型:TypeNode
init()
public init()
功能:构造一个默认的 FuncParam 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 FuncParam 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 FuncParam 节点时,抛出异常。
func isMemberParam()
public func isMemberParam(): Bool
功能:当前的函数参数是否是主构造函数中的参数。
返回值:
- Bool - 布尔类型,如果是主构造函数中的参数,返回
true。
class FuncType
public class FuncType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示函数类型节点。
由函数的参数类型和返回类型组成,参数类型与返回类型之间用 -> 分隔,如:(Int32) -> Unit。
父类型:
prop arrow
public mut prop arrow: Token
功能:获取或设置 FuncType 节点参数类型与返回类型之间的 ->的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
->的词法单元时,抛出异常。
prop commas
public mut prop commas: Tokens
功能:获取或设置 FuncType 节点中的 "," 词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop keyword
public mut prop keyword: Token
功能:获取或设置 FuncType 节点的中的关键字 CFunc 的词法单元,若不是一个 CFunc 类型,则获取一个 ILLEGAL 的词法单元。
类型:Token
prop lParen
public mut prop lParen: Token
功能:获取或设置 FuncType 节点的 "(" 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 FuncType 节点的 ")" 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop returnType
public mut prop returnType: TypeNode
功能:获取或设置 FuncType 返回类型节点。
类型:TypeNode
prop types
public mut prop types: ArrayList<TypeNode>
功能:获取或设置 FuncType 节点中函数的参数类型列表。
init()
public init()
功能:构造一个默认的 FuncType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 FuncType 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 FuncType 节点时,抛出异常。
class GenericConstraint
public class GenericConstraint <: Node {
public init()
}
功能:表示一个泛型约束节点。
一个 GenericConstraint 节点:interface Enumerable<U> where U <: Bounded {} 中的 where U <: Bounded。
说明:
通过
where之后的<:运算符来声明,由一个下界与一个上界来组成。其中<:左边称为约束的下界,下界只能为类型变元。<:右边称为约束上界,约束上界可以为类型。
父类型:
prop bitAnds
public mut prop bitAnds: Tokens
功能:获取或设置 GenericConstraint 节点中的 & 操作符的词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是
&词法单元序列时,抛出异常。
prop keyword
public mut prop keyword: Token
功能:获取或设置 GenericConstraint 节点中关键字 where 词法单元,可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
where关键字时,抛出异常。
prop typeArgument
public mut prop typeArgument: TypeNode
功能:获取或设置 GenericConstraint 节点中的约束下界。
类型:TypeNode
prop upperBound
public mut prop upperBound: Token
功能:获取或设置 GenericConstraint 节点中的 <: 运算符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
<:运算符时,抛出异常。
prop upperBounds
public mut prop upperBounds: ArrayList<TypeNode>
功能:获取或设置 GenericConstraint 节点约束上界的 TypeNode 类型节点的集合。
init()
public init()
功能:构造一个默认的 GenericConstraint 对象。
class GenericParam
public class GenericParam <: Node {
public init()
public init(parameters: Tokens)
}
功能:表示一个类型形参节点。
一个 GenericParam 节点:<T1, T2, T3>。
说明:
类型形参用
<>括起并用 "," 分隔多个类型形参名称。
父类型:
prop lAngle
public mut prop lAngle: Token
功能:获取或设置 GenericParam 节点中的左尖括号词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是左尖括号时,抛出异常。
prop parameters
public mut prop parameters: Tokens
功能:获取或设置 GenericParam 节点中的类型形参的 Tokens 类型,可能为空,如 <T1, T2, T3> 中的 T1 T2 和 T3。
类型:Tokens
prop rAngle
public mut prop rAngle: Token
功能:获取或设置 GenericParam 节点中的右尖括号词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是右尖括号时,抛出异常。
init()
public init()
功能:构造一个默认的 GenericParam 对象。
init(Tokens)
public init(parameters: Tokens)
功能:构造一个 GenericParam 对象。
参数:
- parameters: Tokens - 将要构造 GenericParam 的类型形参的词法单元集合 (Tokens)。
class IfExpr
public class IfExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示条件表达式。
可以根据判定条件是否成立来决定执行哪条代码分支。一个 IfExpr 节点中 if 是关键字,if 之后是一个小括号,小括号内可以是一个表达式或者一个 let 声明的解构匹配,接着是一个 Block,Block 之后是可选的 else 分支。 else 分支以 else 关键字开始,后接新的 if 表达式或一个 Block。
父类型:
prop condition
public mut prop condition: Expr
功能:获取或设置 IfExpr 节点中的 if 后的条件表达式。
类型:Expr
prop elseExpr
public mut prop elseExpr: Expr
功能:获取或设置 IfExpr 节点中 else 分支节点。
类型:Expr
异常:
- ASTException - 当前 IfExpr 节点没有 else 分支节点。
prop ifBlock
public mut prop ifBlock: Block
功能:获取或设置 IfExpr 节点中的 if 后的 block 节点。
类型:Block
prop keywordE
public mut prop keywordE: Token
功能:获取或设置 IfExpr 节点中 else 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
else关键字时,抛出异常。
prop keywordI
public mut prop keywordI: Token
功能:获取或设置 IfExpr 节点中的 if 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
if关键字时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 IfExpr 节点中的 if 后的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 IfExpr 节点中的 if 后的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 IfExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 IfExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 IfExpr 节点时,抛出异常。
class ImportContent
public class ImportContent <: Node {
public init()
}
父类型:
prop importKind
public mut prop importKind: ImportKind
功能:获取或设置 ImportContent 节点中导入类型。
类型:ImportKind
prop prefixPaths
public mut prop prefixPaths: Tokens
功能:获取或设置 ImportContent 节点中完整包名的前缀部分的词法单元序列,可能为空。如 import a.b.c 中的 a 和 b。
类型:Tokens
prop prefixDots
public mut prop prefixDots: Tokens
功能:获取或设置 ImportContent 节点中完整包名中用于分隔每层子包的词法单元序列,可能为空。如 import a.b.c 中的两个 "."。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "." 词法单元序列时,抛出异常。
prop identifier
public mut prop identifier: Token
功能:获取或设置 ImportContent 节点中被导入的项,它可能是包中的顶层定义或声明,也可能是子包的名字。
类型:Token
prop importAlias
public mut prop importAlias: Tokens
功能:获取或设置 ImportContent 节点中导入的定义或声明的别名词法单元序列,只有 importKind 为 ImportKind.Alias 时非空。如:import packageName.xxx as yyy 中的 as yyy。
类型:Tokens
prop lBrace
public mut prop lBrace: Token
功能:获取或设置 ImportContent 节点中的 { 操作符词法单元,只有 importKind 为 ImportKind.Multi 时非空。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
{操作符时,抛出异常。
prop items
public mut prop items: ArrayList<ImportContent>
功能:获取或设置 ImportContent 节点中被导入的所有项,只有 importKind 为 ImportKind.Multi 时非空。
类型:ArrayList<ImportContent>
prop commas
public mut prop commas: Tokens
功能:获取或设置 ImportContent 节点中的 "," 词法单元序列,只有 importKind 为 ImportKind.Multi 时非空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop rBrace
public mut prop rBrace: Token
功能:获取或设置 ImportContent 节点中的 } 操作符词法单元,只有 importKind 为 ImportKind.Multi 时非空。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
}操作符时,抛出异常。
init()
public init()
功能:构造一个默认的 ImportContent 对象。
func isImportAlias()
public func isImportAlias(): Bool
功能:判断 ImportContent 节点是否对导入项取了别名。
返回值:
- Bool - ImportContent 节点是否对导入项取了别名。
func isImportAll()
public func isImportAll(): Bool
功能:判断 ImportContent 节点是否为全导入。
返回值:
- Bool - ImportContent 节点是否为全导入。
func isImportMulti()
public func isImportMulti(): Bool
功能:判断 ImportContent 节点是否导入了多个顶级定义或声明。
返回值:
- Bool - ImportContent 节点是否导入了多个顶级定义或声明。
func isImportSingle()
public func isImportSingle(): Bool
功能:判断 ImportContent 节点是否为单导入。
返回值:
- Bool - ImportContent 节点是否为单导入。
class ImportList
public class ImportList <: Node {
public init()
public init(inputs: Tokens)
}
功能:表示包导入节点。
一个 ImportList 节点: import moduleName.packageName.foo as bar。
说明:
导入节点以可选的访问性修饰符(
public/protected/internal/private)加关键字import开头。以import pkga.pkgb.item为例,pkga.pkgb为导入的顶级定义或声明所在的包的名字,item为导入的顶级定义或声明。
父类型:
prop modifier
public mut prop modifier: Token
功能:获取或设置 ImportList 节点中的修饰符,可能为 ILLEGAL 的词法单元。
类型:Token
prop keywordI
public mut prop keywordI: Token
功能:获取或设置 ImportList 节点中的 import 关键字的词法单元,I 为关键字首字母。
类型:Token
prop content
public mut prop content: ImportContent
功能:获取或设置 ImportList 节点中的被导入的具体项。如 import a.b.c 中的 a.b.c 部分。
init()
public init()
功能:构造一个默认的 ImportList 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ImportList 对象。
参数:
- inputs: Tokens - 将要构造 ImportList 类型的词法单元集合 (Tokens) 序列。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ImportList 节点时,抛出异常。
func isImportMulti()
public func isImportMulti(): Bool
功能:判断 ImportList 节点是否导入了多个顶级定义或声明。
返回值:
- Bool - 如果 ImportList 节点导入了多个顶级定义或声明,返回 true;反之,返回 false。
class IncOrDecExpr
public class IncOrDecExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示包含自增操作符(++)或自减操作符(--)的表达式。
父类型:
prop expr
public mut prop expr: Expr
功能:获取或设置 IncOrDecExpr 中的表达式。
类型:Expr
prop op
public mut prop op: Token
功能:获取或设置 IncOrDecExpr 中的操作符。
类型:Token
init()
public init()
功能:构造一个默认的 IncOrDecExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 IncOrDecExpr 对象。
参数:
- inputs: Tokens - 将要构造 IncOrDecExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 IncOrDecExpr 节点时,抛出异常。
class InterfaceDecl
public class InterfaceDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示接口定义节点。
接口的定义使用 interface 关键字,接口定义依次为:可缺省的修饰符、interface 关键字、接口名、可选的类型参数、是否指定父接口、可选的泛型约束、接口体的定义。
父类型:
prop body
public mut prop body: Body
功能:获取或设置 InterfaceDecl 节点的类体。
类型:Body
prop superTypeBitAnds
public mut prop superTypeBitAnds: Tokens
功能:获取或设置 InterfaceDecl 节点的父接口声明中的 & 操作符的词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是
&词法单元序列时,抛出异常。
prop superTypes
public mut prop superTypes: ArrayList<TypeNode>
功能:获取或设置 InterfaceDecl 节点的父接口。
prop upperBound
public mut prop upperBound: Token
功能:获取或设置 <: 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
<:操作符时,抛出异常。
init()
public init()
功能:构造一个默认的 InterfaceDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 InterfaceDecl 对象。
参数:
- inputs: Tokens - 将要构造 InterfaceDecl 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 InterfaceDecl 节点时,抛出异常。
class IsExpr
public class IsExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示一个类型检查表达式。
一个 IsExpr 表达式:e is T,类型为 Bool。其中 e 可以是任何类型的表达式,T 可以是任何类型。
父类型:
prop expr
public mut prop expr: Expr
功能:获取或设置 IsExpr 节点中的表达式节点。
类型:Expr
prop keyword
public mut prop keyword: Token
功能:获取或设置 IsExpr 节点中的 is 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
is操作符时,抛出异常。
prop shiftType
public mut prop shiftType: TypeNode
功能:获取或设置 IsExpr 节点中的目标类型。
类型:TypeNode
init()
public init()
功能:构造一个默认的 IsExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 IsExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 IsExpr 节点时,抛出异常。
class JumpExpr
public class JumpExpr <: Expr {
public init()
public init(kind: Tokens)
}
功能:表示循环表达式的循环体中的 break 和 continue。
父类型:
prop keyword
public mut prop keyword: Token
功能:获取或设置关键字。
类型:Token
init()
public init()
功能:构造一个默认的 JumpExpr 对象。
init(Tokens)
public init(kind: Tokens)
功能:构造一个 JumpExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 JumpExpr 节点时,抛出异常。
class LambdaExpr
public class LambdaExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 Lambda 表达式,是一个匿名的函数。
一个 LambdaExpr 节点有两种形式,一种是有形参的,例如 {a: Int64 => e1; e2 },另一种是无形参的,例如 { => e1; e2 }。
父类型:
prop doubleArrow
public mut prop doubleArrow: Token
功能:获取或设置 LambdaExpr 中的 =>。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
=>操作符时,抛出异常。
prop funcParams
public mut prop funcParams: ArrayList<FuncParam>
功能:获取或设置 LambdaExpr 中的参数列表。
prop lBrace
public mut prop lBrace: Token
功能:获取或设置 LambdaExpr 中的 "{"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "{" 时,抛出异常。
prop nodes
public mut prop nodes: ArrayList<Node>
功能:获取或设置 LambdaExpr 中的表达式或声明节点。
prop rBrace
public mut prop rBrace: Token
功能:获取或设置 LambdaExpr 中的 "}"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "}" 时,抛出异常。
init()
public init()
功能:构造一个默认的 LambdaExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 LambdaExpr 对象。
参数:
- inputs: Tokens - 将要构造 LambdaExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 LambdaExpr 节点时,抛出异常。
class LetPatternExpr
public class LetPatternExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 let 声明的解构匹配节点。
一个 LetPatternExpr 节点:if (let Some(v) <- x) 中的 let Some(v) <- x。
父类型:
prop backArrow
public mut prop backArrow: Token
功能:获取或设置 LetPatternExpr 节点中 <- 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
<-操作符时,抛出异常。
prop expr
public mut prop expr: Expr
功能:获取或设置 LetPatternExpr 节点中 <- 操作符之后的表达式。
类型:Expr
prop keyword
public mut prop keyword: Token
功能:获取或设置 LetPatternExpr 节点中 let 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
let关键字时,抛出异常。
prop pattern
public mut prop pattern: Pattern
功能:获取或设置 LetPatternExpr 节点中 let 之后的 pattern。
类型:Pattern
init()
public init()
功能:构造一个默认的 LetPatternExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 LetPatternExpr 对象。
参数:
- inputs: Tokens - 将要构造 LetPatternExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 LetPatternExpr 节点时,抛出异常。
class LitConstExpr
public class LitConstExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示一个常量表达式节点。
一个 LitConstExpr 表达式:"abc",123 等。
父类型:
prop literal
public mut prop literal: Token
功能:获取或设置 LitConstExpr 节点中的字面量。
类型:Token
init()
public init()
功能:构造一个默认的 LitConstExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 LitConstExpr 对象。
参数:
- inputs: Tokens - 将要构造 LitConstExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ParenExpr 节点时,抛出异常。
class MacroDecl
public class MacroDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示一个宏定义节点。
一个 MacroDecl 节点:public macro M(input: Tokens): Tokens {...}。
父类型:
prop block
public mut prop block: Block
功能:获取或设置 MacroDecl 节点的函数体。
类型:Block
prop colon
public mut prop colon: Token
功能:获取或设置 MacroDecl 节点的冒号。
类型:Token
异常:
- ASTException - 当设置的 Token 不是冒号时,抛出异常。
prop declType
public mut prop declType: TypeNode
功能:获取或设置 MacroDecl 节点的函数返回类型。
类型:TypeNode
异常:
- ASTException - 当 MacroDecl 节点的函数返回类型是一个缺省值时,抛出异常。
prop funcParams
public mut prop funcParams: ArrayList<FuncParam>
功能:获取或设置 MacroDecl 节点的参数。
prop lParen
public mut prop lParen: Token
功能:获取或设置 MacroDecl 节点的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 MacroDecl 节点的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 MacroDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 MacroDecl 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 MacroDecl 节点时,抛出异常。
class MacroExpandDecl
public class MacroExpandDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示宏调用节点。
一个 MacroExpandDecl 节点: @M class A {}。
父类型:
prop fullIdentifier
public mut prop fullIdentifier: Token
功能:获取或设置宏调用节点的完整标识符。
类型:Token
prop lParen
public mut prop lParen: Token
功能:获取或设置 MacroExpandDecl 宏调用的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop lSquare
public mut prop lSquare: Token
功能:获取或设置 MacroExpandDecl 属性宏调用的 "["。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "[" 时,抛出异常。
prop macroAttrs
public mut prop macroAttrs: Tokens
功能:获取或设置 MacroExpandDecl 属性宏调用的输入。
类型:Tokens
prop macroInputDecl
public mut prop macroInputDecl: Decl
功能:获取或设置 MacroExpandDecl 中的声明节点。
类型:Decl
异常:
- ASTException - 当 MacroExpandDecl 节点中没有声明节点时,抛出异常。
prop macroInputs
public mut prop macroInputs: Tokens
功能:获取或设置 MacroExpandDecl 宏调用的输入。
类型:Tokens
prop rParen
public mut prop rParen: Token
功能:获取或设置 MacroExpandDecl 宏调用的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop rSquare
public mut prop rSquare: Token
功能:获取或设置 MacroExpandDecl 属性宏调用的 "]"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "]" 时,抛出异常。
init()
public init()
功能:构造一个默认的 MacroExpandDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 MacroExpandDecl 对象。
参数:
- inputs: Tokens - 将要构造 MacroExpandDecl 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 MacroExpandDecl 节点时,抛出异常。
class MacroExpandExpr
public class MacroExpandExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示宏调用节点。
一个 MacroExpandExpr 节点: @M (a is Int64)。
父类型:
prop at
public mut prop at: Token
功能:获取或设置 MacroExpandExpr 节点中的 @ 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
@操作符时,抛出异常。
prop identifier
public mut prop identifier: Token
功能:获取或设置宏调用节点的标识符。
类型:Token
prop lParen
public mut prop lParen: Token
功能:获取或设置 MacroExpandExpr 宏调用的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop lSquare
public mut prop lSquare: Token
功能:获取或设置 MacroExpandExpr 属性宏调用的 "["。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "[" 时,抛出异常。
prop macroAttrs
public mut prop macroAttrs: Tokens
功能:获取或设置 MacroExpandExpr 属性宏调用的输入。
类型:Tokens
prop macroInputs
public mut prop macroInputs: Tokens
功能:获取或设置 MacroExpandExpr 宏调用的输入。
类型:Tokens
prop rParen
public mut prop rParen: Token
功能:获取或设置 MacroExpandExpr 宏调用的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop rSquare
public mut prop rSquare: Token
功能:获取或设置 MacroExpandExpr 属性宏调用的 "]"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "]" 时,抛出异常。
init()
public init()
功能:构造一个默认的 MacroExpandExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 MacroExpandExpr 对象。
参数:
- inputs: Tokens - 将要构造 MacroExpandExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 MacroExpandExpr 节点时,抛出异常。
class MacroExpandParam
public class MacroExpandParam <: FuncParam {
public init()
}
功能:表示宏调用节点。
一个 MacroExpandParam 节点: func foo (@M a: Int64) 中的 @M a: Int64。
父类型:
prop fullIdentifier
public mut prop fullIdentifier: Token
功能:获取或设置宏调用节点的完整标识符。
类型:Token
prop lParen
public mut prop lParen: Token
功能:获取或设置 MacroExpandParam 宏调用的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop lSquare
public mut prop lSquare: Token
功能:获取或设置 MacroExpandParam 属性宏调用的 "["。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "[" 时,抛出异常。
prop macroAttrs
public mut prop macroAttrs: Tokens
功能:获取或设置 MacroExpandParam 属性宏调用的输入。
类型:Tokens
prop macroInputDecl
public mut prop macroInputDecl: Decl
功能:获取或设置 MacroExpandParam 中的声明节点。
类型:Decl
异常:
- ASTException - 当 MacroExpandParam 节点中没有声明节点时,抛出异常。
prop macroInputs
public mut prop macroInputs: Tokens
功能:获取或设置 MacroExpandParam 宏调用的输入。
类型:Tokens
prop rParen
public mut prop rParen: Token
功能:获取或设置 MacroExpandParam 宏调用的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop rSquare
public mut prop rSquare: Token
功能:获取或设置 MacroExpandParam 属性宏调用的 "]"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "]" 时,抛出异常。
init()
public init()
功能:构造一个默认的 MacroExpandParam 对象。
class MacroMessage
public class MacroMessage
功能:记录内层宏发送的信息。
func getBool(String)
public func getBool(key: String): Bool
功能:获取对应 key 值的 Bool 类型信息。
参数:
- key: String - 用于检索的关键字的名字。
返回值:
异常:
func getInt64(String)
public func getInt64(key: String): Int64
功能:获取对应 key 值的 Int64 类型信息。
参数:
- key: String - 用于检索的关键字的名字。
返回值:
异常:
func getString(String)
public func getString(key: String): String
功能:获取对应 key 值的 String 类型信息。
参数:
- key: String - 用于检索的关键字的名字。
返回值:
异常:
func getTokens(String)
public func getTokens(key: String): Tokens
功能:获取对应 key 值的 Tokens 类型信息。
参数:
- key: String - 用于检索的关键字的名字。
返回值:
异常:
func hasItem(String)
public func hasItem(key: String): Bool
功能:检查是否有 key 值对应的相关信息。
参数:
- key: String - 用于检索的关键字名字。
返回值:
- Bool - 若存在 key 值对应的相关信息,返回 true;反之,返回 false。
class MainDecl
public class MainDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示一个 main 函数定义节点。
一个 MainDecl 节点:main() {}。
父类型:
prop block
public mut prop block: Block
功能:获取或设置 MainDecl 节点的函数体。
类型:Block
prop colon
public mut prop colon: Token
功能:获取或设置 MainDecl 节点的冒号。
类型:Token
异常:
- ASTException - 当设置的 Token 不是冒号时,抛出异常。
prop declType
public mut prop declType: TypeNode
功能:获取或设置 MainDecl 节点的函数返回类型。
类型:TypeNode
异常:
- ASTException - 当 MainDecl 节点的函数返回类型是一个缺省值时,抛出异常。
prop funcParams
public mut prop funcParams: ArrayList<FuncParam>
功能:获取或设置 MainDecl 节点的函数参数。
prop lParen
public mut prop lParen: Token
功能:获取或设置 MainDecl 节点的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 MainDecl 节点的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 MainDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 MainDecl 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 MainDecl 节点时,抛出异常。
class MatchCase
public class MatchCase <: Node {
public init()
}
功能:表示 match 表达式中的一个 case 节点。
一个 MatchCase 节点:case failScore where score > 0 => 0。
说明:
父类型:
prop arrow
public mut prop arrow: Token
功能:获取或设置 MatchCase 中的 => 操作符的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
=>操作符时,抛出异常。
prop bitOrs
public mut prop bitOrs: Tokens
功能:获取或设置 MatchCase 中的 | 操作符的词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是
|词法单元序列时,抛出异常。
prop block
public mut prop block: Block
功能:获取或设置 MatchCase 中的一系列声明或表达式节点。
类型:Block
prop expr
public mut prop expr: Expr
功能:获取或设置 MatchCase 中位于 case 后的表达式节点。
类型:Expr
异常:
- ASTException - 当 MatchCase 节点中不存在表达式节点时,抛出异常。
prop keywordC
public mut prop keywordC: Token
功能:获取或设置 MatchCase 内的 case 关键字的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
case关键字时,抛出异常。
prop keywordW
public mut prop keywordW: Token
功能:获取或设置 MatchCase 中可选的关键字 where 的词法单元,可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
where关键字时,抛出异常。
prop patternGuard
public mut prop patternGuard: Expr
功能:获取或设置 MatchCase 中可选的 pattern guard 表达式节点。
类型:Expr
异常:
- ASTException - 当 MatchCase 节点中不存在 pattern guard 表达式时,抛出异常。
prop patterns
public mut prop patterns: ArrayList<Pattern>
功能:获取或设置 MatchCase 中位于 case 后的 pattern 列表。
init()
public init()
功能:构造一个默认的 MatchCase 对象。
class MatchExpr
public class MatchExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示模式匹配表达式实现模式匹配。
模式匹配表达式分为带 selector 的 match 表达式和不带 selector 的 match 表达式。
父类型:
prop keyword
public mut prop keyword: Token
功能:获取或设置 MatchExpr 节点中 match 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
matcch关键字时,抛出异常。
prop lBrace
public mut prop lBrace: Token
功能:获取或设置 MatchExpr 之后的 "{"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "{" 时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 MatchExpr 之后的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop matchCases
public mut prop matchCases: ArrayList<MatchCase>
功能:获取或设置 MatchExpr 内的 matchCase, matchCase 以关键字 case 开头,后跟一个或者多个由 Pattern 或 Expr节点,具体见 MatchCase。
prop rBrace
public mut prop rBrace: Token
功能:获取或设置 MatchExpr 之后的 "}"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "}" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 MatchExpr 之后的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop selector
public mut prop selector: Expr
功能:获取或设置关键字 match 之后的 Expr。
类型:Expr
异常:
- ASTException - 当该表达式是一个不带 selector 的
match表达式时,抛出异常。
init()
public init()
功能:构造一个默认的 MatchExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 MatchExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 MatchExpr 节点时,抛出异常。
class MemberAccess
public class MemberAccess <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示成员访问表达式。
可以用于访问 class、interface、struct 等类型的成员。一个 MemberAccess 节点的形式为 T.a,T 为成员访问表达式的主体,a 表示成员的名字。
父类型:
prop baseExpr
public mut prop baseExpr: Expr
功能:获取或设置 MemberAccess 节点的成员访问表达式主体。
类型:Expr
prop commas
public mut prop commas: Tokens
功能:获取或设置 MemberAccess 节点中的 "," 词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop dot
public mut prop dot: Token
功能:获取或设置 MemberAccess 节点中的 "."。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "." 词法单元类型时,抛出异常。
prop field
public mut prop field: Token
功能:获取或设置 MemberAccess 节点成员的名字。
类型:Token
prop lAngle
public mut prop lAngle: Token
功能:获取或设置 MemberAccess 节点中的左尖括号。
类型:Token
异常:
- ASTException - 当设置的 Token 不是左尖括号时,抛出异常。
prop rAngle
public mut prop rAngle: Token
功能:获取或设置 MemberAccess 节点中的右尖括号。
类型:Token
异常:
- ASTException - 当设置的 Token 不是右尖括号时,抛出异常。
prop typeArguments
public mut prop typeArguments: ArrayList<TypeNode>
功能:获取或设置 MemberAccess 节点中的实例化类型。
init()
public init()
功能:构造一个默认的 MemberAccess 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 MemberAccess 对象。
参数:
- inputs: Tokens - 将要构造 MemberAccess 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 MemberAccess 节点时,抛出异常。
class Modifier
public class Modifier <: Node {
public init()
public init(keyword: Token)
}
功能:表示该定义具备某些特性,通常放在定义处的最前端。
一个 Modifier 节点:public func foo() 中的 public。
父类型:
prop keyword
public mut prop keyword: Token
功能:获取或设置 Modifier 节点中的修饰符词法单元。
类型:Token
init()
public init()
功能:构造一个默认的 Modifier 对象。
init(Token)
public init(keyword: Token)
功能:构造一个 Modifier 对象。
参数:
class Node
abstract sealed class Node <: ToTokens
功能:所有仓颉语法树节点的父类。
该类提供了所有数据类型通用的操作接口。
父类型:
prop beginPos
public mut prop beginPos: Position
功能:获取或设置当前节点的起始的位置信息。
类型:Position
prop endPos
public mut prop endPos: Position
功能:获取或设置当前节点的终止的位置信息。
类型:Position
func dump()
public func dump(): Unit
功能:将当前语法树节点转化为树形结构的形态并进行打印。
语法树节点的树形结构将按照以下形式进行输出:
-字符串:表示当前节点的公共属性, 如-keyword,-identifier。- 节点属性后紧跟该节点的具体类型, 如
-declType: PrimitiveType表示节点类型是一个 PrimitiveType 节点。 - 每个类型使用大括号表示类型的作用区间。
语法树输出的详细格式请参见语法树节点打印。
func toTokens()
public func toTokens(): Tokens
功能:将语法树节点转化为 Tokens 类型。
返回值:
func traverse(Visitor)
public func traverse(v: Visitor): Unit
功能:遍历当前语法树节点及其子节点。若提前终止遍历子节点的行为,可重写 visit 函数并调用 breakTraverse 函数提前终止遍历行为,请参见自定义访问函数遍历 AST 对象示例。
参数:
class OptionalExpr
public class OptionalExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示一个带有问号操作符的表达式节点。
一个 OptionalExpr 节点:a?.b, a?(b), a?[b] 中的 a?。
父类型:
prop baseExpr
public mut prop baseExpr: Expr
功能:获取或设置 OptionalExpr 的表达式节点。
类型:Expr
prop quest
public mut prop quest: Token
功能:获取或设置 OptionalExpr 中的问号操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是问号操作符时,抛出异常。
init()
public init()
功能:构造一个默认的 OptionalExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 OptionalExpr 对象。
参数:
- inputs: Tokens - 将要构造 OptionalExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 OptionalExpr 节点时,抛出异常。
class PackageHeader
public class PackageHeader <: Node {
public init()
public init(inputs: Tokens)
}
功能:表示包声明节点。
一个 PackageHeader 节点: package define 或者 macro package define。
说明:
包声明以关键字
package或macro package开头,后面紧跟包名,且包声明必须在源文件的首行。
父类型:
prop accessible
public mut prop accessible: Token
功能:获取或设置 PackageHeader 节点中的访问性修饰符的词法单元,可能为 ILLEGAL 的词法单元。
类型:Token
prop keywordM
public mut prop keywordM: Token
功能:获取或设置 PackageHeader 节点中的 macro 关键字的词法单元(M 为关键字首字母,下同),可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
macro关键字时,抛出异常。
prop keywordP
public mut prop keywordP: Token
功能:获取或设置 PackageHeader 节点中的 package 关键字的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
package关键字时,抛出异常。
prop prefixPaths
public mut prop prefixPaths: Tokens
功能:获取或设置 PackageHeader 节点中完整包名的前缀部分的词法单元序列,可能为空。如 package a.b.c 中的 a 和 b。
类型:Tokens
prop prefixDots
public mut prop prefixDots: Tokens
功能:获取或设置 PackageHeader 节点中完整包名中用于分隔每层子包的词法单元序列,可能为空。如 package a.b.c 中的两个 "."。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "." 词法单元序列时,抛出异常。
prop packageIdentifier
public mut prop packageIdentifier: Token
功能:获取或设置 PackageHeader 节点中当前包的名字,如果当前包为 root 包,即为完整包名,若当前包为子包,则为最后一个 "." 后的名字。
类型:Token
init()
public init()
功能:构造一个默认的 PackageHeader 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 PackageHeader 对象。
参数:
- inputs: Tokens - 将要构造 PackageHeader 类型的词法单元集合 (Tokens) 序列。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 PackageHeader 节点时,抛出异常。
class ParenExpr
public class ParenExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示一个括号表达式节点,是指使用圆括号括起来的表达式。
一个 ParenExpr 节点:(1 + 2)。
父类型:
prop lParen
public mut prop lParen: Token
功能:获取或设置 ParenExpr 节点中的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop parenthesizedExpr
public mut prop parenthesizedExpr: Expr
功能:获取或设置 ParenExpr 节点中由圆括号括起来的子表达式。
类型:Expr
prop rParen
public mut prop rParen: Token
功能:获取或设置 ParenExpr 节点中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 ParenExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ParenExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ParenExpr 节点时,抛出异常。
class ParenType
public class ParenType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示括号类型节点。
例如 var a: (Int64) 中的 (Int64)。
父类型:
prop lParen
public mut prop lParen: Token
功能:获取或设置 ParenType 节点中的 "(" 词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop parenthesizedType
public mut prop parenthesizedType: TypeNode
功能:获取或设置 ParenType 节点中括起来的类型,如 (Int64) 中的 Int64。
类型:TypeNode
prop rParen
public mut prop rParen: Token
功能:获取或设置 ParenType 节点中的 ")" 词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 ParenType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ParenType 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ParenType 节点时,抛出异常。
class Pattern
public open class Pattern <: Node
功能:所有模式匹配节点的父类,继承自 Node 节点。
父类型:
class PrefixType
public class PrefixType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示带问号的前缀类型节点。
例如 var a : ?A 中的 ?A。
父类型:
prop baseType
public mut prop baseType: TypeNode
功能:获取或设置 PrefixType 节点中的类型节点,如 var a: ?A 中的 A。
类型:TypeNode
prop prefixOps
public mut prop prefixOps: Tokens
功能:获取或设置 PrefixType 节点中前缀操作符集合。
类型:Tokens
init()
public init()
功能:构造一个默认的 PrefixType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 PrefixType 对象。
参数:
- inputs: Tokens - 将要构造 PrefixType 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 PrefixType 节点时,抛出异常。
class PrimaryCtorDecl
public class PrimaryCtorDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示一个主构造函数节点。
主构造函数节点由修饰符,主构造函数名,形参列表和主构造函数体构成。
父类型:
prop block
public mut prop block: Block
功能:获取或设置 PrimaryCtorDecl 节点的主构造函数体。
类型:Block
prop funcParams
public mut prop funcParams: ArrayList<FuncParam>
功能:获取或设置 PrimaryCtorDecl 节点的参数。
prop lParen
public mut prop lParen: Token
功能:获取或设置 PrimaryCtorDecl 节点的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 PrimaryCtorDecl 节点的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 PrimaryCtorDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 PrimaryCtorDecl 对象。
参数:
- inputs: Tokens - 将要构造 PrimaryCtorDecl 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 PrimaryCtorDecl 节点时,抛出异常。
func isConst()
public func isConst(): Bool
功能:判断是否是一个 Const 类型的节点。
返回值:
- Bool - 当前节点为
Const类型的节点时,返回 true;反之,返回 false。
class PrimitiveType
public class PrimitiveType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示一个基本类型节点。
例如数值类型,Rune 类型,布尔类型等。
父类型:
prop keyword
public mut prop keyword: Token
功能:获取或设置构造 PrimitiveType 类型的关键字,如 Int8。
类型:Token
init()
public init()
功能:构造一个默认的 PrimitiveType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 PrimitiveType 对象。
参数:
- inputs: Tokens - 将要构造 PrimitiveType 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 PrimitiveType 节点时,抛出异常。
class PrimitiveTypeExpr
public class PrimitiveTypeExpr <: Expr {
public init()
public init(kind: Tokens)
}
功能:表示基本类型表达式节点。
PrimitiveTypeExpr 节点:编译器内置的基本类型作为表达式出现在节点中。如 Int64.toSting() 中的 Int64。
父类型:
prop keyword
public mut prop keyword: Token
功能:获取或设置 PrimitiveTypeExpr 中的基本类型关键字。
类型:Token
init()
public init()
功能:构造一个默认的 PrimitiveTypeExpr 对象。
init(Tokens)
public init(kind: Tokens)
功能:构造一个 PrimitiveTypeExpr 对象。
参数:
- kind: Tokens - 将要构造 PrimitiveTypeExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 PrimitiveTypeExpr 节点时,抛出异常。
class Program
public class Program <: Node {
public init()
public init(inputs: Tokens)
}
功能:表示一个仓颉源码文件节点。
一个仓颉源码文件节点主要包括包定义节点,包导入节点和 TopLevel 作用域内的所有声明节点。
说明:
任何一个仓颉源码文件都可以被解析为一个 Program 类型。
父类型:
prop decls
public mut prop decls: ArrayList<Decl>
功能:获取或设置仓颉源码文件中 TopLevel 作用域内定义的声明节点列表。
prop importLists
public mut prop importLists: ArrayList<ImportList>
功能:获取或设置仓颉源码文件中包导入节点 ImportList 的列表。
类型:ArrayList<ImportList>
prop packageHeader
public mut prop packageHeader: PackageHeader
功能:获取或设置仓颉源码文件中包的声明节点 PackageHeader。
init()
public init()
功能:构造一个默认的 Program 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 Program 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为一个文件节点时,抛出异常。
class PropDecl
public class PropDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示一个属性定义节点。
一个 PropDecl 节点:prop X: Int64 { get() { 0 } }。
父类型:
prop colon
public mut prop colon: Token
功能:获取或设置 PropDecl 节点的冒号。
类型:Token
异常:
- ASTException - 当设置的 Token 不是冒号时,抛出异常。
prop declType
public mut prop declType : TypeNode
功能:获取或设置 PropDecl 节点的返回类型。
类型:TypeNode
prop getter
public mut prop getter: FuncDecl
功能:获取或设置 PropDecl 节点的 getter 函数。
类型:FuncDecl
异常:
- ASTException - 当 PropDecl 节点不存在 getter 函数时,抛出异常。
prop lBrace
public mut prop lBrace: Token
功能:获取或设置 PropDecl 节点的 "{"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "{" 时,抛出异常。
prop rBrace
public mut prop rBrace: Token
功能:获取或设置 PropDecl 节点的 "}"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "}" 时,抛出异常。
prop setter
public mut prop setter: FuncDecl
功能:获取或设置 PropDecl 节点的 setter 函数。
类型:FuncDecl
异常:
- ASTException - 当 PropDecl 节点不存在 setter 函数时,抛出异常。
init()
public init()
功能:构造一个默认的 PropDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 PropDecl 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 PropDecl 节点时,抛出异常。
class QualifiedType
public class QualifiedType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示一个用户自定义成员类型。
例如 var a : T.a 中的 T.a, 其中 T 是包名,a 是从 T 包中导入的类型。
父类型:
prop baseType
public mut prop baseType: TypeNode
功能:获取或设置 QualifiedType 节点的成员访问类型主体,如 var a : T.a 中的 T。
类型:TypeNode
prop commas
public mut prop commas: Tokens
功能:获取或设置 QualifiedType 节点中的 "," 词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop dot
public mut prop dot: Token
功能:获取或设置 QualifiedType 节点中的 "." 。
类型:Token
异常:
- ASTException - 当设置的 Tokens 不是 "." 词法单元时,抛出异常。
prop identifier
public mut prop identifier: Token
功能:获取或设置 QualifiedType 节点成员的标识符,如 var a : T.a 中的 a。
类型:Token
prop lAngle
public mut prop lAngle: Token
功能:获取或设置 QualifiedType 节点中的左尖括号词法单元,可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是左尖括号时,抛出异常。
prop rAngle
public mut prop rAngle: Token
功能:获取或设置 QualifiedType 节点中的右尖括号词法单元,可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是右尖括号时,抛出异常。
prop typeArguments
public mut prop typeArguments: ArrayList<TypeNode>
功能:获取或设置 QualifiedType 节点中的实例化类型的列表,如 T.a<Int32> 中的 Int32,列表可能为空。
init()
public init()
功能:构造一个默认的 QualifiedType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 QualifiedType 对象。
参数:
- inputs: Tokens - 将要构造 QualifiedType 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 QualifiedType 节点时,抛出异常。
class QuoteExpr
public class QuoteExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 quote 表达式节点。
一个 QuoteExpr 节点: quote(var ident = 0)。
父类型:
prop exprs
public mut prop exprs: ArrayList<Expr>
功能:获取或设置 QuoteExpr 中由 () 括起的内部引用表达式节点。
prop keyword
public mut prop keyword: Token
功能:获取或设置 QuoteExpr 的 quote 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
quote关键字时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 QuoteExpr 中的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 QuoteExpr 中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 QuoteExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 QuoteExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 QuoteExpr 节点。
class QuoteToken
public class QuoteToken <: Expr
功能:表示 quote 表达式节点内任意合法的 token。
父类型:
prop tokens
public mut prop tokens: Tokens
功能:获取 QuoteToken 内的 Tokens。
类型:Tokens
class RangeExpr
public class RangeExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示包含区间操作符的表达式。
RangeExpr 节点:存在两种 Range 操作符:.. 和 ..=,分别用于创建左闭右开和左闭右闭的 Range 实例。它们的使用方式分别为 start..end:step 和 start..=end:step。
父类型:
prop colon
public mut prop colon: Token
功能:获取或设置 RangeExpr 中的 ":" 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ":" 操作符时,抛出异常。
prop end
public mut prop end: Expr
功能:获取或设置 RangeExpr 中的终止值。
类型:Expr
异常:
- ASTException - 终止表达式省略。只有在 Range<Int64> 类型的实例用在下标操作符
[]为空的场景。
prop op
public mut prop op: Token
功能:获取或设置 RangeExpr 中的 Range 的操作符。
类型:Token
prop start
public mut prop start: Expr
功能:获取或设置 RangeExpr 中的起始值。
类型:Expr
异常:
- ASTException - 起始表达式省略。只有在 Range<Int64> 类型的实例用在下标操作符
[]为空的场景。
prop step
public mut prop step: Expr
功能:获取或设置 RangeExpr 中序列中前后两个元素之间的差值。
类型:Expr
异常:
- ASTException - 当 RangeExpr 中未设置序列前后两个元素之间的差值时,抛出异常。
init()
public init()
功能:构造一个默认的 RangeExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 RangeExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 RangeExpr 节点时,抛出异常。
class RefExpr
public class RefExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示引用一个声明的表达式节点。
一个 RefExpr 节点:var b = a + 1 中的 a 是一个 RefExpr。
父类型:
prop commas
public mut prop commas: Tokens
功能:获取或设置 RefExpr 节点中的 "," 词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop identifier
public mut prop identifier: Token
功能:获取或设置 RefExpr 节点中的自定义类型的标识符。
类型:Token
prop lAngle
public mut prop lAngle: Token
功能:获取或设置 RefExpr 节点中的左尖括号。
类型:Token
异常:
- ASTException - 当设置的 Token 不是左尖括号时,抛出异常。
prop rAngle
public mut prop rAngle: Token
功能:获取或设置 RefExpr 节点中的右尖括号。
类型:Token
异常:
- ASTException - 当设置的 Token 不是右尖括号时,抛出异常。
prop typeArguments
public mut prop typeArguments: ArrayList<TypeNode>
功能:获取或设置 RefExpr 节点中的实例化类型。
init()
public init()
功能:构造一个默认的 RefExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 RefExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 RefExpr 节点时,抛出异常。
class RefType
public class RefType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示一个非基础类型节点。
例如用户通过 class、struct、enum 等定义的自定义类型,以及 Array、String 等内置类型都可以使用 RefType 表示。例如 var a : A 中的 A。
父类型:
prop commas
public mut prop commas: Tokens
功能:获取或设置 RefType 节点中的 "," 词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop identifier
public mut prop identifier: Token
功能:获取或设置构造 RefType 类型的关键字,如 var a : A = A() 中的 A。
类型:Token
prop lAngle
public mut prop lAngle: Token
功能:获取或设置 RefType 节点中的左尖括号词法单元,可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是左尖括号时,抛出异常。
prop rAngle
public mut prop rAngle: Token
功能:获取或设置 RefType 节点中的右尖括号词法单元,可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是右尖括号时,抛出异常。
prop typeArguments
public mut prop typeArguments: ArrayList<TypeNode>
功能:获取或设置 RefType 节点中的实例化类型的列表,可能为空,如 var a : Array<Int32> 中的 Int32。
init()
public init()
功能:构造一个默认的 RefType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 RefType 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 RefType 节点时,抛出异常。
class ReturnExpr
public class ReturnExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 return 表达式节点。
一个 ReturnExpr 节点:return 1。
父类型:
prop expr
public mut prop expr: Expr
功能:获取或设置 ReturnExpr 节点中的表达式节点。
类型:Expr
异常:
- ASTException - 当 ReturnExpr 节点没有表达式时,抛出异常。
prop keyword
public mut prop keyword: Token
功能:获取或设置 ReturnExpr 节点中的关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
return关键字时,抛出异常。
init()
public init()
功能:构造一个默认的 ReturnExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ReturnExpr 对象。
参数:
- inputs: Tokens - 将要构造 ReturnExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ReturnExpr 节点时,抛出异常。
class SpawnExpr
public class SpawnExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 Spawn 表达式。
一个 SpawnExpr 节点由 spawn 关键字和一个不包含形参的闭包组成,例如:spawn { add(1, 2) }。
父类型:
prop keyword
public mut prop keyword: Token
功能:获取或设置 SpawnExpr 中的 spawn 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
spawn关键字时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 SpawnExpr 中的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop lambdaExpr
public mut prop lambdaExpr: LambdaExpr
功能:获取或设置 SpawnExpr 中的不含形参的闭包。
类型:LambdaExpr
prop rParen
public mut prop rParen: Token
功能:获取或设置 SpawnExpr 中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop threadContext
public mut prop threadContext: Expr
功能:获取或设置 SpawnExpr 中的线程上下文环境表达式。
类型:Expr
异常:
- ASTException - 当 SpawnExpr 中不含有上下文表达式时,抛出异常。
init()
public init()
功能:构造一个默认的 SpawnExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 SpawnExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 SpawnExpr 节点时,抛出异常。
class StructDecl
public class StructDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示一个 Struct 节点。
Struct 的定义使用 struct 关键字,定义依次为:可缺省的修饰符、struct 关键字、struct 名、可选的类型参数、是否指定父接口、可选的泛型约束、struct 体的定义。
父类型:
prop body
public mut prop body: Body
功能:获取或设置 StructDecl 节点的类体。
类型:Body
prop superTypeBitAnds
public mut prop superTypeBitAnds: Tokens
功能:获取或设置 StructDecl 节点的父接口声明中的 & 操作符的词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是
&词法单元序列时,抛出异常。
prop superTypes
public mut prop superTypes: ArrayList<TypeNode>
功能:获取或设置 StructDecl 节点的父接口。
prop upperBound
public mut prop upperBound: Token
功能:获取或设置 <: 操作符。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
<:操作符时,抛出异常。
init()
public init()
功能:构造一个默认的 StructDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 StructDecl 对象。
参数:
- inputs: Tokens - 将要构造 StructDecl 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 StructDecl 节点时,抛出异常。
class SubscriptExpr
public class SubscriptExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示索引访问表达式。
SubscriptExpr 节点:用于那些支持索引访问的类型(包括 Array 类型和 Tuple 类型)通过下标来访问其具体位置的元素,如 arr[0]。
父类型:
prop baseExpr
public mut prop baseExpr: Expr
功能:获取或设置 SubscriptExpr 中的表达式。
类型:Expr
prop indexList
public mut prop indexList: ArrayList<Expr>
功能:获取或设置 SubscriptExpr 中的索引表达式序列。
prop lSquare
public mut prop lSquare: Token
功能:获取或设置 SubscriptExpr 中的 "["。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "[" 时,抛出异常。
prop rSquare
public mut prop rSquare: Token
功能:获取或设置 SubscriptExpr 中的 "]"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "]" 时,抛出异常。
init()
public init()
功能:构造一个默认的 SubscriptExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 SubscriptExpr 对象。
参数:
- inputs: Tokens - 将要构造 SubscriptExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 SubscriptExpr 节点时,抛出异常。
class SynchronizedExpr
public class SynchronizedExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 synchronized 表达式。
一个 SynchronizedExpr 节点由 synchronized 关键字和 StructuredMutex 对以及后面的代码块组成, 例如 synchronized(m) { foo() }。
父类型:
prop block
public mut prop block: Block
功能:获取或设置 SynchronizedExpr 修饰的代码块。
类型:Block
prop keyword
public mut prop keyword: Token
功能:获取或设置 SynchronizedExpr 中的 synchronized 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
synchronized关键字时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 SynchronizedExpr 中的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 SynchronizedExpr 中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop structuredMutex
public mut prop structuredMutex: Expr
功能:获取或设置 SynchronizedExpr 中的 StructuredMutex 的对象。
类型:Expr
init()
public init()
功能:构造一个默认的 SynchronizedExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 SynchronizedExpr 对象。
参数:
- inputs: Tokens - 将要构造 SynchronizedExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 SynchronizedExpr 节点时,抛出异常。
class ThisType
public class ThisType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示 This 类型节点。
父类型:
prop keyword
public mut prop keyword: Token
功能:获取或设置 ThisType 节点关键字 This 的词法单元。
类型:Token
init()
public init()
功能:构造一个默认的 ThisType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ThisType 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ThisType 节点时,抛出异常。
class ThrowExpr
public class ThrowExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 throw 表达式节点。
一个 ThrowExpr 节点:throw Exception()。
父类型:
prop expr
public mut prop expr: Expr
功能:获取或设置 ThrowExpr 节点中的表达式节点。
类型:Expr
prop keyword
public mut prop keyword: Token
功能:获取或设置 ThrowExpr 节点中的关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
throw关键字时,抛出异常。
init()
public init()
功能:构造一个默认的 ThrowExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 ThrowExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 ThrowExpr 节点时,抛出异常。
class Tokens
public open class Tokens <: ToString & Iterable<Token> & ToBytes {
public init()
public init(tokArray: Array<Token>)
public init(tokArrayList: ArrayList<Token>)
}
功能:对 Token 序列进行封装的类型。
父类型:
prop size
public open prop size: Int64
类型:Int64
init()
public init()
功能:构造一个默认的 Tokens 对象。
init(Array<Token>)
public init(tokArray: Array<Token>)
功能:构造一个 Tokens 对象。
参数:
init(ArrayList<Token>)
public init(tokArrayList: ArrayList<Token>)
功能:构造一个 Tokens 对象。
参数:
func append(Node)
public func append(node: Node): Tokens
功能:将当前的 Tokens 与传入节点所转换得到的 Tokens 进行拼接。
参数:
返回值:
func append(Token)
public open func append(token: Token): Tokens
功能:将当前的 Tokens 与传入的 Token 进行拼接。
参数:
返回值:
func append(Tokens)
public open func append(tokens: Tokens): Tokens
功能:在当前的 Tokens 后追加传入的 Tokens 进行拼接(该接口性能较其他拼接函数表现更好)。
参数:
返回值:
func concat(Tokens)
public func concat(tokens: Tokens): Tokens
功能:将当前的 Tokens 与传入的 Tokens 进行拼接,返回新的 Tokens 实例。
参数:
返回值:
func dump()
public func dump(): Unit
功能:将 Tokens 内所有 Token 的信息打印出来。
func get(Int64)
public open func get(index: Int64): Token
功能:通过索引值获取 Token 元素。
参数:
- index: Int64 - 待索引的数值。
返回值:
异常:
- IndexOutOfBoundsException - 当
index无效时,抛出异常。
func iterator()
public func iterator(): TokensIterator
功能:获取 Tokens 对象中的一个迭代器对象。
返回值:
- TokensIterator - Tokens 对象的迭代器对象。
func remove(Int64)
public func remove(index: Int64): Tokens
功能:删除指定位置的 Token 对象。
参数:
返回值:
func toBytes()
public func toBytes(): Array<UInt8>
功能:Tokens 类型的序列化。
返回值:
func toString()
public func toString(): String
operator func +(Token)
public operator func +(r: Token): Tokens
功能:使用当前 Tokens 与另一个 Token 相加以获取新的 Tokens 实例。
参数:
返回值:
operator func +(Tokens)
public operator func +(r: Tokens): Tokens
功能:使用当前 Tokens 与 Tokens 相加以获取新的 Tokens 实例。
参数:
返回值:
operator func [](Int64)
public operator func [](index: Int64): Token
功能:操作符重载,通过索引值获取对应 Token。
参数:
- index: Int64 - 待索引的数值。
返回值:
异常:
- IndexOutOfBoundsException - 当
index无效时,抛出异常。
operator func [](Range<Int64>)
public open operator func [](range: Range<Int64>): Tokens
功能:操作符重载,通过 range 获取对应 Tokens 切片。
参数:
返回值:
异常:
- IllegalArgumentException - 当
range.step不等于 1 时,抛出异常。 - IndexOutOfBoundsException - 当 range 无效时,抛出异常。
class TokensIterator
public class TokensIterator <: Iterator<Token> {
public init(tokens: Tokens)
}
功能:实现 Tokens 的迭代器功能。
父类型:
init(Tokens)
public init(tokens: Tokens)
功能:构造一个 TokensIterator 对象。
参数:
func iterator()
public func iterator(): Iterator<Token>
功能:获取当前迭代器实例。
返回值:
func next()
public func next(): Option<Token>
功能:获取迭代器中的下一个值。
返回值:
func peek()
public func peek(): Option<Token>
功能:获取迭代器中的当前值。
返回值:
func seeing(TokenKind)
public func seeing(kind: TokenKind): Bool
功能:判断当前节点的 Token 类型是否是传入的类型。
参数:
返回值:
class TrailingClosureExpr
public class TrailingClosureExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示尾随 Lambda 节点。
一个 TrailingClosureExpr 节点将 lambda 表达式放在函数调用的尾部,括号外面,如 f(a){ i => i * i }。
父类型:
prop expr
public mut prop expr: Expr
功能:获取或设置 TrailingClosureExpr 中的表达式。
类型:Expr
prop lambdaExpr
public mut prop lambdaExpr: LambdaExpr
功能:获取或设置 TrailingClosureExpr 中的尾随 lambda。
类型:LambdaExpr
init()
public init()
功能:构造一个默认的 TrailingClosureExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 TrailingClosureExpr 对象。
参数:
- inputs: Tokens - 将要构造 TrailingClosureExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 TrailingClosureExpr 节点。
class TryExpr
public class TryExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 try 表达式节点。
try 表达式包括三个部分:try 块,catch 块和 finally 块。
父类型:
prop catchBlocks
public mut prop catchBlocks: ArrayList<Block>
功能:获取或设置 TryExpr 中的 Catch 块。
prop catchPatterns
public mut prop catchPatterns: ArrayList<Pattern>
功能:获取或设置 TryExpr 中通过模式匹配的方式匹配待捕获的异常序列。
prop finallyBlock
public mut prop finallyBlock: Block
功能:获取或设置 TryExpr 中的关键字 Finally 块。
类型:Block
异常:
- ASTException - 当 TryExpr 节点无
Finally块节点时,抛出异常。
prop keywordF
public mut prop keywordF: Token
功能:获取或设置 TryExpr 中的 finally 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
finally关键字时,抛出异常。
prop keywordT
public mut prop keywordT: Token
功能:获取或设置 TryExpr 中的 try 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
try关键字时,抛出异常。
prop keywordsC
public mut prop keywordsC: Tokens
功能:获取或设置 TryExpr 中的关键字 catch。
类型:Tokens
异常:
- ASTException - 当设置的 Token 不是
catch关键字时,抛出异常。
prop resourceSpec
public mut prop resourceSpec: ArrayList<VarDecl>
功能:获取或设置 TryExpr 中 Try-with-resources 类型表达式的实例化对象序列。
prop tryBlock
public mut prop tryBlock: Block
功能:获取或设置 TryExpr 中由表达式与声明组成的块。
类型:Block
init()
public init()
功能:构造一个默认的 TryExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 TryExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 TryExpr 节点时,抛出异常。
class TupleLiteral
public class TupleLiteral <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示元组字面量节点。
TupleLiteral 节点:使用格式 (expr1, expr2, ... , exprN) 表示,每个 expr 是一个表达式。
父类型:
prop elements
public mut prop elements: ArrayList<Expr>
功能:获取或设置 TupleLiteral 中的表达式列表。
prop lParen
public mut prop lParen: Token
功能:获取或设置 TupleLiteral 中的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 TupleLiteral 中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 TupleLiteral 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 TupleLiteral 对象。
参数:
- inputs: Tokens - 将要构造 TupleLiteral 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 TupleLiteral 节点时,抛出异常。
class TuplePattern
public class TuplePattern <: Pattern {
public init()
public init(inputs: Tokens)
}
功能:表示 Tuple 模式节点。
用于 tuple 值的匹配,如 case ("Bob", age) => 1 中的 ("Bob", age)。
父类型:
prop commas
public mut prop commas: Tokens
功能:获取或设置 TuplePattern 节点中的 "," 词法单元序列,可能为空。
类型:Tokens
异常:
- ASTException - 当设置的 Tokens 不是 "," 词法单元序列时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 TuplePattern 节点中的 "(" 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop patterns
public mut prop patterns: ArrayList<Pattern>
功能:获取或设置 TuplePattern 节点中的一组 Pattern 节点。
prop rParen
public mut prop rParen: Token
功能:获取或设置 TuplePattern 节点中的 ")" 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 TuplePattern 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 TuplePattern 对象。
参数:
- inputs: Tokens - 将要构造 TuplePattern 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 TuplePattern 节点时,抛出异常。
class TupleType
public class TupleType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示元组类型节点。
例如 var a : (Int64, Int32) 中的 (Int64, Int32)。
父类型:
prop lParen
public mut prop lParen: Token
功能:获取或设置 TupleType 节点中的 "(" 词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 TupleType 节点中的 ")" 词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop types
public mut prop types: ArrayList<TypeNode>
功能:获取或设置 TupleType 节点中的类型节点列表。
init()
public init()
功能:构造一个默认的 TupleType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 TupleType 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 TupleType 节点时,抛出异常。
class TypeAliasDecl
public class TypeAliasDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示类型别名节点。
一个 TypeAliasDecl 节点: type Point2D = Float64。
说明:
该节点中
type作为关键字,紧跟任意的合法标识符,其后的type是任意的 top-level 可见的类型,标识符和type之间使用=进行连接。
父类型:
prop aliasType
public mut prop aliasType: TypeNode
功能:获取或设置将要别名的类型。
类型:TypeNode
prop assign
public mut prop assign: Token
功能:获取或设置标识符和 type 之间的 =。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
=时,抛出异常。
init()
public init()
功能:构造一个默认的 TypeAliasDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 TypeAliasDecl 对象。
参数:
- inputs: Tokens - 将要构造 TypeAliasDecl 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 TypeAliasDecl 节点时,抛出异常。
class TypeConvExpr
public class TypeConvExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示类型转换表达式。
用于实现若干数值类型间的转换。一个 TypeConvExpr 节点:Int8(32)。
父类型:
prop expr
public mut prop expr: Expr
功能:获取或设置 TypeConvExpr 中进行类型转化的原始表达式。
类型:Expr
prop lParen
public mut prop lParen: Token
功能:获取或设置 TypeConvExpr 中的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 TypeConvExpr 中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop targetType
public mut prop targetType: PrimitiveType
功能:获取或设置 TypeConvExpr 中将要转换到的目标类型。
init()
public init()
功能:构造一个默认的 TypeConvExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 TypeConvExpr 对象。
参数:
- inputs: Tokens - 将要构造 TypeConvExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 TypeConvExpr 节点时,抛出异常。
class TypeNode
public open class TypeNode <: Node
功能:所有类型节点的父类,继承自 Node。
父类型:
prop typeParameterName
public mut prop typeParameterName: Token
功能:获取或设置类型节点的参数,如:(p1:Int64, p2:Int64) 中的 p1 和 p2,可能为 ILLEGAL 的词法单元。
类型:Token
prop colon
public mut prop colon: Token
功能:获取或设置 TypeNode 节点中的操作符 ":",可能为 ILLEGAL 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ":" 操作符时,抛出异常。
class TypePattern
public class TypePattern <: Pattern {
public init()
public init(inputs: Tokens)
}
功能:表示类型模式节点。
用于判断一个值的运行时类型是否是某个类型的子类型,如 case b: Base => 0 中的 b: Base。
父类型:
prop colon
public mut prop colon: Token
功能:获取或设置 TypePattern 节点中的 ":" 操作符的词法单元节点。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ":" 操作符时,抛出异常。
prop pattern
public mut prop pattern: Pattern
功能:获取或设置 TypePattern 节点中的模式节点。
类型:Pattern
prop patternType
public mut prop patternType: TypeNode
功能:获取或设置 TypePattern 节点中的待匹配的模式类型节点。
类型:TypeNode
init()
public init()
功能:构造一个默认的 TypePattern 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 TypePattern 对象。
参数:
- inputs: Tokens - 将要构造 TypePattern 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 TypePattern 节点时,抛出异常。
class UnaryExpr
public class UnaryExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示一个一元操作表达式节点。
父类型:
prop expr
public mut prop expr: Expr
功能:获取或设置 UnaryExpr 节点中的操作数。
类型:Expr
prop op
public mut prop op: Token
功能:获取或设置 UnaryExpr 节点中的一元操作符。
类型:Token
init()
public init()
功能:构造一个默认的 UnaryExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 UnaryExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 UnaryExpr 节点时,抛出异常。
class VArrayExpr
public class VArrayExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 VArray 的实例节点。
一个 VArrayExpr 节点:let arr: VArray<Int64, $5> = VArray<Int64, $5>({ i => i }) 中的 VArray<Int64, $5>({ i => i })。
父类型:
prop arguments
public mut prop arguments: ArrayList<Argument>
功能:获取或设置 VArrayExpr 中的中的初始化参数序列。
prop lParen
public mut prop lParen: Token
功能:获取或设置 VArrayExpr 中的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 VArrayExpr 中的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
prop vArrayType
public mut prop vArrayType: VArrayType
功能:获取或设置 VArrayExpr 的 VArray 类型节点。
类型:VArrayType
init()
public init()
功能:构造一个默认的 VArrayExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 VArrayExpr 对象。
参数:
- inputs: Tokens - 将要构造 VArrayExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 VArrayExpr 节点时,抛出异常。
class VArrayType
public class VArrayType <: TypeNode {
public init()
public init(inputs: Tokens)
}
功能:表示 VArray 类型节点。
使用泛型 VArray<T, size: Int64> 表示 VArray 类型。
父类型:
prop dollar
public mut prop dollar: Token
功能:获取或设置 VArrayType 节点中的操作符 $ 的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
$词法单元时,抛出异常。
prop elementTy
public mut prop elementTy: TypeNode
功能:获取或设置 VArrayType 节点中的类型变元节点,如 VArray<Int16, $0> 中的 Int16。
类型:TypeNode
prop keyword
public mut prop keyword: Token
功能:获取或设置 VArrayType 节点的关键字 VArray 的词法单元。
类型:Token
prop lAngle
public mut prop lAngle: Token
功能:获取或设置 VArrayType 节点左尖括号的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是左尖括号时,抛出异常。
prop rAngle
public mut prop rAngle: Token
功能:获取或设置 VArrayType 节点右尖括号的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是右尖括号时,抛出异常。
prop size
public mut prop size: Token
功能:获取或设置 VArrayType 节点中类型长度的词法单元。
类型:Token
init()
public init()
功能:构造一个默认的 VArrayType 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 VArrayType 对象。
参数:
- inputs: Tokens - 将要构造 VArrayType 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 VArrayType 节点时,抛出异常。
class VarDecl
public class VarDecl <: Decl {
public init()
public init(inputs: Tokens)
}
功能:表示变量定义节点。
一个 VarDecl 节点: var a: String,var b: Int64 = 1。
说明:
变量的定义主要包括如下几个部分:修饰符、关键字、patternsMaybeIrrefutable、变量类型和变量初始值。
父类型:
prop assign
public mut prop assign: Token
功能:获取或设置 VarDecl 节点中的赋值操作符的位置信息。
类型:Token
异常:
- ASTException - 当设置的 Token 不是赋值操作符时,抛出异常。
prop colon
public mut prop colon: Token
功能:获取或设置 VarDecl 节点中的冒号位置信息。
类型:Token
异常:
- ASTException - 当设置的 Token 不是冒号时,抛出异常。
prop declType
public mut prop declType: TypeNode
功能:获取或设置 VarDecl 节点的变量类型。
类型:TypeNode
异常:
- ASTException - 当 VarDecl 节点没有声明变量类型时,抛出异常。
prop expr
public mut prop expr: Expr
功能:获取或设置 VarDecl 节点的变量初始化节点。
类型:Expr
异常:
- ASTException - 当 VarDecl 节点没有对变量进行初始化时,抛出异常。
prop pattern
public mut prop pattern: Pattern
功能:获取或设置 VarDecl 节点的 pattern 节点。
类型:Pattern
异常:
- ASTException - 当 VarDecl 节点没有声明 pattern 节点时,抛出异常。
init()
public init()
功能:构造一个默认的 VarDecl 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 VarDecl 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 VarDecl 节点时,抛出异常。
func isConst()
public func isConst(): Bool
功能:判断是否是一个 Const 类型的节点。
返回值:
- Bool - 是一个
Const类型的节点返回 true;反之,返回 false。
class VarOrEnumPattern
public class VarOrEnumPattern <: Pattern {
public init()
public init(identifier: Token)
}
功能:表示当模式的标识符为 Enum 构造器时的节点。
例如 case RED 中的 RED 为 Enum 构造器。
父类型:
prop identifier
public mut prop identifier: Token
功能:获取或设置 VarOrEnumPattern 节点中的标识符的词法单元。
类型:Token
init()
public init()
功能:构造一个默认的 VarOrEnumPattern 对象。
init(Tokens)
public init(identifier: Token)
功能:构造一个 VarOrEnumPattern 对象。
参数:
- identifier: Token - 将要构造 VarOrEnumPattern 类型的词法单元。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 VarOrEnumPattern 节点时,抛出异常。
class VarPattern
public class VarPattern <: Pattern {
public init()
public init(identifier: Token)
}
功能:表示绑定模式节点。
使用一个合法的标识符表示,如 for (i in 1..10) 中的 i。
父类型:
prop identifier
public mut prop identifier: Token
功能:获取或设置 VarPattern 节点中的标识符符的词法单元。
类型:Token
init()
public init()
功能:构造一个默认的 VarPattern 对象。
init(Tokens)
public init(identifier: Token)
功能:构造一个 VarPattern 对象。
参数:
- identifier: Token - 将要构造 VarPattern 类型的词法单元。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 VarPattern 节点时,抛出异常。
class Visitor
public abstract class Visitor
功能:一个抽象类,其内部默认定义了访问不同类型 AST 节点访问(visit)函数。
说明:
visit函数搭配traverse一起使用,可实现对节点的访问和修改, 所有visit函数都有默认为空的实现,可以按需实现需要的visit方法。- 该类需要被继承使用,并允许子类重新定义访问函数。
func breakTraverse()
public func breakTraverse(): Unit
功能:用于重写 visit 函数中,通过调用该函数来终止继续遍历子节点的行为。
class WhileExpr
public class WhileExpr <: Expr {
public init()
public init(inputs: Tokens)
}
功能:表示 while 表达式。
while 是关键字,while 之后是一个小括号,小括号内可以是一个表达式或者一个 let 声明的解构匹配,接着是一个 Block 节点。
父类型:
prop block
public mut prop block: Block
功能:获取或设置 WhileExpr 中的块节点。
类型:Block
prop condition
public mut prop condition: Expr
功能:获取或设置关键字 WhileExpr 中的条件表达式。
类型:Expr
prop keyword
public mut prop keyword: Token
功能:获取或设置 WhileExpr 节点中 while 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是
while关键字时,抛出异常。
prop lParen
public mut prop lParen: Token
功能:获取或设置 WhileExpr 中 while 关键字之后的 "("。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "(" 时,抛出异常。
prop rParen
public mut prop rParen: Token
功能:获取或设置 WhileExpr 中 while 关键字之后的 ")"。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 ")" 时,抛出异常。
init()
public init()
功能:构造一个默认的 WhileExpr 对象。
init(Tokens)
public init(inputs: Tokens)
功能:构造一个 WhileExpr 对象。
参数:
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 WhileExpr 节点时,抛出异常。
class WildcardExpr
public class WildcardExpr <: Expr {
public init()
public init(keyword: Tokens)
}
功能:表示通配符表达式节点。
父类型:
prop keyword
public mut prop keyword: Token
功能:获取 WildcardExpr 的 "_" 关键字。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "_" 关键字时,抛出异常。
init()
public init()
功能:构造一个默认的 WildcardExpr 对象。
init(Tokens)
public init(keyword: Tokens)
功能:构造一个 WildcardExpr 对象。
参数:
- keyword: Tokens - 将要构造 WildcardExpr 类型的词法单元集合 (Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 WildcardExpr 节点时,抛出异常。
class WildcardPattern
public class WildcardPattern <: Pattern {
public init()
public init(keyword: Tokens)
}
功能:表示通配符模式节点。
使用下划线 "_" 表示,可以匹配任意值。
父类型:
prop wildcard
public mut prop wildcard: Token
功能:获取或设置 WildcardPattern 节点中的 "_" 操作符的词法单元。
类型:Token
异常:
- ASTException - 当设置的 Token 不是 "_" 操作符时,抛出异常。
init()
public init()
功能:构造一个默认的 WildcardPattern 对象。
init(Tokens)
public init(keyword: Tokens)
功能:构造一个 WildcardPattern 对象。
参数:
- keyword: Tokens - 将要构造 WildcardPattern 类型的词法单元集合(Tokens)。
异常:
- ASTException - 当输入的 Tokens 类型无法构造为 WildcardPattern 节点时,抛出异常。
枚举
enum DiagReportLevel
public enum DiagReportLevel {
ERROR|
WARNING
}
功能:表示报错接口的信息等级,支持 ERROR 和 WARNING 两种等级。
ERROR
ERROR
功能:构造一个表示 ERROR 的枚举实例。
WARNING
WARNING
功能:构造一个表示 WARNING 的枚举实例。
func level()
public func level(): Int32
功能:返回枚举值对应的整型。
返回值:
- Int32 - 枚举值对应的整型。
ERROR返回 0,WARNING返回 1。
enum ImportKind
public enum ImportKind <: ToString {
Single | Alias | All | Multi
}
功能:表示导入语句的类型。
父类型:
Single
Single
功能:表示单导入,如 import a.b。
Alias
Alias
功能:表示别名导入,如 import a.b as c。
All
All
功能:表示全导入,如 import a.b.*。
Multi
Multi
功能:表示多导入,如 import a.{b, c, d}。
func toString()
public func toString(): String
功能:将 ImportKind 类型转化为字符串类型表示。
返回值:
- String - ImportKind 转换后的字符串值。
enum TokenKind
public enum TokenKind <: ToString {
DOT| /* "." */
COMMA| /* "," */
LPAREN| /* "(" */
RPAREN| /* ")" */
LSQUARE| /* "[" */
RSQUARE| /* "]" */
LCURL| /* "{" */
RCURL| /* "}" */
EXP| /* "**" */
MUL| /* "*" */
MOD| /* "%" */
DIV| /* "/" */
ADD| /* "+" */
SUB| /* "-" */
INCR| /* "++" */
DECR| /* "--" */
AND| /* "&&" */
OR| /* "||" */
COALESCING| /* "??" */
PIPELINE| /* "|>" */
COMPOSITION| /* "~>" */
NOT| /* "!" */
BITAND| /* "&" */
BITOR| /* "|" */
BITXOR| /* "^" */
BITNOT| /* "~" */
LSHIFT| /* "<<" */
RSHIFT| /* ">>" */
COLON| /* ":" */
SEMI| /* ";" */
ASSIGN| /* "=" */
ADD_ASSIGN| /* "+=" */
SUB_ASSIGN| /* "-=" */
MUL_ASSIGN| /* "*=" */
EXP_ASSIGN| /* "**=" */
DIV_ASSIGN| /* "/=" */
MOD_ASSIGN| /* "%=" */
AND_ASSIGN| /* "&&=" */
OR_ASSIGN| /* "||=" */
BITAND_ASSIGN| /* "&=" */
BITOR_ASSIGN| /* "|=" */
BITXOR_ASSIGN| /* "^=" */
LSHIFT_ASSIGN| /* "<<=" */
RSHIFT_ASSIGN| /* ">>=" */
ARROW| /* "->" */
BACKARROW| /* "<-" */
DOUBLE_ARROW| /* "=>" */
RANGEOP| /* ".." */
CLOSEDRANGEOP| /* "..=" */
ELLIPSIS| /* "..." */
HASH| /* "#" */
AT| /* "@" */
QUEST| /* "?" */
LT| /* "<" */
GT| /* ">" */
LE| /* "<=" */
GE| /* ">=" */
IS| /* "is" */
AS| /* "as" */
NOTEQ| /* "!=" */
EQUAL| /* "==" */
WILDCARD| /* "_" */
INT8| /* "Int8" */
INT16| /* "Int16" */
INT32| /* "Int32" */
INT64| /* "Int64" */
INTNATIVE| /* "IntNative" */
UINT8| /* "UInt8" */
UINT16| /* "UInt16" */
UINT32| /* "UInt32" */
UINT64| /* "UInt64" */
UINTNATIVE| /* "UIntNative" */
FLOAT16| /* "Float16" */
FLOAT32| /* "Float32" */
FLOAT64| /* "Float64" */
RUNE| /* "Rune" */
BOOLEAN| /* "Bool" */
NOTHING| /* "Nothing" */
UNIT| /* "Unit" */
STRUCT| /* "struct" */
ENUM| /* "enum" */
VARRAY| /* "VArray" */
THISTYPE| /* "This" */
PACKAGE| /* "package" */
IMPORT| /* "import" */
CLASS| /* "class" */
INTERFACE| /* "interface" */
FUNC| /* "func" */
MACRO| /* "macro" */
QUOTE| /* "quote" */
DOLLAR| /* "$" */
LET| /* "let" */
VAR| /* "var" */
CONST| /* "const" */
TYPE| /* "type" */
INIT| /* "init" */
THIS| /* "this" */
SUPER| /* "super" */
IF| /* "if" */
ELSE| /* "else" */
CASE| /* "case" */
TRY| /* "try" */
CATCH| /* "catch" */
FINALLY| /* "finally" */
FOR| /* "for" */
DO| /* "do" */
WHILE| /* "while" */
THROW| /* "throw" */
RETURN| /* "return" */
CONTINUE| /* "continue" */
BREAK| /* "break" */
IN| /* "in" */
NOT_IN| /* "!in" */
MATCH| /* "match" */
WHERE| /* "where" */
EXTEND| /* "extend" */
WITH| /* "with" */
PROP| /* "prop" */
STATIC| /* "static" */
PUBLIC| /* "public" */
PRIVATE| /* "private" */
INTERNAL| /* "internal" */
PROTECTED| /* "protected" */
OVERRIDE| /* "override" */
REDEF| /* "redef" */
ABSTRACT| /* "abstract" */
SEALED| /* "sealed" */
OPEN| /* "open" */
FOREIGN| /* "foreign" */
INOUT| /* "inout" */
MUT| /* "mut" */
UNSAFE| /* "unsafe" */
OPERATOR| /* "operator" */
SPAWN| /* "spawn" */
SYNCHRONIZED| /* "synchronized" */
UPPERBOUND| /* "<:" */
MAIN| /* "main" */
IDENTIFIER| /* "x" */
PACKAGE_IDENTIFIER| /* e.g. "x-y" */
INTEGER_LITERAL| /* e.g. "1" */
RUNE_BYTE_LITERAL| /* e.g. "b'x'" */
FLOAT_LITERAL| /* e.g. "'1.0'" */
COMMENT| /* e.g. "/*xx*/" */
NL| /* newline */
END| /* end of file */
SENTINEL| /* ";" */
RUNE_LITERAL| /* e.g. "r'x'" */
STRING_LITERAL| /* e.g. ""xx"" */
SINGLE_QUOTED_STRING_LITERAL|
/* e.g. "'xx'" */
JSTRING_LITERAL| /* e.g. "J"xx"" */
MULTILINE_STRING| /* e.g. """"aaa"""" */
MULTILINE_RAW_STRING| /* e.g. "#"aaa"#" */
BOOL_LITERAL| /* "true" or "false" */
UNIT_LITERAL| /* "()" */
DOLLAR_IDENTIFIER| /* e.g. "$x" */
ANNOTATION| /* e.g. "@When" */
AT_EXCL| /* e.g. "@!" */
ILLEGAL|
...
}
功能:表示仓颉编译内部所有的词法结构,包括符号、关键字、标识符、换行等。
父类型:
ABSTRACT
ABSTRACT
功能:构造一个表示 abstract 的枚举实例。
ADD
ADD
功能:构造一个表示 + 的枚举实例。
ADD_ASSIGN
ADD_ASSIGN
功能:构造一个表示 += 的枚举实例。
AND
AND
功能:构造一个表示 && 的枚举实例。
AND_ASSIGN
AND_ASSIGN
功能:构造一个表示 &&= 的枚举实例。
ANNOTATION
ANNOTATION
功能:构造一个表示注解的枚举实例。
ARROW
ARROW
功能:构造一个表示 -> 的枚举实例。
AS
AS
功能:构造一个表示 as 的枚举实例。
ASSIGN
ASSIGN
功能:构造一个表示 = 的枚举实例。
AT
AT
功能:构造一个表示 @ 的枚举实例。
AT_EXCL
AT_EXCL
功能:构造一个表示 @! 的枚举实例。
BACKARROW
BACKARROW
功能:构造一个表示 <- 的枚举实例。
BITAND
BITAND
功能:构造一个表示 & 的枚举实例。
BITAND_ASSIGN
BITAND_ASSIGN
功能:构造一个表示 &= 的枚举实例。
BITNOT
BITNOT
功能:构造一个表示 ~ 的枚举实例。
BITOR
BITOR
功能:构造一个表示 | 的枚举实例。
BITOR_ASSIGN
BITOR_ASSIGN
功能:构造一个表示 |= 的枚举实例。
BITXOR
BITXOR
功能:构造一个表示 ^ 的枚举实例。
BITXOR_ASSIGN
BITXOR_ASSIGN
功能:构造一个表示 ^= 的枚举实例。
BOOLEAN
BOOLEAN
功能:构造一个表示 bool 的枚举实例。
BOOL_LITERAL
BOOL_LITERAL
功能:构造一个表示布尔类型字面量的枚举实例。
BREAK
BREAK
功能:构造一个表示 break 的枚举实例。
CASE
CASE
功能:构造一个表示 case 的枚举实例。
CATCH
CATCH
功能:构造一个表示 catch 的枚举实例。
CLASS
CLASS
功能:构造一个表示 class 的枚举实例。
CLOSEDRANGEOP
CLOSEDRANGEOP
功能:构造一个表示 ..= 的枚举实例。
COALESCING
COALESCING
功能:构造一个表示 ?? 的枚举实例。
COLON
COLON
功能:构造一个表示 : 的枚举实例。
COMMA
COMMA
功能:构造一个表示 , 的枚举实例。
COMMENT
COMMENT
功能:构造一个表示注释的枚举实例。
COMPOSITION
COMPOSITION
功能:构造一个表示 ~> 的枚举实例。
CONST
CONST
功能:构造一个表示 const 的枚举实例。
CONTINUE
CONTINUE
功能:构造一个表示 continue 的枚举实例。
DECR
DECR
功能:构造一个表示 -- 的枚举实例。
DIV
DIV
功能:构造一个表示 / 的枚举实例。
DIV_ASSIGN
DIV_ASSIGN
功能:构造一个表示 /= 的枚举实例。
DO
DO
功能:构造一个表示 do 的枚举实例。
DOLLAR
DOLLAR
功能:构造一个表示 $ 的枚举实例。
DOLLAR_IDENTIFIER
DOLLAR_IDENTIFIER
功能:构造一个表示插值字符串的枚举实例。
DOT
DOT
功能:构造一个表示 . 的枚举实例。
DOUBLE_ARROW
DOUBLE_ARROW
功能:构造一个表示 => 的枚举实例。
ELLIPSIS
ELLIPSIS
功能:构造一个表示 ... 的枚举实例。
ELSE
ELSE
功能:构造一个表示 else 的枚举实例。
END
END
功能:构造一个表示 EOF 的枚举实例。
ENUM
ENUM
功能:构造一个表示 enum 的枚举实例。
EQUAL
EQUAL
功能:构造一个表示 == 的枚举实例。
EXP
EXP
功能:构造一个表示 ** 的枚举实例。
EXP_ASSIGN
EXP_ASSIGN
功能:构造一个表示 **= 的枚举实例。
EXTEND
EXTEND
功能:构造一个表示 extend 的枚举实例。
FINALLY
FINALLY
功能:构造一个表示 finally 的枚举实例。
FLOAT16
FLOAT16
功能:构造一个表示 float16 的枚举实例。
FLOAT32
FLOAT32
功能:构造一个表示 float32 的枚举实例。
FLOAT64
FLOAT64
功能:构造一个表示 float64 的枚举实例。
FLOAT_LITERAL
FLOAT_LITERAL
功能:构造一个表示浮点字面量的枚举实例。
FOR
FOR
功能:构造一个表示 for 的枚举实例。
FOREIGN
FOREIGN
功能:构造一个表示 foreign 的枚举实例。
FUNC
FUNC
功能:构造一个表示 func 的枚举实例。
GE
GE
功能:构造一个表示 >= 的枚举实例。
GT
GT
功能:构造一个表示 > 的枚举实例。
HASH
HASH
功能:构造一个表示 # 的枚举实例。
IDENTIFIER
IDENTIFIER
功能:构造一个表示标识符的枚举实例。
PACKAGE_IDENTIFIER
PACKAGE_IDENTIFIER
功能:构造一个表示包标识符的枚举实例。
IF
IF
功能:构造一个表示 if 的枚举实例。
ILLEGAL
ILLEGAL
功能:构造一个表示非法的枚举实例。
IMPORT
IMPORT
功能:构造一个表示 import 的枚举实例。
IN
IN
功能:构造一个表示 in 的枚举实例。
INCR
INCR
功能:构造一个表示 ++ 的枚举实例。
INIT
INIT
功能:构造一个表示 init 的枚举实例。
INOUT
INOUT
功能:构造一个表示 inout 的枚举实例。
INT16
INT16
功能:构造一个表示 int16 的枚举实例。
INT32
INT32
功能:构造一个表示 int32 的枚举实例。
INT64
INT64
功能:构造一个表示 int64 的枚举实例。
INT8
INT8
功能:构造一个表示 int8 的枚举实例。
INTEGER_LITERAL
INTEGER_LITERAL
功能:构造一个表示整型字面量的枚举实例。
INTERFACE
INTERFACE
功能:构造一个表示 interface 的枚举实例。
INTERNAL
INTERNAL
功能:构造一个表示 internal 的枚举实例。
INTNATIVE
INTNATIVE
功能:构造一个表示 intnative 的枚举实例。
IS
IS
功能:构造一个表示 is 的枚举实例。
JSTRING_LITERAL
JSTRING_LITERAL
功能:构造一个表示 JavaSTRING字面量 的枚举实例。
LCURL
LCURL
功能:构造一个表示 { 的枚举实例。
LE
LE
功能:构造一个表示 <= 的枚举实例。
LET
LET
功能:构造一个表示 let 的枚举实例。
LPAREN
LPAREN
功能:构造一个表示 ( 的枚举实例。
LSHIFT
LSHIFT
功能:构造一个表示 << 的枚举实例。
LSHIFT_ASSIGN
LSHIFT_ASSIGN
功能:构造一个表示 <<= 的枚举实例。
LSQUARE
LSQUARE
功能:构造一个表示 [ 的枚举实例。
LT
LT
功能:构造一个表示 < 的枚举实例。
MACRO
MACRO
功能:构造一个表示 macro 的枚举实例。
MAIN
MAIN
功能:构造一个表示 main 的枚举实例。
MATCH
MATCH
功能:构造一个表示 match 的枚举实例。
MOD
MOD
功能:构造一个表示 % 的枚举实例。
MOD_ASSIGN
MOD_ASSIGN
功能:构造一个表示 %= 的枚举实例。
MUL
MUL
功能:构造一个表示 * 的枚举实例。
MULTILINE_RAW_STRING
MULTILINE_RAW_STRING
功能:构造一个表示多行原始字符串字面量的枚举实例。
MULTILINE_STRING
MULTILINE_STRING
功能:构造一个表示多行字符串字面量的枚举实例。
MUL_ASSIGN
MUL_ASSIGN
功能:构造一个表示 *= 的枚举实例。
MUT
MUT
功能:构造一个表示 mut 的枚举实例。
NL
NL
功能:构造一个表示换行符的枚举实例。
NOT
NOT
功能:构造一个表示 ! 的枚举实例。
NOTEQ
NOTEQ
功能:构造一个表示 != 的枚举实例。
NOTHING
NOTHING
功能:构造一个表示 nothing 的枚举实例。
NOT_IN
NOT_IN
功能:构造一个表示 !in 的枚举实例。
OPEN
OPEN
功能:构造一个表示 open 的枚举实例。
OPERATOR
OPERATOR
功能:构造一个表示 operator 的枚举实例。
OR
OR
功能:构造一个表示 || 的枚举实例。
OR_ASSIGN
OR_ASSIGN
功能:构造一个表示 ||= 的枚举实例。
OVERRIDE
OVERRIDE
功能:构造一个表示 override 的枚举实例。
PACKAGE
PACKAGE
功能:构造一个表示 package 的枚举实例。
PIPELINE
PIPELINE
功能:构造一个表示 |> 的枚举实例。
PRIVATE
PRIVATE
功能:构造一个表示 private 的枚举实例。
PROP
PROP
功能:构造一个表示 prop 的枚举实例。
PROTECTED
PROTECTED
功能:构造一个表示 protected 的枚举实例。
PUBLIC
PUBLIC
功能:构造一个表示 public 的枚举实例。
QUEST
QUEST
功能:构造一个表示 ? 的枚举实例。
QUOTE
QUOTE
功能:构造一个表示 quote 的枚举实例。
RANGEOP
RANGEOP
功能:构造一个表示 .. 的枚举实例。
RCURL
RCURL
功能:构造一个表示 } 的枚举实例。
REDEF
REDEF
功能:构造一个表示 redef 的枚举实例。
RETURN
RETURN
功能:构造一个表示 return 的枚举实例。
RPAREN
RPAREN
功能:构造一个表示 ) 的枚举实例。
RSHIFT
RSHIFT
功能:构造一个表示 >> 的枚举实例。
RSHIFT_ASSIGN
RSHIFT_ASSIGN
功能:构造一个表示 >>= 的枚举实例。
RSQUARE
RSQUARE
功能:构造一个表示 ] 的枚举实例。
RUNE
RUNE
功能:构造一个表示 Rune 的枚举实例。
RUNE_BYTE_LITERAL
RUNE_BYTE_LITERAL
功能:构造一个表示字符字节字面量的枚举实例。
RUNE_LITERAL
RUNE_LITERAL
功能:构造一个表示字符字面量的枚举实例。
SEALED
SEALED
功能:构造一个表示 sealed 的枚举实例。
SEMI
SEMI
功能:构造一个表示 ; 的枚举实例。
SENTINEL
SENTINEL
功能:构造一个表示 ; 的枚举实例。
SINGLE_QUOTED_STRING_LITERAL
SINGLE_QUOTED_STRING_LITERAL
功能:构造一个表示单引号字符串字面量的枚举实例。
SPAWN
SPAWN
功能:构造一个表示 spawn 的枚举实例。
STATIC
STATIC
功能:构造一个表示 static 的枚举实例。
STRING_LITERAL
STRING_LITERAL
功能:构造一个表示双引号字符串字面量的枚举实例。
STRUCT
STRUCT
功能:构造一个表示 struct 的枚举实例。
SUB
SUB
功能:构造一个表示 - 的枚举实例。
SUB_ASSIGN
SUB_ASSIGN
功能:构造一个表示 -= 的枚举实例。
SUPER
SUPER
功能:构造一个表示 super 的枚举实例。
SYNCHRONIZED
SYNCHRONIZED
功能:构造一个表示 synchronized 的枚举实例。
THIS
THIS
功能:构造一个表示 this 的枚举实例。
THISTYPE
THISTYPE
功能:构造一个表示 This 的枚举实例。
THROW
THROW
功能:构造一个表示 throw 的枚举实例。
TRY
TRY
功能:构造一个表示 try 的枚举实例。
TYPE
TYPE
功能:构造一个表示 type 的枚举实例。
UINT16
UINT16
功能:构造一个表示 uint16 的枚举实例。
UINT32
UINT32
功能:构造一个表示 uint32 的枚举实例。
UINT64
UINT64
功能:构造一个表示 uint64 的枚举实例。
UINT8
UINT8
功能:构造一个表示 uint8 的枚举实例。
UINTNATIVE
UINTNATIVE
功能:构造一个表示 uintnative 的枚举实例。
UNIT
UNIT
功能:构造一个表示 unit 的枚举实例。
UNIT_LITERAL
UNIT_LITERAL
功能:构造一个表示 unit 字面量的枚举实例。
UNSAFE
UNSAFE
功能:构造一个表示 unsafe 的枚举实例。
UPPERBOUND
UPPERBOUND
功能:构造一个表示 <: 的枚举实例。
VAR
VAR
功能:构造一个表示 var 的枚举实例。
VARRAY
VARRAY
功能:构造一个表示 varray 的枚举实例。
WHERE
WHERE
功能:构造一个表示 where 的枚举实例。
WHILE
WHILE
功能:构造一个表示 while 的枚举实例。
WILDCARD
WILDCARD
功能:构造一个表示 _ 的枚举实例。
WITH
WITH
功能:构造一个表示 with 的枚举实例。
func !=(TokenKind)
public operator func !=(right: TokenKind): Bool
功能:重载不等号操作符,用于比较两个 TokenKind 是否相等。
返回值:
- Bool - 布尔类型。
func ==(TokenKind)
public operator func ==(right: TokenKind): Bool
功能:重载等号操作符,用于比较两个 TokenKind 是否相等。
返回值:
- Bool - 布尔类型。
func toString()
public func toString(): String
功能:将 TokenKind 类型转化为字符串类型表示。
返回值:
结构体
struct Position
public struct Position <: ToBytes {
public let column: Int32
public let fileID: UInt32
public let line: Int32
public init()
public init(fileID: UInt32, line: Int32, column: Int32)
}
功能:表示位置信息的数据结构,包含文件ID,行号和列号。
父类型:
let column
public let column: Int32
功能:获取列号信息。
类型:Int32
let fileID
public let fileID: UInt32
功能:获取文件 ID 信息。
类型:UInt32
let line
public let line: Int32
功能:获取行号信息。
类型:Int32
init()
public init()
功能:构造一个默认的 Position 实例,其中 fileID、line、column 成员变量均为 0。
init(UInt32, Int32, Int32)
public init(fileID: UInt32, line: Int32, column: Int32)
功能:构造一个 Position 实例。
参数:
func dump()
public func dump(): Unit
功能:将 Position 的信息打印出来。
func isEmpty()
public func isEmpty(): Bool
功能:判断行号和列号是否同时为 0。
返回值:
- Bool - 当行号和列号为
0时返回 true。
func toBytes()
public func toBytes(): Array<UInt8>
功能:Position 类型的序列化。
返回值:
operator func !=(Position)
public operator func !=(r: Position): Bool
功能:比较两个 Position 实例是否不等。
参数:
- r: Position - 与当前位置比较的另一个位置实例。
返回值:
operator func ==(Position)
public operator func ==(r: Position): Bool
功能:比较两个 Position 实例是否相等。
参数:
- r: Position - 与当前位置比较的另一个位置实例。
返回值:
struct Token
public struct Token <: ToBytes {
public let kind: TokenKind
public let pos: Position
public let value: String
public var delimiterNum: UInt16 = 1
public init()
public init(kind: TokenKind)
public init(kind: TokenKind, value: String)
}
功能:词法单元类型。
词法单元是构成仓颉源码的最小单元,一组合法的词法单元列表经过语法解析后可生成一个语法树节点。
父类型:
let kind
public let kind: TokenKind
功能:词法单元的类型。词法单元类型有关键字、标识符、运算符、常量值等,具体见 TokenKind 章节。
类型:TokenKind
let pos
public let pos: Position
功能:词法单元在源码中的位置信息。
类型:Position
let value
public let value: String
功能:词法单元的字面量值。
类型:String
var delimiterNum
public var delimiterNum: UInt16 = 1
功能:多行字符串的 '#' 符号个数。
类型:UInt16
init()
public init()
功能:构造一个默认的 Token 对象,其中 TokenKind 类型为 ILLEGAL,value 为空字符串,Position 成员变量均为 0。
init(TokenKind)
public init(kind: TokenKind)
功能:根据词法单元类型,构造一个默认的 Token 对象。
参数:
- kind: TokenKind - 构建词法单元的类型。
init(TokenKind, String)
public init(kind: TokenKind, value: String)
功能:根据词法单元类型 kind 和词法单元值 value,构造一个 Token 对象。
参数:
异常:
- IllegalArgumentException - 当输入的
kind与value不匹配时,抛出异常点。
func addPosition(UInt32, Int32, Int32)
public func addPosition(fileID: UInt32, line: Int32, colum: Int32): Token
功能:补充词法单元的位置信息。
参数:
返回值:
func dump()
public func dump(): Unit
功能:将 Token 的信息打印出来。
func toBytes()
public func toBytes(): Array<UInt8>
功能:Token 类型的序列化。
返回值:
operator func !=(Token)
public operator func !=(r: Token): Bool
功能:判断两个 Token 对象是否不相等。
参数:
返回值:
- Bool - 两个词法单元的种类
ID、值、位置不相同时,返回 true。
operator func +(Token)
public operator func +(r: Token): Tokens
功能:使用当前 Token 添加一个 Token 以获取新的 Tokens。
参数:
返回值:
operator func +(Tokens)
public operator func +(r: Tokens): Tokens
功能:使用当前 Token 添加一个 Tokens 以获取新的 Tokens。
参数:
返回值:
operator func ==(Token)
public operator func ==(r: Token): Bool
功能:判断两个 Token 对象是否相等。
参数:
返回值:
- Bool - 两个词法单元的种类
ID、值、位置相同时,返回 true。
异常类
class ASTException
public class ASTException <: Exception {
public init()
public init(message: String)
}
功能:ast 库的异常类,在 ast 库调用过程中发生异常时使用。
父类型:
init()
public init()
功能:构造一个默认的 ASTException 对象。
init(String)
public init(message: String)
功能:根据异常信息构造一个 ASTException 对象。
参数:
- message: String - 异常信息。
class MacroContextException
public class MacroContextException <: Exception {
public init()
public init(message: String)
}
功能:ast库的上下文宏异常类,在上下文宏的相关接口中发生异常时使用。
父类型:
init()
public init()
功能:构造一个默认的 MacroContextException 对象。
init(String)
public init(message: String)
功能:根据异常信息构造一个 MacroContextException 对象。
参数:
- message: String - 异常信息。
class ParseASTException
public class ParseASTException <: Exception {
public init()
public init(message: String)
}
功能:ast 库的解析异常类,在节点解析过程中发生异常时使用。
父类型:
init()
public init()
功能:构造一个默认的 ParseASTException 对象。
init(String)
public init(message: String)
功能:根据异常信息构造一个 ParseASTException 对象。
参数:
- message: String - 异常信息。
Macro With Context
宏定义如下:
// macro_definition.cj
macro package macro_definition
import std.ast.*
public macro Outter(input: Tokens): Tokens {
return input
}
public macro Inner(input: Tokens): Tokens {
assertParentContext("Outter")
return input
}
宏调用如下:
// macro_call.cj
package macro_calling
import macro_definition.*
main() {
@Outter var a = 0
@Inner var b = 0 // error: The macro call 'Inner' should with the surround code contains a call 'Outter'.
}
编译命令如下:
# 先编译宏定义文件
cjc macro_definition.cj --compile-macro
# 编译使用宏的文件
cjc macro_call.cj -o demo
如上代码所示,Inner 宏在定义时使用了 assertParentContext 函数用于检查其在调用阶段是否位于 Outter 宏中,在代码示例的宏调用场景下,由于 Outter 和 Inner 在调用时不存在这样的嵌套关系,因此编译器将报告一个错误。
宏定义如下:
// macro_definition.cj
macro package macro_definition
import std.ast.*
public macro Outter(input: Tokens): Tokens {
let messages = getChildMessages("Inner")
for (m in messages) {
let value1 = m.getString("key1") // get value: "value1"
let value2 = m.getString("key2") // get value: "value2"
println("value1: ${value1} value2: ${value2}")
}
return input
}
public macro Inner(input: Tokens): Tokens {
assertParentContext("Outter")
setItem("key1", "value1")
setItem("key2", "value2")
return input
}
宏调用如下:
// macro_call.cj
import std.ast.*
import macro_definition.*
main() {
@Outter(
@Inner var cnt = 0
)
println(cnt)
}
编译命令如下:
# 先编译宏定义文件
cjc macro_definition.cj --compile-macro
# 编译使用宏的文件
cjc macro_call.cj -o demo
编译阶段输出:
value1: value1 value2: value2
在上面的代码中,内层宏 Inner 通过 setItem 向外层宏发送信息;Outter 宏通过 getChildMessages 函数接收到 Inner 发送的一组信息对象(Outter 中可以调用多次 Inner);最后通过该信息对象的 getString 函数接收对应的值。
语法树节点打印
仓颉 ast 包提供了丰富的语法树节点用于表示仓颉源码。由于节点种类丰富、不同节点间属性不同,使用过程可能会发生混淆不清的情况,为此我们为每个 AST 节点实现了 dump 函数方便实时查看语法树节点的整体结构,避免重复查看该手册带来的困扰。
示例:
import std.ast.*
main() {
let input = quote(var demo: Int64 = 1) // 假设当前代码所在行数为:3
let varDecl = parseDecl(input)
varDecl.dump()
}
运行结果:
VarDecl {
-keyword: Token {
value: "var"
kind: VAR
pos: 3: 23
}
-identifier: Token {
value: "demo"
kind: IDENTIFIER
pos: 3: 27
}
-declType: PrimitiveType {
-keyword: Token {
value: "Int64"
kind: INT64
pos: 3: 33
}
}
-assign: Token {
value: "="
kind: ASSIGN
pos: 3: 39
}
-expr: LitConstExpr {
-literal: Token {
value: "1"
kind: INTEGER_LITERAL
pos: 3: 41
}
}
}
操作 AST 对象示例
获取 ClassDecl 类型的节点后,可以对该节点进行增、删、改、查等操作。代码如下所示:
import std.ast.*
main() {
let input: Tokens = quote(
class Data {
var a: Int32
init(a_: Int32) {
a = a_
}
}
)
let decl = parseDecl(input) // 获取一个 Decl 声明节点
var classDecl = match (decl as ClassDecl) { // decl 的具体类型为 ClassDecl, 将其进行类型转化。
case Some(v) => v
case None => throw Exception()
}
var identifier = classDecl.identifier
// 为该节点增加一个成员函数用于获取a的值
var funcdecl = FuncDecl(quote(func getValue() {a}))
classDecl.body.decls.add(funcdecl)
println("Identifier value is ${identifier.value}")
println("ClassDecl body size is ${classDecl.body.decls.size}")
0
}
运行结果:
Identifier value is Data
ClassDecl body size is 3
将仓颉源码解析为 AST 对象示例
如下有一个类 Data:
class Data {
var a: Int32
init(a_: Int32) {
a = a_
}
}
利用解析函数将上述代码解析为一个 Decl 对象,代码如下所示:
import std.ast.*
main() {
let input: Tokens = quote(
class Data {
var a: Int32
init(a_: Int32) {
a = a_
}
}
)
let decl = parseDecl(input) // 获取一个 Decl 声明节点
var classDecl = match (decl as ClassDecl) { // decl 的具体类型为 ClassDecl, 将其进行类型转化。
case Some(v) => v
case None => throw Exception()
}
classDecl.dump()
}
运行结果:
ClassDecl {
-keyword: Token {
value: "class"
kind: CLASS
pos: 5: 9
}
-identifier: Token {
value: "Data"
kind: IDENTIFIER
pos: 5: 15
}
-body: Body {
-decls: 0, VarDecl {
-keyword: Token {
value: "var"
kind: VAR
pos: 6: 13
}
-identifier: Token {
value: "a"
kind: IDENTIFIER
pos: 6: 17
}
-declType: PrimitiveType {
-keyword: Token {
value: "Int32"
kind: INT32
pos: 6: 20
}
}
}
-decls: 1, FuncDecl {
-keyword: Token {
value: "init"
kind: INIT
pos: 7: 13
}
-identifier: Token {
value: "init"
kind: IDENTIFIER
pos: 7: 13
}
-funcParams: 0, FuncParam {
-identifier: Token {
value: "a_"
kind: IDENTIFIER
pos: 7: 18
}
-colon: Token {
value: ":"
kind: COLON
pos: 7: 20
}
-paramType: PrimitiveType {
-keyword: Token {
value: "Int32"
kind: INT32
pos: 7: 22
}
}
}
-block: Block {
-nodes: 0, AssignExpr {
-leftExpr: RefExpr {
-identifier: Token {
value: "a"
kind: IDENTIFIER
pos: 8: 17
}
}
-assign: Token {
value: "="
kind: ASSIGN
pos: 8: 19
}
-rightExpr: RefExpr {
-identifier: Token {
value: "a_"
kind: IDENTIFIER
pos: 8: 21
}
}
}
}
}
}
}
自定义报错接口
仓颉 ast 包提供了自定义报错接口 diagReport。方便定义宏的用户,在解析传入 Tokens 时,对错误 Tokens 内容进行自定义报错。
自定义报错接口提供同原生编译器报错一样的输出格式,允许用户报 WARNING 和 ERROR 两类错误提示信息。
正确使用示例
宏定义如下:
// macro_definition.cj
macro package macro_definition
import std.ast.*
public macro testDef(input: Tokens): Tokens {
for (i in 0..input.size) {
if (input[i].kind == IDENTIFIER) {
diagReport(DiagReportLevel.ERROR, input[i..(i + 1)], "This expression is not allowed to contain identifier", "Here is the illegal identifier")
}
}
return input
}
宏调用如下:
// macro_call.cj
package macro_calling
import std.ast.*
import macro_definition.*
main(): Int64 {
let a = @testDef(1)
let b = @testDef(a)
let c = @testDef(1 + a)
return 0
}
编译命令如下:
# 先编译宏定义文件
cjc macro_definition.cj --compile-macro
# 编译使用宏的文件
cjc macro_call.cj -o demo
报错提示信息如下:
error: This expression is not allowed to contain identifier
==> call.cj:9:22:
|
9 | let b = @testDef(a)
| ^ Here is the illegal identifier
|
error: This expression is not allowed to contain identifier
==> call.cj:10:26:
|
10 | let c = @testDef(1 + a)
| ^ Here is the illegal identifier
|
2 errors generated, 2 errors printed.
非宏展开过程中调用示例
import std.ast.*
func A(input: Tokens) {
diagReport(DiagReportLevel.ERROR, input, "Message", "Hint") // 该调用处在普通函数 A 中,diagReport 实际不会执行任何操作
}
main() {
let tokens = quote(var a = 0)
A(tokens)
}
自定义访问函数遍历 AST 对象示例
定义访问变量声明节点的行为:继承 Visitor 并重写访问函数,找到未定义变量,将其变量词法单元存起来。
import std.ast.*
class MyVisitor <: Visitor {
public var uninitializedVars = Tokens() // 存储变量词法单元
override public func visit(varDecl: VarDecl) {
try {
varDecl.expr
} catch (e: ASTException) {
uninitializedVars.append(varDecl.identifier)
}
breakTraverse() // 不会继续遍历 varDecl 的子节点
return
}
}
main(): Int64 {
let input = quote(
var a : Int64
)
let varDecl = parseDecl(input)
let visitor = MyVisitor() // MyVisitor中定义了对 varDecl 节点的处理
varDecl.traverse(visitor) // 实现对 varDecl 节点的处理
println("Uninitialized VarDecl size is ${visitor.uninitializedVars.size}")
0
}
运行结果:
Uninitialized VarDecl size is 1
std.binary
功能介绍
当前 binary 包提供了如下功能:
- 仓颉数据类型和二进制字节序列间的互相转换接口,分为大端序和小端序两种转换类型。
- 仓颉数据类型自身大小端序转换的接口。
说明:
- 一般来说,多字节对象被存储为连续的字节序列。存储器或数字通信链路中,字节的排列顺序称为端序(Endianness)。端序又称字节顺序或者尾序。
- 字节有两种排列方式:将将一个多位数的低位存储在内存的低地址端,高位存储在内存的高地址端,称为小端序(Little-endian);反之称为大端序(Big-endian)。
API 列表
接口
| 接口名 | 功能 |
|---|---|
| BigEndianOrder<T> | 大端序字节序列转换接口。 |
| LittleEndianOrder<T> | 小端序字节序列转换接口。 |
| SwapEndianOrder<T> | 反转字节顺序接口。 |
接口
interface BigEndianOrder<T>
public interface BigEndianOrder<T> {
func writeBigEndian(buffer: Array<Byte>): Int64
static func readBigEndian(buffer: Array<Byte>): T
}
功能:大端序字节序列转换接口。
static func readBigEndian(Array<Byte>)
static func readBigEndian(buffer: Array<Byte>): T
功能:从字节数组中以大端序的方式读取一个 T 值。
参数:
返回值:
- T - T 值。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 T 值时,抛出异常。
func writeBigEndian(Array<Byte>)
func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 T 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 T 值时,抛出异常。
extend Bool <: BigEndianOrder<Bool>
extend Bool <: BigEndianOrder<Bool>
功能:为 Bool 扩展 BigEndianOrder 接口,以实现将 Bool 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): Bool
功能:从字节数组中以大端序的方式读取一个 Bool 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Bool 值时,抛出异常。
示例:
import std.binary.*
main() {
let buffer: Array<Byte> = [0x1]
let n = Bool.readBigEndian(buffer)
println(n)
}
运行结果:
true
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 Bool 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Bool 值时,抛出异常。
示例:
import std.binary.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = true.writeBigEndian(buffer)
println(n == 1)
println(buffer[0] == 0x01u8)
}
运行结果:
true
true
extend Float16 <: BigEndianOrder<Float16>
extend Float16 <: BigEndianOrder<Float16>
功能:为 Float16 扩展 BigEndianOrder 接口,以实现将 Float16 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): Float16
功能:从字节数组中以大端序的方式读取一个 Float16 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Float16 值时,抛出异常。
示例:
import std.binary.*
main() {
/* 12.5的IEEE 754表示为0x4A40 */
let buffer: Array<Byte> = [0x4A, 0x40]
let n = Float16.readBigEndian(buffer)
println(n == 12.5)
}
运行结果:
true
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 Float16 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Float16 值时,抛出异常。
示例:
import std.binary.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let len = 12.5f16.writeBigEndian(buffer)
println(len)
/* 0x4A的十进制表示为74,0x40的十进制表示为64 */
println(buffer[0..len])
}
运行结果:
2
[74, 64]
extend Float32 <: BigEndianOrder<Float32>
extend Float32 <: BigEndianOrder<Float32>
功能:为 Float32 扩展 BigEndianOrder 接口,以实现将 Float32 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): Float32
功能:从字节数组中以大端序的方式读取一个 Float32 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Float32 值时,抛出异常。
示例:
import std.binary.*
main() {
let buffer: Array<Byte> = [0x41, 0x48, 0x00, 0x00]
let n = Float32.readBigEndian(buffer)
println(n)
}
运行结果:
12.500000
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 Float32 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Float32 值时,抛出异常。
示例:
import std.binary.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let len = 12.5f32.writeBigEndian(buffer)
println(len)
/* 12.5的IEEE 754的单精度浮点表示为 0x4148 ,0x41的十进制表示为65,0x48的十进制表示为72 */
println(buffer[0..len])
}
运行结果:
4
[65, 72, 0, 0]
extend Float64 <: BigEndianOrder<Float64>
extend Float64 <: BigEndianOrder<Float64>
功能:为 Float64 扩展 BigEndianOrder 接口,以实现将 Float64 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): Float64
功能:从字节数组中以大端序的方式读取一个 Float64 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Float64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
let n = Float64.readBigEndian(buffer)
@Assert(n, 12.5)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 Float64 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Float64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 12.5f64.writeBigEndian(buffer)
@Assert(n, 8)
@Assert(buffer[..n] == [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
}
extend Int16 <: BigEndianOrder<Int16>
extend Int16 <: BigEndianOrder<Int16>
功能:为 Int16 扩展 BigEndianOrder 接口,以实现将 Int16 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): Int16
功能:从字节数组中以大端序的方式读取一个 Int16 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Int16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12, 0x34]
let n = Int16.readBigEndian(buffer)
@Assert(n, 0x1234)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 Int16 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Int16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x1234i16.writeBigEndian(buffer)
@Assert(n, 2)
@Assert(buffer[..n] == [0x12, 0x34])
}
extend Int32 <: BigEndianOrder<Int32>
extend Int32 <: BigEndianOrder<Int32>
功能:为 Int32 扩展 BigEndianOrder 接口,以实现将 Int32 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): Int32
功能:从字节数组中以大端序的方式读取一个 Int32 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Int32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12, 0x34, 0x56, 0x78]
let n = Int32.readBigEndian(buffer)
@Assert(n, 0x12345678)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 Int32 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Int32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
var buffer: Array<Byte> = Array<Byte>(8, repeat: 0)
let n = 0x12345678i32.
writeBigEndian(buffer)
@Assert(n, 4)
@Assert(buffer[..n] == [0x12u8, 0x34u8, 0x56u8, 0x78u8])
}
extend Int64 <: BigEndianOrder<Int64>
extend Int64 <: BigEndianOrder<Int64>
功能:为 Int64 扩展 BigEndianOrder 接口,以实现将 Int64 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): Int64
功能:从字节数组中以大端序的方式读取一个 Int64 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Int64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]
let n = Int64.readBigEndian(buffer)
@Assert(n, 0x1234567890123456)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 Int64 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Int64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x1234567890123456i64.writeBigEndian(buffer)
@Assert(n, 8)
@Assert(buffer[..n] == [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56])
}
extend Int8 <: BigEndianOrder<Int8>
extend Int8 <: BigEndianOrder<Int8>
功能:为 Int8 扩展 BigEndianOrder 接口,以实现将 Int8 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): Int8
功能:从字节数组中以大端序的方式读取一个 Int8 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Int8 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12]
let n = Int8.readBigEndian(buffer)
@Assert(n, 0x12)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 Int8 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Int8 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x12i8.writeBigEndian(buffer)
@Assert(n, 1)
@Assert(buffer[..n] == [0x12])
}
extend UInt16 <: BigEndianOrder<UInt16>
extend UInt16 <: BigEndianOrder<UInt16>
功能:为 UInt16 扩展 BigEndianOrder 接口,以实现将 UInt16 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): UInt16
功能:从字节数组中以大端序的方式读取一个 UInt16 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 UInt16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12, 0x34]
let n = UInt16.readBigEndian(buffer)
@Assert(n, 0x1234)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 UInt16 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 UInt16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x1234u16.writeBigEndian(buffer)
@Assert(n, 2)
@Assert(buffer[..n] == [0x12, 0x34])
}
extend UInt32 <: BigEndianOrder<UInt32>
extend UInt32 <: BigEndianOrder<UInt32>
功能:为 UInt32 扩展 BigEndianOrder 接口,以实现将 UInt32 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): UInt32
功能:从字节数组中以大端序的方式读取一个 UInt32 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 UInt32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12, 0x34, 0x56, 0x78]
let n = UInt32.readBigEndian(buffer)
@Assert(n, 0x12345678)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 UInt32 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 UInt32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x12345678u32.writeBigEndian(buffer)
@Assert(n, 4)
@Assert(buffer[..n] == [0x12, 0x34, 0x56, 0x78])
}
extend UInt64 <: BigEndianOrder<UInt64>
extend UInt64 <: BigEndianOrder<UInt64>
功能:为 UInt64 扩展 BigEndianOrder 接口,以实现将 UInt64 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): UInt64
功能:从字节数组中以大端序的方式读取一个 UInt64 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 UInt64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]
let n = UInt64.readBigEndian(buffer)
@Assert(n, 0x1234567890123456)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 UInt64 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 UInt64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x1234567890123456u64.writeBigEndian(buffer)
@Assert(n, 8)
@Assert(buffer[..n] == [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56])
}
extend UInt8 <: BigEndianOrder<UInt8>
extend UInt8 <: BigEndianOrder<UInt8>
功能:为 UInt8 扩展 BigEndianOrder 接口,以实现将 UInt8 值和大端序字节序列的转换。
父类型:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): UInt8
功能:从字节数组中以大端序的方式读取一个 UInt8 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 UInt8 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12]
let n = UInt8.readBigEndian(buffer)
@Assert(n, 0x12)
}
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:将 UInt8 值以大端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 UInt8 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x12u8.writeBigEndian(buffer)
@Assert(n, 1)
@Assert(buffer[..n] == [0x12])
}
interface LittleEndianOrder<T>
public interface LittleEndianOrder<T> {
func writeLittleEndian(buffer: Array<Byte>): Int64
static func readLittleEndian(buffer: Array<Byte>): T
}
功能:小端序字节序列转换接口。
static func readLittleEndian(Array<Byte>)
static func readLittleEndian(buffer: Array<Byte>): T
功能:从字节数组中以小端序的方式读取一个 T 值。
参数:
返回值:
- T - T 值。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 T 值时,抛出异常。
func writeLittleEndian(Array<Byte>)
func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 T 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 T 值时,抛出异常。
extend Bool <: LittleEndianOrder<Bool>
extend Bool <: LittleEndianOrder<Bool>
功能:为 Bool 扩展 LittleEndianOrder 接口,以实现将 Bool 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): Bool
功能:从字节数组中以小端序的方式读取一个 Bool 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Bool 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x1]
let n = Bool.readLittleEndian(buffer)
@Assert(n, true)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 Bool 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Bool 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = true.writeLittleEndian(buffer)
@Assert(n, 1)
@Assert(buffer[..n] == [0x01])
}
extend Float16 <: LittleEndianOrder<Float16>
extend Float16 <: LittleEndianOrder<Float16>
功能:为 Float16 扩展 LittleEndianOrder 接口,以实现将 Float16 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): Float16
功能:从字节数组中以小端序的方式读取一个 Float16 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Float16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x40, 0x4A]
let n = Float16.readLittleEndian(buffer)
@Assert(n, 12.5)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 Float16 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Float16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 12.5f16.writeLittleEndian(buffer)
@Assert(n, 2)
@Assert(buffer[..n] == [0x40, 0x4A])
}
extend Float32 <: LittleEndianOrder<Float32>
extend Float32 <: LittleEndianOrder<Float32>
功能:为 Float32 扩展 LittleEndianOrder 接口,以实现将 Float32 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): Float32
功能:从字节数组中以小端序的方式读取一个 Float32 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Float32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x00, 0x00, 0x48, 0x41]
let n = Float32.readLittleEndian(buffer)
@Assert(n, 12.5)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 Float32 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Float32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 12.5f32.writeLittleEndian(buffer)
@Assert(n, 4)
@Assert(buffer[..n] == [0x00, 0x00, 0x48, 0x41])
}
extend Float64 <: LittleEndianOrder<Float64>
extend Float64 <: LittleEndianOrder<Float64>
功能:为 Float64 扩展 LittleEndianOrder 接口,以实现将 Float64 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): Float64
功能:从字节数组中以小端序的方式读取一个 Float64 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Float64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
let n = Float64.readLittleEndian(buffer)
@Assert(n, 12.5)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 Float64 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Float64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 12.5f64.writeLittleEndian(buffer)
@Assert(n, 8)
@Assert(buffer[..n] == [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40])
}
extend Int16 <: LittleEndianOrder<Int16>
extend Int16 <: LittleEndianOrder<Int16>
功能:为 Int16 扩展 LittleEndianOrder 接口,以实现将 Int16 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): Int16
功能:从字节数组中以小端序的方式读取一个 Int16 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Int16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x34, 0x12]
let n = Int16.readLittleEndian(buffer)
@Assert(n, 0x1234i16)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 Int16 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Int16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x1234i16.writeLittleEndian(buffer)
@Assert(n, 2)
@Assert(buffer[..n] == [0x34, 0x12])
}
extend Int32 <: LittleEndianOrder<Int32>
extend Int32 <: LittleEndianOrder<Int32>
功能:为 Int32 扩展 LittleEndianOrder 接口,以实现将 Int32 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): Int32
功能:从字节数组中以小端序的方式读取一个 Int32 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Int32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x78, 0x56, 0x34, 0x12]
let n = Int32.readLittleEndian(buffer)
@Assert(n, 0x12345678)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 Int32 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Int32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x12345678i32.writeLittleEndian(buffer)
@Assert(n, 4)
@Assert(buffer[..n] == [0x78, 0x56, 0x34, 0x12])
}
extend Int64 <: LittleEndianOrder<Int64>
extend Int64 <: LittleEndianOrder<Int64>
功能:为 Int64 扩展 LittleEndianOrder 接口,以实现将 Int64 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): Int64
功能:从字节数组中以小端序的方式读取一个 Int64 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Int64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]
let n = Int64.readLittleEndian(buffer)
@Assert(n, 0x1234567890123456)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 Int64 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Int64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x1234567890123456i64.writeLittleEndian(buffer)
@Assert(n, 8)
@Assert(buffer[..n] == [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12])
}
extend Int8 <: LittleEndianOrder<Int8>
extend Int8 <: LittleEndianOrder<Int8>
功能:为 Int8 扩展 LittleEndianOrder 接口,以实现将 Int8 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): Int8
功能:从字节数组中以小端序的方式读取一个 Int8 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 Int8 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12]
let n = Int8.readLittleEndian(buffer)
@Assert(n, 0x12)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 Int8 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 Int8 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x12i8.writeLittleEndian(buffer)
@Assert(n, 1)
@Assert(buffer[..n] == [0x12])
}
extend UInt16 <: LittleEndianOrder<UInt16>
extend UInt16 <: LittleEndianOrder<UInt16>
功能:为 UInt16 扩展 LittleEndianOrder 接口,以实现将 UInt16 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): UInt16
功能:从字节数组中以小端序的方式读取一个 UInt16 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 UInt16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x34, 0x12]
let n = UInt16.readLittleEndian(buffer)
@Assert(n, 0x1234u16)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 UInt16 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 UInt16 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x1234u16.writeLittleEndian(buffer)
@Assert(n, 2)
@Assert(buffer[..n] == [0x34, 0x12])
}
extend UInt32 <: LittleEndianOrder<UInt32>
extend UInt32 <: LittleEndianOrder<UInt32>
功能:为 UInt32 扩展 LittleEndianOrder 接口,以实现将 UInt32 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): UInt32
功能:从字节数组中以小端序的方式读取一个 UInt32 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 UInt32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x78, 0x56, 0x34, 0x12]
let n = UInt32.readLittleEndian(buffer)
@Assert(n, 0x12345678)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 UInt32 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 UInt32 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x12345678u32.writeLittleEndian(buffer)
@Assert(n, 4)
@Assert(buffer[..n] == [0x78, 0x56, 0x34, 0x12])
}
extend UInt64 <: LittleEndianOrder<UInt64>
extend UInt64 <: LittleEndianOrder<UInt64>
功能:为 UInt64 扩展 LittleEndianOrder 接口,以实现将 UInt64 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): UInt64
功能:从字节数组中以小端序的方式读取一个 UInt64 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 UInt64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]
let n = UInt64.readLittleEndian(buffer)
@Assert(n, 0x1234567890123456)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 UInt64 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 UInt64 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x1234567890123456u64.writeLittleEndian(buffer)
@Assert(n, 8)
@Assert(buffer[..n] == [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12])
}
extend UInt8 <: LittleEndianOrder<UInt8>
extend UInt8 <: LittleEndianOrder<UInt8>
功能:为 UInt8 扩展 LittleEndianOrder 接口,以实现将 UInt8 值和小端序字节序列的转换。
父类型:
static func readLittleEndian(Array<Byte>)
public static func readLittleEndian(buffer: Array<Byte>): UInt8
功能:从字节数组中以小端序的方式读取一个 UInt8 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 UInt8 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer: Array<Byte> = [0x12]
let n = UInt8.readLittleEndian(buffer)
@Assert(n, 0x12)
}
func writeLittleEndian(Array<Byte>)
public func writeLittleEndian(buffer: Array<Byte>): Int64
功能:将 UInt8 值以小端序的方式写入字节数组中。
参数:
返回值:
- Int64 - 写入的数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 太小,不足以存储 UInt8 值时,抛出异常。
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let buffer = Array<Byte>(8, repeat: 0)
let n = 0x12u8.writeLittleEndian(buffer)
@Assert(n, 1)
@Assert(buffer[..n] == [0x12])
}
interface SwapEndianOrder<T>
public interface SwapEndianOrder<T> {
func swapBytes(): T
}
功能:反转字节顺序接口。
func swapBytes()
func swapBytes(): T
功能:反转 T 值的字节顺序。
返回值:
- T - T 值。
extend Int16 <: SwapEndianOrder<Int16>
extend Int16 <: SwapEndianOrder<Int16>
功能:为 Int16 扩展 SwapEndianOrder 接口,以实现将 Int16 值的字节顺序反转。
父类型:
func swapBytes()
public func swapBytes(): Int16
功能:反转 Int16 值的字节顺序。
返回值:
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let n = 0x1234i16
let m = n.swapBytes()
@Assert(m, 0x3412)
}
extend Int32 <: SwapEndianOrder<Int32>
extend Int32 <: SwapEndianOrder<Int32>
功能:为 Int32 扩展 SwapEndianOrder 接口,以实现将 Int32 值的字节顺序反转。
父类型:
func swapBytes()
public func swapBytes(): Int32
功能:反转 Int32 值的字节顺序。
返回值:
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let n = 0x12345678i32
let m = n.swapBytes()
@Assert(m, 0x78563412)
}
extend Int64 <: SwapEndianOrder<Int64>
extend Int64 <: SwapEndianOrder<Int64>
功能:为 Int64 扩展 SwapEndianOrder 接口,以实现将 Int64 值的字节顺序反转。
父类型:
func swapBytes()
public func swapBytes(): Int64
功能:反转 Int64 值的字节顺序。
返回值:
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let n = 0x1234567890123456i64
let m = n.swapBytes()
@Assert(m, 0x5634129078563412)
}
extend Int8 <: SwapEndianOrder<Int8>
extend Int8 <: SwapEndianOrder<Int8>
功能:为 Int8 扩展 SwapEndianOrder 接口,以实现将 Int8 值的字节顺序反转。
父类型:
func swapBytes()
public func swapBytes(): Int8
功能:反转 Int8 值的字节顺序。
返回值:
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let n = 0x12i8
let m = n.swapBytes()
@Assert(m, 0x12)
}
extend UInt16 <: SwapEndianOrder<UInt16>
extend UInt16 <: SwapEndianOrder<UInt16>
功能:为 UInt16 扩展 SwapEndianOrder 接口,以实现将 UInt16 值的字节顺序反转。
父类型:
func swapBytes()
public func swapBytes(): UInt16
功能:反转 UInt16 值的字节顺序。
返回值:
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let n = 0x1234u16
let m = n.swapBytes()
@Assert(m, 0x3412)
}
extend UInt32 <: SwapEndianOrder<UInt32>
extend UInt32 <: SwapEndianOrder<UInt32>
功能:为 UInt32 扩展 SwapEndianOrder 接口,以实现将 UInt32 值的字节顺序反转。
父类型:
func swapBytes()
public func swapBytes(): UInt32
功能:反转 UInt32 值的字节顺序。
返回值:
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let n = 0x12345678u32
let m = n.swapBytes()
@Assert(m, 0x78563412)
}
extend UInt64 <: SwapEndianOrder<UInt64>
extend UInt64 <: SwapEndianOrder<UInt64>
功能:为 UInt64 扩展 SwapEndianOrder 接口,以实现将 UInt64 值的字节顺序反转。
父类型:
func swapBytes()
public func swapBytes(): UInt64
功能:反转 UInt64 值的字节顺序。
返回值:
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let n = 0x1234567890123456u64
let m = n.swapBytes()
@Assert(m, 0x5634129078563412)
}
extend UInt8 <: SwapEndianOrder<UInt8>
extend UInt8 <: SwapEndianOrder<UInt8>
功能:为 UInt8 扩展 SwapEndianOrder 接口,以实现将 UInt8 值的字节顺序反转。
父类型:
func swapBytes()
public func swapBytes(): UInt8
功能:反转 UInt8 值的字节顺序。
返回值:
示例:
import std.binary.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let n = 0x12u8
let m = n.swapBytes()
@Assert(m, 0x12)
}
std.collection
功能介绍
collection 包提供了常见数据结构的高效实现、相关抽象的接口的定义以及在集合类型中常用的函数功能。
本包实现了以下常用的数据结构:
-
ArrayDeque:基于数组实现的双端循环队列,支持在集合的两端进行元素的插入和删除操作。可以使用 addFirst() 和 addLast() 方法在头部和尾部插入元素,使用 removeFirst() 和 removeLast() 方法从集合的头部和尾部删除元素。
-
ArrayList:变长的连续数组,在需要存储不确定数量的数据,或者需要根据运行时的条件动态调整数组大小时使用 ArrayList。使用 ArrayList 可能会导致内存分配和释放的开销增加,因此需要谨慎使用。
-
ArrayQueue:基于数组实现的循环队列,只允许在尾部插入元素,在头部删除元素。
-
ArrayStack:基于数组实现的栈数据结构。特点是先进后出,只能在顶部进行数据的插入和删除。
-
LinkedList:链表结构, LinkedList 的优点是它可以动态地添加或删除元素,而不需要移动其他元素。这使得它在需要频繁添加或删除元素的情况下非常有用。它还可以轻松地进行修改或删除操作,并且可以在列表中存储多个元素。 LinkedList 的缺点是它需要额外的内存来存储每个元素的引用,这可能会导致内存浪费。
-
HashMap:哈希表,它存储键值对,并且可以根据键快速访问值。在需要使用映射关系并且需要快速查找时使用。
-
HashSet:基于哈希表实现的集合数据结构,它可以用于快速检索和删除元素,具有高效的插入、删除和查找操作。
-
TreeMap:基于红黑树实现的有序映射表。通常情况下,当需要将元素按照自然顺序或者自定义顺序进行排序时,可以使用TreeMap。
-
TreeSet:基于 TreeMap 实现的有序集合。能自动排序元素,可用于存储不重复且需排序的数据。
collection 包提供的集合类型都不支持并发安全,并发安全的集合请参见 collection.concurrent 包。
API 列表
函数
接口
| 接口名 | 功能 |
|---|---|
| Deque<T> | 双端队列是一种具有队列和栈特性的数据结构,它允许在两端进行插入和删除操作。 |
| EquatableCollection<T> | 定义了可以进行比较的集合类型。 |
| List<T> | 提供了对索引友好的列表操作。 |
| Map<K, V> | 提供了一种将键映射到值的方式。 |
| MapEntryView<K, V> | 键值对集合中的某个Key的视图 |
| OrderedMap<K, V> | 有序映射 |
| OrderedSet<T> | 有序集合 |
| Queue<T> | 队列数据结构,它遵循先进先出(First In First Out, FIFO)原则。 |
| ReadOnlyList<T> | 定义了对列表的只读操作。 |
| ReadOnlyMap<K, V> | 只读映射 |
| ReadOnlySet<K, V> | 只读集合 |
| Set<T> | 不包含重复元素的集合。 |
| Stack<T> | 栈数据结构接口,具有后进先出(Last In First Out,LIFO)的特点。 |
类
| 类名 | 功能 |
|---|---|
| ArrayDeque<T> | 根据可调整大小的循环数组实现的双端队列。 |
| ArrayList<T> | 提供可变长度的数组的功能。 |
| ArrayQueue<T> | 基于数组实现的循环队列数据结构。 |
| ArrayStack<T> | 基于数组实现的栈Stack 数据结构。 |
| HashMapIterator<K, V> where K <: Hashable & Equatable<K> | 此类主要实现 HashMap 的迭代器功能。 |
| HashMap<K, V> where K <: Hashable & Equatable<K> | Map<K, V> 接口的哈希表实现。 |
| HashSet<T> where T <: Hashable & Equatable<T> | 基于 HashMap<K, V> 实现的 Set<T> 接口的实例。 |
| LinkedListNode<T> | LinkedList<T> 上的节点。 |
| LinkedList<T> | 实现双向链表的数据结构。 |
| TreeMap<K, V> where K <: Comparable<K> | 基于平衡二叉搜索树实现的 Map<K, V> 接口实例。 |
| TreeSet<T> where T <: Comparable<T> | 基于 TreeMap<K, V> 实现的 Set<T> 接口的实例。 |
异常类
| 异常类名 | 功能 |
|---|---|
| ConcurrentModificationException | 并发修改异常类。 |
函数
func all<T>((T) -> Bool)
public func all<T>(predicate: (T) -> Bool): (Iterable<T>) -> Bool
功能:判断迭代器所有元素是否都满足条件。
参数:
- predicate: (T) -> Bool - 给定的条件。
返回值:
func any<T>((T) -> Bool)
public func any<T>(predicate: (T) -> Bool): (Iterable<T>) -> Bool
功能:判断迭代器是否存在任意一个满足条件的元素。
参数:
- predicate: (T) -> Bool - 给定的条件。
返回值:
func at<T>(Int64)
public func at<T>(n: Int64): (Iterable<T>) -> Option<T>
功能:获取迭代器指定位置的元素。
参数:
- n: Int64 - 给定的个数。
返回值:
func collectArrayList<T>(Iterable<T>)
public func collectArrayList<T>(it: Iterable<T>): ArrayList<T>
功能:将一个迭代器转换成 ArrayList 类型。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
func collectArray<T>(Iterable<T>)
public func collectArray<T>(it: Iterable<T>): Array<T>
功能:将一个迭代器转换成 Array 类型。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
- Array<T> - 返回一个数组。
func collectHashMap<K, V>(Iterable<(K, V)>) where K <: Hashable & Equatable<K>
public func collectHashMap<K, V>(it: Iterable<(K, V)>): HashMap<K, V> where K <: Hashable & Equatable<K>
功能:将一个迭代器转换成 HashMap 类型。
参数:
- it: Iterable<(K, V)> - 给定的迭代器。
返回值:
func collectHashSet<T>(Iterable<T>) where T <: Hashable & Equatable<T>
public func collectHashSet<T>(it: Iterable<T>): HashSet<T> where T <: Hashable & Equatable<T>
功能:将一个迭代器转换成 HashSet 类型。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
func collectString<T>(String) where T <: ToString
public func collectString<T>(delimiter!: String = ""): (Iterable<T>) -> String where T <: ToString
功能:将一个对应元素实现了 ToString 接口的迭代器转换成 String 类型。
参数:
- delimiter!: String - 字符串拼接分隔符。
返回值:
func concat<T>(Iterable<T>)
public func concat<T>(other: Iterable<T>): (Iterable<T>) -> Iterator<T>
功能:串联两个迭代器。
参数:
- other: Iterable<T> - 要串联在后面的迭代器。
返回值:
func contains<T>(T) where T <: Equatable<T>
public func contains<T>(element: T): (Iterable<T>) -> Bool where T <: Equatable<T>
功能:遍历所有元素,判断是否包含指定元素并返回该元素。
参数:
- element: T - 要查找的元素。
返回值:
func count<T>(Iterable<T>)
public func count<T>(it: Iterable<T>): Int64
功能:统计迭代器包含元素数量。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
- Int64 - 返回迭代器包含元素数量。
func enumerate<T>(Iterable<T>)
public func enumerate<T>(it: Iterable<T>): Iterator<(Int64, T)>
功能:用于获取带索引的迭代器。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
func filter<T>((T) -> Bool)
public func filter<T>(predicate: (T) -> Bool): (Iterable<T>) -> Iterator<T>
功能:筛选出满足条件的元素。
参数:
- predicate: (T) -> Bool - 给定的条件。
返回值:
func filterMap<T, R>((T) -> ?R)
public func filterMap<T, R>(transform: (T)-> ?R): (Iterable<T>) ->Iterator<R>
功能:同时进行筛选操作和映射操作,返回一个新的迭代器。
参数:
- transform: (T) -> ?R - 给定的映射函数。函数返回值为 Some 对应 filter 的 predicate 为 true,反之表示 false。
返回值:
func first<T>(Iterable<T>)
public func first<T>(it: Iterable<T>): Option<T>
功能:获取头部元素。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
- Option<T> - 返回头部元素,若为空则返回 None。
func flatMap<T, R>( (T) -> Iterable<R>)
public func flatMap<T, R>(transform: (T) -> Iterable<R>): (Iterable<T>) -> Iterator<R>
功能:创建一个带 flatten 功能的映射。
参数:
- transform: (T) -> Iterable<R> - 给定的映射函数。
返回值:
func flatten<T, R>(Iterable<T>) where T <: Iterable<R>
public func flatten<T, R>(it: Iterable<T>): Iterator<R> where T <: Iterable<R>
功能:将嵌套的迭代器展开一层。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
- Iterator<R> - 返回展开一层后的迭代器。
func fold<T, R>(R, (R, T) -> R)
public func fold<T, R>(initial: R, operation: (R, T) -> R): (Iterable<T>) -> R
功能:使用指定初始值,从左向右计算。
参数:
- initial: R - 给定的 R 类型的初始值。
- operation: (R, T) -> R - 给定的计算函数。
返回值:
- (Iterable<T>) -> R - 返回一个折叠函数。
func forEach<T>((T) -> Unit)
public func forEach<T>(action: (T) -> Unit): (Iterable<T>) -> Unit
功能:遍历所有元素,指定给定的操作。
参数:
- action: (T) -> Unit - 给定的操作函数。
返回值:
func inspect<T>((T) -> Unit)
public func inspect<T>(action: (T)->Unit): (Iterable<T>) ->Iterator<T>
功能:迭代器每次调用 next() 对当前元素执行额外操作(不会消耗迭代器中元素)。
参数:
- action: (T) -> Unit - 给定的操作函数。
返回值:
func isEmpty<T>(Iterable<T>)
public func isEmpty<T>(it: Iterable<T>): Bool
功能:判断迭代器是否为空。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
- Bool - 返回迭代器是否为空。
func last<T>(Iterable<T>)
public func last<T>(it: Iterable<T>): Option<T>
功能:获取尾部元素。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
- Option<T> - 返回尾部元素,若为空则返回 None。
func map<T, R>((T) -> R)
public func map<T, R>(transform: (T) -> R): (Iterable<T>) -> Iterator<R>
功能:创建一个映射。
参数:
- transform: (T) ->R - 给定的映射函数。
返回值:
func max<T>(Iterable<T>) where T <: Comparable<T>
public func max<T>(it: Iterable<T>): Option<T> where T <: Comparable<T>
功能:筛选最大的元素。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
- Option<T> - 返回最大的元素,若为空则返回 None。
func min<T>(Iterable<T>) where T <: Comparable<T>
public func min<T>(it: Iterable<T>): Option<T> where T <: Comparable<T>
功能:筛选最小的元素。
参数:
- it: Iterable<T> - 给定的迭代器。
返回值:
- Option<T> - 返回最小的元素,若为空则返回 None。
func none<T>((T) -> Bool)
public func none<T>(predicate: (T) -> Bool): (Iterable<T>) -> Bool
功能:判断迭代器中所有元素是否都不满足条件。
参数:
- predicate: (T) -> Bool - 给定的条件。
返回值:
func reduce<T>((T, T) -> T)
public func reduce<T>(operation: (T, T) -> T): (Iterable<T>) -> Option<T>
功能:使用第一个元素作为初始值,从左向右计算。
参数:
- operation: (T, T) -> T - 给定的操作函数。
返回值:
func skip<T>(Int64)
public func skip<T>(count: Int64): (Iterable<T>) -> Iterator<T>
功能:从迭代器跳过特定个数。
当 count 小于 0 时,抛出异常。当 count 等于 0 时,相当没有跳过任何元素,返回原迭代器。当 count 大于0并且count小于迭代器的大小时,跳过 count 个元素后,返回含有剩下的元素的新迭代器。当 count 大于等于迭代器的大小时,跳过所有元素,返回空迭代器。
参数:
- count: Int64 - 要跳过的个数。
返回值:
异常:
- IllegalArgumentException - 当 count < 0 时,抛出异常。
func step<T>(Int64)
public func step<T>(count: Int64): (Iterable<T>) -> Iterator<T>
功能:迭代器每次调用 next() 跳过特定个数。
当 count 小于等于 0 时,抛出异常。当 count 大于 0 时,每次调用 next() 跳过 count 次,直到迭代器为空。
参数:
- count: Int64 - 每次调用 next() 要跳过的个数。
返回值:
异常:
- IllegalArgumentException - 当 count <= 0 时,抛出异常。
func take<T>(Int64)
public func take<T>(count: Int64): (Iterable<T>) -> Iterator<T>
功能:从迭代器取出特定个数。
当 count 小于 0 时,抛出异常。当 count 等于 0 时,不取元素,返回空迭代器。当 count 大于 0 小于迭代器的大小时,取前 count 个元素,返回新迭代器。当 count 大于等于迭代器的大小时,取所有元素,返回原迭代器。
参数:
- count: Int64 - 要取出的个数。
返回值:
异常:
- IllegalArgumentException - 当 count < 0 时,抛出异常。
func zip<T, R>(Iterable<R>)
public func zip<T, R>(other: Iterable<R>): (Iterable<T>) -> Iterator<(T, R)>
功能:将两个迭代器合并成一个(长度取决于短的那个迭代器)。
参数:
- other: Iterable<R> - 要合并的其中一个迭代器。
返回值:
接口
interface Deque<T>
public interface Deque<T> <: Collection<T> {
prop first: ?T
prop last: ?T
func addFirst(element: T): Unit
func addLast(element: T): Unit
func removeFirst(): ?T
func removeLast(): ?T
}
功能:Deque(double-ended queue)是一种具有队列和栈特性的数据结构,允许从两端插入和删除元素。Deque 接口的主要功能包括:
- 插入操作:可以在双端队列的前端或后端插入元素。使用 addFirst 方法在双端队列头部插入元素,使用 addLast 在双端队列尾部插入元素。
- 访问操作:可以访问双端队列的前端或后端的元素,而不进行删除操作。使用 first 访问头部元素,使用 last 访问尾部元素。
- 删除操作:可以在双端队列的前端或后端删除元素。使用 removeFirst 删除头部元素并返回其值,使用 removeLast 删除尾部元素并返回其值。
- 其他集合类型支持的操作,比如元素数量、判空、迭代器操作。
父类型:
- Collection<T>
prop first
prop first: ?T
功能:访问双端队列头部元素,该操作不会删除头部元素。
返回值:
- Option<T> - Option 封装的头部元素的值,如果双端队列为空,返回None。
prop last
prop last: ?T
功能:访问双端队列尾部元素,该操作不会删除尾部元素。
返回值:
- Option<T> - Option 封装的尾部元素的值,如果双端队列为空,返回None。
func addFirst(T)
func addFirst(element: T): Unit
功能:在双端队列头部插入指定的元素。
参数:
- element: T - 被添加到双端队列中的元素。
func addLast(T)
func addLast(element: T): Unit
功能:在双端队列尾部插入指定的元素。
参数:
- element: T - 被添加到双端队列中的元素。
func removeFirst()
func removeFirst(): ?T
功能:删除双端队列中的头部元素并返回这个元素的值。
返回值:
- ?T - Option 封装的被删除的元素的值,如果双端队列为空,返回None。
func removeLast()
func removeLast(): ?T
功能:删除双端队列中的尾部元素并返回这个元素的值。
返回值:
- ?T - Option 封装的被删除的元素的值,如果双端队列为空,返回None。
interface EquatableCollection<T>
public interface EquatableCollection<T> <: Collection<T> {
func contains(element: T): Bool
func contains(all!: Collection<T>): Bool
}
功能:定义了可以进行比较的集合类型。
父类型:
- Collection<T>
func contains(T)
func contains(element: T): Bool
功能:判断 Keys 是否包含指定元素。
参数:
- element: T - 指定元素,待判断 Keys 是否包含该元素。
返回值:
- Bool - 包含返回 true,否则返回 false。
func contains(Collection<T>)
func contains(all!: Collection<T>): Bool
功能:判断 Keys 是否包含指定集合的所有元素。
参数:
- all!: Collection<T> - 待判断的集合 all。
返回值:
- Bool - 包含则返回 true,否则返回 false。
interface List<T>
public interface List<T> <: ReadOnlyList<T> {
func add(element: T): Unit
func add(all!: Collection<T>): Unit
func add(element: T, at!: Int64): Unit
func add(all!: Collection<T>, at!: Int64): Unit
func remove(at!: Int64): T
func remove(range: Range<Int64>): Unit
func removeIf(predicate: (T) -> Bool): Unit
func clear(): Unit
operator func [](index: Int64, value!: T): Unit
}
功能:定义了只提供对索引友好操作的列表类型。
父类型:
- ReadOnlyList<T>
func add(T)
func add(element: T): Unit
功能:将指定的元素附加到此列表的末尾。
参数:
- element: T - 插入的元素,类型为 T。
func add(Collection<T>)
func add(all!: Collection<T>): Unit
功能:将指定集合中的所有元素附加到此列表的末尾。
参数:
- all!: Collection<T> - 需要插入的元素的集合。
func add(T, Int64)
func add(element: T, at!: Int64): Unit
功能:在此列表中的指定位置插入指定元素。
参数:
- element: T - 要插入的 T 类型元素。
- at!: Int64 - 插入元素的目标索引。
func add(Collection<T>, Int64)
func add(all!: Collection<T>, at!: Int64): Unit
功能:从指定位置开始,将指定集合中的所有元素插入此列表。
参数:
- all!: Collection<T> - 要插入的 T 类型元素集合。
- at!: Int64 - 插入集合的目标索引。
func clear()
func clear(): Unit
功能:从此列表中删除所有元素。
func remove(Int64)
func remove(at!: Int64): T
功能:删除此列表中指定位置的元素。
参数:
- at!: Int64 - 被删除元素的索引。
返回值:
- T - 被移除的元素。
func remove(Range<Int64>)
func remove(range: Range<Int64>): Unit
功能:删除此列表中 Range 范围所包含的所有元素。
参数:
func removeIf((T) -> Bool)
func removeIf(predicate: (T) -> Bool): Unit
功能:删除此列表中满足给定 lambda 表达式或函数的所有元素。
参数:
- predicate: (T) ->Bool - 传递判断删除的条件。
operator func [](Int64, T)
operator func [](index: Int64, value!: T): Unit
功能:操作符重载 - set,通过下标运算符用指定的元素替换此列表中指定位置的元素。
参数:
- index: Int64 - 要设置的索引值。
- value!: T - 要设置的 T 类型的值。
interface Map<K, V>
public interface Map<K, V> <: ReadOnlyMap<K, V> {
func add(key: K, value: V): ?V
func add(all!: Collection<(K, V)>): Unit
func addIfAbsent(key: K, value: V): ?V
func clear(): Unit
func entryView(k: K): MapEntryView<K, V>
func remove(key: K): Option<V>
func remove(all!: Collection<K>): Unit
func removeIf(predicate: (K, V) -> Bool): Unit
func replace(key: K, value: V): ?V
operator func [](key: K, value!: V): Unit
}
功能:Map 接口提供了一种将键映射到值的方式。它允许我们使用键来查找值,因此可以用于存储和操作键值对。
Map 不能包含重复的key,每个key最多只能映射到一个value。
父类型:
- ReadOnlyMap<K, V>
func add(K, V)
func add(key: K, value: V): ?V
功能:将传入的键值对放入该 Map 中。对于 Map 中已有的键,该键映射的值将被新值替换。
参数:
- key: K - 要放置的键。
- value: V - 要分配的值。
返回值:
- ?V - 如果赋值之前 key 存在,返回旧值,否则返回 None。
func add(Collection<(K, V)>)
func add(all!: Collection<(K, V)>): Unit
功能:将新的键值对放入 Map 中。对于 Map 中已有的键,该键映射的值将被新值替换。
参数:
- all!: Collection<(K, V)> - 需要放入到 Map 中的键值对集合。
func addIfAbsent(K, V)
func addIfAbsent(key: K, value: V): ?V
功能:如果 key 不在当前 Map 中,添加指定键值对 key-value。否则不做修改。
参数:
- key: K - 待添加键值对的键。
- value: V - 待添加键值对的值。
返回值:
- ?V - 如果调用该函数时当前 Map 中已有指定的 key,返回该 key 对应的旧值,否则返回 None。
func clear()
func clear(): Unit
功能:清除所有键值对。
func entryView(K)
func entryView(k: K): MapEntryView<K, V>
功能:获取键 k 对应的视图。
参数:
- k: K - 待获取其视图的键。
返回值:
- MapEntryView<K, V> - 键 k 对应的视图。
func remove(K)
func remove(key: K): Option<V>
功能:从此 Map 中删除指定键的映射(如果存在)。
参数:
- key: K - 传入要删除的 key。
返回值:
func remove(Collection<K>)
func remove(all!: Collection<K>): Unit
功能:从此映射中删除指定集合的映射(如果存在)。
参数:
- all!: Collection<K> - 传入要删除的集合。
func removeIf((K, V) -> Bool)
func removeIf(predicate: (K, V) -> Bool): Unit
功能:传入 lambda 表达式,如果满足条件,则删除对应的键值对。
参数:
- predicate: (K, V) ->Bool - 传递一个 lambda 表达式进行判断。
func replace(K, V)
func replace(key: K, value: V): ?V
功能:如果当前 Map 中已有指定 key,将其值修改为 value。否则不做修改。
参数:
- key: K - 待修改键值对的键。
- value: V - 待修改键值对的新值。
返回值:
- ?V - 如果当前 Map 中已有指定 key,返回其旧值。否则返回 None。
operator func [](K, V)
operator func [](key: K, value!: V): Unit
功能:运算符重载集合,如果键存在,新 value 覆盖旧 value,如果键不存在,添加此键值对。
参数:
- key: K - 需要进行设置的键。
- value!: V - 传递要设置的值。
interface MapEntryView<K, V>
public interface MapEntryView<K, V> {
public prop key: K
public mut prop value: ?V
}
功能:提供映射中的某个 key 对应的视图。
prop key
public prop key: K
功能:返回视图中的 key,如果视图的 key 不在原始映射中,则返回一个该 key 的空视图。
类型:K
prop value
public mut prop value: ?V
功能:读取或修改视图对应原始映射的 value。
设置非空的 value 时,如果该视图的 value 不存在,则在该视图对应的原始映射中新增元素。
设置为 None 时,则会删除当前 Entry,删除完之后仍然能继续使用该视图。
类型:Option(V)
interface OrderedMap<K, V>
public interface OrderedMap<K, V> <: Map<K, V> {
public prop first: ?(K, V)
public prop last: ?(K, V)
public func removeFirst(): ?(K, V)
public func removeLast(): ?(K, V)
public func backward(mark: K, inclusive!: Bool): Iterator<(K, V)>
public func forward(mark: K, inclusive!: Bool): Iterator<(K, V)>
}
功能:OrderedMap 接口提供了一种将键映射到值的方式。它允许我们使用键来查找值,因此可以用于存储和操作键值对。
在 OrderedMap 接口的实例中,其内部的元素是有序的。
父类型:
- Map<K, V>
prop first
public prop first: ?(K, V)
功能:获取 OrderedMap 第一个元素。
类型:Option<(K, V)>
prop last
public prop last: ?(K, V)
功能:获取 OrderedMap 最后一个元素。
类型:Option<(K, V)>
func removeFirst()
public func removeFirst(): ?(K, V)
功能:删除 OrderedMap 的第一个元素。
返回值:
- ?(K, V) - 如果当前 OrderedMap 不为空,返回 Option 封装的被删除的键值对,否则返回
None。
func removeLast()
public func removeLast(): ?(K, V)
功能:删除 OrderedMap 的最后一个元素。
返回值:
- ?(K, V) - 如果当前 OrderedMap 不为空,返回 Option 封装的被删除的键值对,否则返回
None。
func backward(K, Bool)
public func backward(mark: K, inclusive!: Bool): Iterator<(K, V)>
功能:获取从第一个键小于等于 mark 的节点按降序遍历到 first 的迭代器。如果该节点的键等于 mark ,那么根据 inclusive! 确定是否包含该键对应的节点。
参数:
- mark: K - 用于确定从哪里开始的键。
- inclusive!: Bool - 当 mark 是迭代器的首个元素的 key 时,指定是否包含 mark 作为起始点。
返回值:
- Iterator<(K, V)> - 迭代器。
func forward(K, Bool)
public func forward(mark: K, inclusive!: Bool): Iterator<(K, V)>
功能:获取从第一个键大于等于 mark 的节点按升序遍历到 last 结束的一个迭代器。如果该节点的键等于 mark ,那么根据 inclusive! 确定是否包含该键对应的节点。
参数:
- mark: K - 用于确定从哪里开始的键。
- inclusive!: Bool - 当 mark 是迭代器的首个元素的 key 时,指定是否包含 mark 作为起始点。
返回值:
- Iterator<(K, V)> - 迭代器。
interface OrderedSet<T>
public interface OrderedSet<T> <: Set<T> {
public prop first: ?T
public prop last: ?T
public func removeFirst(): ?T
public func removeLast(): ?T
public func backward(mark: T, inclusive!: Bool): Iterator<T>
public func forward(mark: T, inclusive!: Bool): Iterator<T>
}
功能:OrderedSet 接口提供了一组集合的相关操作,允许我们以可读写的方式操作内部元素。
在 OrderedSet 接口的实例中,其内部的元素是有序的。
父类型:
- Set<T>
prop first
public prop first: ?T
功能:获取 OrderedSet 第一个元素。
类型:Option<T>
prop last
public prop last: ?T
功能:获取 OrderedSet 最后一个元素。
类型:Option<T>
func removeFirst()
public func removeFirst(): ?T
功能:删除 OrderedSet 的第一个元素。
返回值:
- ?T - 如果当前 OrderedSet 不为空,返回 Option 封装的被删除的元素,否则返回
None。
func removeLast()
public func removeLast(): ?T
功能:删除 OrderedSet 的最后一个元素。
返回值:
- ?T - 如果当前 OrderedSet 不为空,返回 Option 封装的被删除的元素,否则返回
None。
func backward(T, Bool)
public func backward(mark: T, inclusive!: Bool): Iterator<T>
功能:获取从第一个元素小于等于 mark 的节点按降序遍历到 first 的迭代器。如果该节点的元素等于 mark ,那么根据 inclusive! 确定是否包含该元素对应的节点。
参数:
- mark: T - 用于确定从哪里开始的元素。
- inclusive!: Bool - 当 mark 是迭代器的首个元素时,指定是否包含 mark 作为起始点。
返回值:
- Iterator<T> - 迭代器。
func forward(T, Bool)
public func forward(mark: T, inclusive!: Bool): Iterator<T>
功能:获取从第一个元素大于等于 mark 的节点按升序遍历到 last 结束的一个迭代器。如果该节点的元素等于 mark ,那么根据 inclusive! 确定是否包含该元素对应的节点。
参数:
- mark: T - 用于确定从哪里开始的元素。
- inclusive!: Bool - 当 mark 是迭代器的首个元素时,指定是否包含 mark 作为起始点。
返回值:
- Iterator<T> - 迭代器。
interface Queue<T>
public interface Queue<T> <: Collection<T> {
func add(element: T): Unit
func peek(): ?T
func remove(): ?T
}
功能:队列数据结构,它遵循先进先出(First In First Out, FIFO)原则。Queue 的主要功能包括:
- 添加元素:将指定的元素添加到队列的尾部。
- 访问操作:可以访问队列的前端元素,而不进行删除操作。
- 删除操作:可以删除队列的前端元素。
- 其他集合类型支持的操作,比如元素数量、判空、迭代器操作。
父类型:
- Collection<T>
func add(T)
func add(element: T): Unit
功能:在队列尾部插入指定的元素。
参数:
- element: T - 被添加到队列中的元素。
func peek()
func peek(): ?T
功能:访问双端队列头部元素,该操作不会删除头部元素。
返回值:
- ?T - Option 封装的头部元素的值,如果双端队列为空,返回
None。
func remove()
func remove(): ?T
功能:删除队列中的头部元素并返回这个元素的值。
返回值:
- ?T - Option 封装的被删除的元素的值,如果队列为空,返回
None。
interface ReadOnlyList<T>
public interface ReadOnlyList<T> <: Collection<T> {
prop first: ?T
prop last: ?T
func get(index: Int64): ?T
operator func [](index: Int64): T
}
功能:定义了只读列表。
父类型:
- Collection<T>
prop first
prop first: ?T
功能:返回此列表中的第一个元素,如果没有则返回 None。
类型:Option<T>
prop last
prop last: ?T
功能:返回此列表中的最后一个元素,如果没有则返回 None。
类型:Option<T>
func get(Int64)
func get(index: Int64): ?T
功能:返回此列表中指定位置的元素。
参数:
- index: Int64 - 要返回的元素的索引。
返回值:
- ?T - 返回指定位置的元素,如果 index 大小小于 0 或者大于等于此列表中的元素数量,返回 None。
operator func [](Int64)
operator func [](index: Int64): T
功能:操作符重载 - get。
参数:
- index: Int64 - 表示 get 接口的索引。
返回值:
- T - 索引位置的元素的值。
interface ReadOnlyMap<K, V>
public interface ReadOnlyMap<K, V> <: Collection<(K, V)> {
func get(key: K): ?V
func contains(key: K): Bool
func contains(all!: Collection<K>): Bool
func keys(): EquatableCollection<K>
func values(): Collection<V>
operator func [](key: K): V
}
功能:ReadOnlyMap 接口提供了一种将键映射到值的方式。它允许我们使用键来查找值,因此可以用于存储键值对。
ReadOnlyMap不能包含重复的 key,每个 key 最多只能映射到一个 value。
父类型:
- Collection<(K, V)>
func get(K)
func get(key: K): ?V
功能:根据 key 得到 ReadOnlyMap 中映射的值。
参数:
- key: K - 传递 key,获取 value。
返回值:
- ?V - ReadOnlyMap 中与 Key 对应的值。
func contains(K)
func contains(key: K): Bool
功能:判断是否包含指定键的映射。
参数:
- key: K - 传递要判断的 key。
返回值:
- Bool - 如果存在,则返回 true;否则,返回 false。
func contains(Collection<K>)
func contains(all!: Collection<K>): Bool
功能:判断是否包含指定集合键的映射。
参数:
- all!: Collection<K> - 传递待判断的 的集合。
返回值:
- Bool - 如果存在,则返回 true;否则,返回 false。
func keys()
func keys(): EquatableCollection<K>
功能:返回 ReadOnlyMap 中所有的 key,并将所有 key 存储在一个 EquatableCollection<K> 容器中。
返回值:
- EquatableCollection<K> - 保存所有返回的 key。
func values()
func values(): Collection<V>
功能:返回 ReadOnlyMap 中所有的 value,并将所有 value 存储在一个 Collection<V> 容器中。
返回值:
- Collection<V> - 保存所有返回的 value。
operator func [](K)
operator func [](key: K): V
功能:运算符重载集合,如果键存在,返回键对应的值,如果不存在,抛出异常。
参数:
- key: K - 需要进行查找的键。
返回值:
- V - 与键对应的值。
interface ReadOnlySet<T>
public interface ReadOnlySet<T> <: Collection<T> {
func contains(element: T): Bool
func contains(all!: Collection<T>): Bool
func subsetOf(other: ReadOnlySet<T>): Bool
}
功能:ReadOnlySet 接口提供了一组集合的相关操作,允许我们以只读方式操作内部元素。
父类型:
- Collection<T>
func contains(T)
func contains(element: T): Bool
功能:如果该集合包含指定元素,则返回 true。
参数:
- element: T - 需要判断的元素。
返回值:
- Bool - 如果包含,则返回 true;否则,返回 false。
func contains(Collection<T>)
func contains(all!: Collection<T>): Bool
功能:检查该集合是否包含其他集合。
参数:
- all!: Collection<T> - 其他集合。
返回值:
- Bool - 如果该集合包含指定集合,则返回 true;否则,返回 false。
func subsetOf(ReadOnlySet<T>)
func subsetOf(other: ReadOnlySet<T>): Bool
功能:检查该集合是否为其他集合的子集。
参数:
- other: ReadOnlySet<T> - 其他集合。
返回值:
- Bool - 果该集合是指定集合的子集,则返回 true;否则,返回 false。
interface Set<T>
public interface Set<T> <: ReadOnlySet<T> {
func add(element: T): Bool
func add(all!: Collection<T>): Unit
func remove(element: T): Bool
func remove(all!: Collection<T>): Unit
func removeIf(predicate: (T) -> Bool): Unit
func clear(): Unit
func retain(all!: Set<T>): Unit
}
功能:Set 接口提供了一组集合的相关操作,允许我们以可读写的方式操作内部元素。
Set 接口不规定内部的实现方式,在 Set 接口的实例中,其内部的元素通常是无序的,不能通过索引访问,也不能保证元素的插入顺序。
父类型:
- ReadOnlySet<T>
func add(T)
func add(element: T): Bool
功能:添加元素操作。如果元素已经存在,则不会添加它。
参数:
- element: T - 要添加的元素。
返回值:
- Bool - 如果添加成功,则返回 true;否则,返回 false。
func add(Collection<T>)
func add(all!: Collection<T>): Unit
功能:添加 Collection 中的所有元素至此 Set 中,如果元素存在,则不添加。
参数:
- all!: Collection<T> - 需要被添加的元素的集合。
func remove(T)
func remove(element: T): Bool
功能:从该集合中移除指定元素(如果存在)。
参数:
- element: T - 要删除的元素。
返回值:
- Bool - 集合中存在指定的元素并且删除成功返回
true,否则返回false。
func remove(Collection<T>)
func remove(all!: Collection<T>): Unit
功能:移除此 Set 中那些也包含在指定 Collection 中的所有元素。
参数:
- all!: Collection<T> - 传入 Collection<T>。
func removeIf((T) -> Bool)
func removeIf(predicate: (T) -> Bool): Unit
功能:传入 lambda 表达式,如果满足 true 条件,则删除对应的元素。
参数:
- predicate: (T) ->Bool - 传入一个 lambda 表达式进行判断。
func clear()
func clear(): Unit
功能:清除所有键值对。
func retain(Set<T>)
func retain(all!: Set<T>): Unit
参数:
- all!: Set<T> - 要保存的元素集合。
interface Stack<T>
public interface Stack<T> <: Collection<T> {
func add(element: T): Unit
func peek(): ?T
func remove(): ?T
}
功能:Stack(栈)是一种数据结构,具有后进先出(Last In First Out,LIFO)的特点。可以在一端(称为栈顶)进行插入和删除操作,而另一端(称为栈底)则不允许进行操作。
栈的基本操作包括入栈(add)、出栈(remove)、查看栈顶元素(peek)。
父类型:
- Collection<T>
func add(T)
func add(element: T): Unit
功能:向栈中添加元素。
参数:
- element: T - 将被放到栈顶的元素。
func peek()
func peek(): ?T
功能:查看栈顶元素,该操作不会删除栈顶元素。
返回值:
- ?T - 栈顶元素,如果栈为空,返回
None。
func remove()
func remove(): ?T
功能:删除并返回栈顶的元素。
返回值:
- ?T - 被删除的栈顶元素,如果栈为空,返回
None。
类
class ArrayDeque<T>
public class ArrayDeque<T> <: Deque<T> {
public init()
public init(capacity: Int64)
}
功能:ArrayDeque 是双端队列(deque)实现类,可以在双端队列的两端进行元素的插入和删除操作。ArrayDeque 是根据可调整大小的数组实现的,其容量会在插入元素的过程中不断地增长,默认每次扩容 50% 大小。ArrayDeque 的实现采用了循环队列的方式,在没有扩容的情况下,其插入、删除、查看等操作的时间复杂度为 O(1)。
父类型:
- Deque<T>
prop capacity
public prop capacity: Int64
功能:获取此双端队列的容量。
类型:Int64
prop first
public prop first: ?T
功能:获取双端队列的头部元素。如果双端队列为空,返回 None。
类型:Option<T>
prop last
public prop last: ?T
功能:获取双端队列的尾部元素。如果双端队列为空,返回 None。
类型:Option<T>
prop size
public prop size: Int64
功能:返回此双端队列中的元素个数。
类型:Int64
init()
public init()
功能:构造一个空的双端队列,其容量大小为默认值 8。
init(Int64)
public init(capacity: Int64)
功能:构造一个具有指定容量的双端队列,当 capacity 小于默认容量 8 时,构造的 ArrayDeque 初始容量为 8 。
参数:
- capacity: Int64 - 指定的初始容量。
异常:
- IllegalArgumentException - 如果参数的大小小于 0 则抛出异常。
func addFirst(T)
public func addFirst(element: T): Unit
功能:在此双端队列头部插入元素。
参数:
- element: T - 被插入到此双端队列的元素。
func addLast(T)
public func addLast(element: T): Unit
功能:在此双端队列尾部插入元素。
参数:
- element: T - 被插入到此双端队列的元素。
func clear()
public func clear(): Unit
功能:清空此双端队列中的所有元素。
func iterator()
public func iterator(): Iterator<T>
功能:获取此双端队列中元素的迭代器,其顺序为从前到后的顺序。
返回值:
- Iterator<T> - 元素的迭代器。
func isEmpty()
public func isEmpty(): Bool
功能:判断此双端队列是否为空。
返回值:
- Bool - 如果为空,则返回
true,否则,返回false。
func removeFirst()
public func removeFirst(): ?T
功能:删除双端队列中的头部元素并返回该值,如果此双端队列为空,返回 None。
返回值:
- ?T - 被删除的头部元素。
func removeLast()
public func removeLast(): ?T
功能:删除双端队列中的尾部元素并返回该值,如果此双端队列为空,返回 None。
返回值:
- ?T - 被删除的尾部元素。
func reserve(Int64)
public func reserve(additional: Int64): Unit
功能:增加此双端队列的容量。
将双端队列扩容 additional 大小,当 additional 小于等于零时,不发生扩容;当此双端队列剩余容量大于等于 additional 时,不发生扩容;当此双端队列剩余容量小于 additional 时,取(原始容量的1.5倍向下取整)与(additional + 已使用容量)两个值中的最大值进行扩容。
参数:
- additional: Int64 - 将要扩容的大小。
func toArray()
public func toArray(): Array<T>
功能:返回一个数组,其包含此双端队列中的所有元素,且顺序为从前到后的顺序。
返回值:
- Array<T> - T 类型数组。
extend<T> ArrayDeque<T> <: ToString where T <: ToString
extend<T> ArrayDeque<T> <: ToString where T <: ToString
功能:为 ArrayDeque<T> 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:获取当前ArrayDeque<T>实例的字符串表示。
该字符串包含双端队列内每个元素的字符串表示,其顺序为从前到后的顺序,形如:"[elem1, elem2, elem3]"。
返回值:
- String - 转换得到的字符串。
class ArrayList<T>
public class ArrayList<T> <: List<T> {
public init()
public init(capacity: Int64)
public init(size: Int64, initElement: (Int64) -> T)
public init(elements: Collection<T>)
}
功能:提供可变长度的数组的功能。
ArrayList 是一种线性的动态数组,与 Array 不同,它可以根据需要自动调整大小,并且在创建时不需要指定大小。
说明:
当向动态数组中添加元素时,如果数组已满,则会重新分配更大的内存空间,并将原有的元素复制到新的内存空间中。
动态数组的优点是可以节省内存空间,并且可以根据需要自动调整大小,因此非常适合需要频繁添加或删除元素的情况。但是,动态数组的缺点是在重新分配内存空间时可能会导致性能下降,因此在使用动态数组时需要考虑这一点。
父类型:
- List<T>
prop size
public prop size: Int64
功能:返回此 ArrayList 中的元素个数。
类型:Int64
prop capacity
public prop capacity: Int64
功能:返回此 ArrayList 的容量大小。
类型:Int64
prop first
public prop first: ?T
功能:返回此 ArrayList 中的第一个元素,如果没有则返回 None。
类型:Option<T>
prop last
public prop last: ?T
功能:返回此 ArrayList 中的最后一个元素,如果没有则返回 None。
类型:Option<T>
init()
public init()
功能:构造一个初始容量大小为默认值16的ArrayList。
init(Collection<T>)
public init(elements: Collection<T>)
功能:构造一个包含指定集合中所有元素的 ArrayList。这些元素按照集合的迭代器返回的顺序排列。
参数:
- elements: Collection<T> - 传入集合。
init(Int64)
public init(capacity: Int64)
功能:构造一个初始容量为指定大小的 ArrayList。
参数:
- capacity: Int64 - 指定的初始容量大小。
异常:
- IllegalArgumentException - 如果参数的大小小于 0 则抛出异常。
init(Int64, (Int64) -> T)
public init(size: Int64, initElement: (Int64) -> T)
功能:构造具有指定初始元素个数和指定规则函数的 ArrayList。该构造函数根据参数 size 设置 ArrayList 的容量。
参数:
异常:
- IllegalArgumentException - 如果 size 小于 0 则抛出异常。
static func of(Array<T>)
public static func of(elements: Array<T>): ArrayList<T>
功能:构造一个包含指定数组中所有元素的 ArrayList。
参数:
- elements: Array<T> - 传入数组。
返回值:
- ArrayList<T> - 元素为 T 类型的 ArrayList。
func add(T)
public func add(element: T): Unit
功能:将指定的元素附加到此 ArrayList 的末尾。
参数:
- element: T - 插入的元素,类型为 T。
示例:
使用示例见 ArrayList 的 add 函数。
func add(Collection<T>)
public func add(all!: Collection<T>): Unit
功能:将指定集合中的所有元素附加到此 ArrayList 的末尾。
函数会按照迭代器顺序遍历入参中的集合,并且将所有元素插入到此 ArrayList 的尾部。
参数:
- all!: Collection<T> - 需要插入的元素的集合。
func add(T, Int64)
public func add(element: T, at!: Int64): Unit
功能:在此 ArrayList 中的指定位置插入指定元素。
参数:
- element: T - 要插入的 T 类型元素。
- at!: Int64 - 插入元素的目标索引。
异常:
- IndexOutOfBoundsException - 当 at 超出范围时,抛出异常。
示例:
使用示例见 ArrayList 的 add 函数。
func add(Collection<T>, Int64)
public func add(all!: Collection<T>, at!: Int64): Unit
功能:从指定位置开始,将指定集合中的所有元素插入此 ArrayList。
函数会按照迭代器顺序遍历入参中的集合,并且将所有元素插入到指定位置,原先在指定位置及其后的元素会后移。
参数:
- all!: Collection<T> - 要插入的 T 类型元素集合。
- at!: Int64 - 插入集合的目标索引。
异常:
- IndexOutOfBoundsException - 当 at 超出范围时,抛出异常。
示例:
使用示例见 ArrayList 的 add 函数。
func clear()
public func clear(): Unit
功能:从此 ArrayList 中删除所有元素。
示例:
使用示例见 ArrayList 的 remove/clear/slice 函数。
func clone()
public func clone(): ArrayList<T>
功能:返回此 ArrayList 实例的拷贝(浅拷贝)。
返回值:
func get(Int64)
public func get(index: Int64): ?T
功能:返回此 ArrayList 中指定位置的元素。
参数:
- index: Int64 - 要返回的元素的索引。
返回值:
- ?T - 返回指定位置的元素,如果 index 大小小于 0 或者大于等于 ArrayList 中的元素数量,返回 None。
示例:
使用示例见 ArrayList 的 get/set 函数。
func getRawArray()
public unsafe func getRawArray(): Array<T>
功能:返回 ArrayList 的原始数据。
注意:
这是一个 unsafe 的接口,使用处需要在 unsafe 上下文中。
原始数据是指 ArrayList 底层实现的数组,其大小大于等于 ArrayList 中的元素数量,且索引大于等于 ArrayList 大小的位置中可能包含有未初始化的元素,对其进行访问可能会产生未定义的行为。
返回值:
func isEmpty()
public func isEmpty(): Bool
功能:判断 ArrayList 是否为空。
返回值:
- Bool - 如果为空,则返回
true,否则,返回false。
func iterator()
public func iterator(): Iterator<T>
功能:返回此 ArrayList 中元素的迭代器。
返回值:
func remove(Int64)
public func remove(at!: Int64): T
功能:删除此 ArrayList 中指定位置的元素。
参数:
- at!: Int64 - 被删除元素的索引。
返回值:
- T - 被移除的元素。
异常:
- IndexOutOfBoundsException - 当 at 超出范围时,抛出异常。
示例:
使用示例见 ArrayList 的 remove/clear/slice 函数。
func remove(Range<Int64>)
public func remove(range: Range<Int64>): Unit
功能:删除此 ArrayList 中 Range 范围所包含的所有元素。
注意:
如果参数 range 是使用 Range 构造函数构造的 Range 实例,hasEnd 为 false 时,end 值不生效,且不受构造时传入的 isClosed 的值的影响,数组切片取到原数组最后一个元素。
参数:
异常:
- IllegalArgumentException - 当 range 的 step 不等于 1 时抛出异常。
- IndexOutOfBoundsException - 当 range 的 start 或 end 小于 0,或 end 大于 Array 的长度时抛出。
func removeIf((T) -> Bool)
public func removeIf(predicate: (T) -> Bool): Unit
功能:删除此 ArrayList 中满足给定 lambda 表达式或函数的所有元素。
参数:
- predicate: (T) ->Bool - 传递判断删除的条件。
异常:
- ConcurrentModificationException - 当
predicate中增删或者修改 ArrayList 内元素时,抛出异常。
func reserve(Int64)
public func reserve(additional: Int64): Unit
功能:增加此 ArrayList 实例的容量。
将 ArrayList 扩容 additional 大小,当 additional 小于等于零时,不发生扩容;当 ArrayList 剩余容量大于等于 additional 时,不发生扩容;当 ArrayList 剩余容量小于 additional 时,取(原始容量的1.5倍向下取整)与(additional + 已使用容量)两个值中的最大值进行扩容。
参数:
- additional: Int64 - 将要扩容的大小。
异常:
- OverflowException - 当additional + 已使用容量超过Int64.Max时,抛出异常。
func reverse()
public func reverse(): Unit
功能:反转此 ArrayList 中元素的顺序。
func slice(Range<Int64>)
public func slice(range: Range<Int64>): ArrayList<T>
功能:以传入参数 range 作为索引,返回索引对应的 ArrayList<T>。
注意:
如果参数 range 是使用 Range 构造函数构造的 Range 实例,有如下行为:
- start 的值就是构造函数传入的值本身,不受构造时传入的 hasStart 的值的影响。
- hasEnd 为 false 时,end 值不生效,且不受构造时传入的 isClosed 的值的影响,该数组切片取到原数组最后一个元素。
参数:
返回值:
- ArrayList<T> - 切片所得的数组。
异常:
- IllegalArgumentException - 当 range.step 不等于 1 时,抛出异常。
- IndexOutOfBoundsException - 当 range 无效时,抛出异常。
示例:
使用示例见 ArrayList 的 remove/clear/slice 函数。
func sortBy((T, T) -> Ordering) (deprecated)
public func sortBy(comparator!: (T, T) -> Ordering): Unit
功能:对数组中的元素进行非稳定排序。
通过传入的比较函数,根据其返回值 Ordering 类型的结果,可对数组进行自定义排序comparator: (t1: T, t2: T) -> Ordering,如果 comparator 的返回值为 Ordering.GT,排序后 t1 在 t2后;如果 comparator 的返回值为 Ordering.LT,排序后 t1 在t2 前;如果 comparator 的返回值为 Ordering.EQ,且为稳定排序,那么 t1 在 t2 之前; 如果 comparator 的返回值为 Ordering.EQ,且为不稳定排序,那么 t1,t2 顺序不确定。
注意:
未来版本即将废弃,使用 sort 替代。
参数:
func sortBy(Bool, (T, T) -> Ordering) (deprecated)
public func sortBy(stable!: Bool, comparator!: (T, T) -> Ordering): Unit
功能:对数组中的元素进行排序。
通过传入的比较函数,根据其返回值 Ordering 类型的结果,可对数组进行自定义排序comparator: (t1: T, t2: T) -> Ordering,如果 comparator 的返回值为 Ordering.GT,排序后 t1 在 t2后;如果 comparator 的返回值为 Ordering.LT,排序后 t1 在t2 前;如果 comparator 的返回值为 Ordering.EQ,且为稳定排序,那么 t1 在 t2 之前; 如果 comparator 的返回值为 Ordering.EQ,且为不稳定排序,那么 t1,t2 顺序不确定。
注意:
未来版本即将废弃,使用 sort 替代。
参数:
func toArray()
public func toArray(): Array<T>
功能:返回一个数组,其中包含此列表中按正确顺序排列的所有元素。
返回值:
- Array<T> - T 类型数组。
operator func [](Int64)
public operator func [](index: Int64): T
功能:操作符重载 - get。
参数:
- index: Int64 - 表示 get 接口的索引。
返回值:
- T - 索引位置的元素的值。
异常:
- IndexOutOfBoundsException - 当 index 超出范围时,抛出异常。
operator func [](Int64, T)
public operator func [](index: Int64, value!: T): Unit
功能:操作符重载,通过下标运算符用指定的元素替换此列表中指定位置的元素。
参数:
- index: Int64 - 要设置的索引值。
- value!: T - 要设置的 T 类型的值。
异常:
- IndexOutOfBoundsException - 当 index 超出范围时,抛出异常。
operator func [](Range<Int64>)
public operator func [](range: Range<Int64>): ArrayList<T>
功能:运算符重载 - 切片。
注意:
参数:
返回值:
- ArrayList<T> - 切片所得的数组。
异常:
- IllegalArgumentException - 当 range.step 不等于 1 时,抛出异常。
- IndexOutOfBoundsException - 当 range 无效时,抛出异常。
extend<T> ArrayList<T> <: Equatable<ArrayList<T>> where T <: Equatable<T>
extend<T> ArrayList<T> <: Equatable<ArrayList<T>> where T <: Equatable<T>
功能:为 ArrayList<T> 类型扩展 Equatable<ArrayList<T>> 接口,支持判等操作。
父类型:
operator func ==(ArrayList<T>)
public operator func ==(that: ArrayList<T>): Bool
功能:判断当前实例与参数指向的 ArrayList 实例是否相等。
两个数组相等指的是两者对应位置的元素分别相等。
参数:
- that: ArrayList<T> - 被比较的对象。
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
operator func !=(ArrayList<T>)
public operator func !=(that: ArrayList<T>): Bool
功能:判断当前实例与参数指向的 ArrayList 实例是否不等。
参数:
- that: ArrayList<T> - 被比较的对象。
返回值:
- Bool - 如果不等,则返回 true,否则返回 false。
func contains(T)
public func contains(element: T): Bool
功能:判断当前数组中是否含有指定元素 element。
参数:
- element: T - 待寻找的元素。
返回值:
- Bool - 如果数组中包含指定元素,返回 true,否则返回 false。
extend<T> ArrayList<T> <: SortExtension where T <: Comparable<T> (deprecated)
extend<T> ArrayList<T> where T <: Comparable<T>
功能:为 ArrayList<T> 扩展 SortExtension 接口,支持数组排序。
注意:
未来版本即将废弃。
父类型:
func sort() (deprecated)
public func sort(): Unit
功能:将当前数组内元素以升序的方式非稳定排序。
注意:
未来版本即将废弃,使用 sort 替代。
func sort(Bool) (deprecated)
public func sort(stable!: Bool): Unit
功能:将当前数组内元素以升序的方式排序。
参数:
- stable!: Bool - 是否使用稳定排序。
注意:
未来版本即将废弃,使用 sort 替代。
func sortDescending() (deprecated)
public func sortDescending(): Unit
功能:将当前数组内元素以降序的方式非稳定排序。
注意:
未来版本即将废弃,使用 sort 替代。
func sortDescending(Bool) (deprecated)
public func sortDescending(stable!: Bool): Unit
功能:将当前数组内元素以降序的方式排序。
参数:
- stable!: Bool - 是否使用稳定排序。
注意:
未来版本即将废弃,使用 sort 替代。
extend<T> ArrayList<T> <: ToString where T <: ToString
extend<T> ArrayList<T> <: ToString where T <: ToString
功能:为 ArrayList<T> 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将当前数组转换为字符串。
该字符串包含数组内每个元素的字符串表示,形如:"[elem1, elem2, elem3]"。
返回值:
- String - 转换得到的字符串。
class ArrayQueue<T>
public class ArrayQueue<T> <: Queue<T> {
public init()
public init(capacity: Int64)
}
功能:基于数组实现的循环队列数据结构。
父类型:
- Queue<T>
prop capacity
public prop capacity: Int64
功能:获取此队列的容量。
类型:Int64
prop size
public prop size: Int64
功能:返回此队列中的元素个数。
类型:Int64
init()
public init()
功能:构造一个空的队列,其容量大小为默认值 8。
init(Int64)
public init(capacity: Int64)
功能:构造一个具有指定容量的队列,当 capacity 小于默认容量 8 时,构造的 ArrayQueue 初始容量为 8 。
参数:
- capacity: Int64 - 指定的初始容量。
异常:
- IllegalArgumentException - 如果参数的大小小于 0 则抛出异常。
func add(T)
public func add(element: T): Unit
功能:在此队列尾部插入元素。
参数:
- element: T - 被插入到此双端队列的元素。
func clear()
public func clear(): Unit
功能:清空此队列中的所有元素。
func iterator()
public func iterator(): Iterator<T>
功能:获取此队列中元素的迭代器,其顺序为从前到后的顺序。
返回值:
- Iterator<T> - 元素的迭代器。
func isEmpty()
public func isEmpty(): Bool
功能:判断此队列是否为空。
返回值:
- Bool - 如果为空,则返回
true,否则,返回false。
func peek()
public func peek():?T
功能:查看此队列头部元素。此操作不会删除元素。
返回值:
- ?T - 队列的头部元素,如果队列为空,返回
None。
func remove()
public func remove(): ?T
功能:删除队列中的头部元素并返回该值,如果此队列为空,返回 None。
返回值:
- ?T - 被删除的头部元素。
func reserve(Int64)
public func reserve(additional: Int64): Unit
功能:增加此队列的容量。
将队列扩容 additional 大小,当 additional 小于等于零时,不发生扩容;当此队列剩余容量大于等于 additional 时,不发生扩容;当此队列剩余容量小于 additional 时,取(原始容量的 1.5 倍向下取整)与(additional + 已使用容量)两个值中的最大值进行扩容。
参数:
- additional: Int64 - 将要扩容的大小。
func toArray()
public func toArray(): Array<T>
功能:返回一个数组,其包含此队列中的所有元素,且顺序为从前到后的顺序。
返回值:
- Array<T> - T 类型数组。
extend<T> ArrayQueue<T> <: ToString where T <: ToString
extend<T> ArrayQueue<T> <: ToString where T <: ToString
功能:为 ArrayQueue<T> 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:获取当前ArrayQueue<T>实例的字符串表示。
该字符串包含双端队列内每个元素的字符串表示,其顺序为从前到后的顺序,形如:"[elem1, elem2, elem3]"。
返回值:
- String - 转换得到的字符串。
class ArrayStack<T>
public class ArrayStack<T> <: Stack<T> {
public init(capacity: Int64)
public init()
}
功能:ArrayStack 是一种基于数组 Array 实现的栈 Stack 数据结构。ArrayStack 的实现方式是使用一个数组来存储栈中的元素,同时使用一个指针来指向栈顶元素的位置。
ArrayStack 只支持后进先出(Last In First Out,LIFO),只能在头部进行插入删除操作,并且 ArrayStack 会根据实际需要进行扩容。
父类型:
- Stack<T>
prop capacity
public prop capacity: Int64
功能:栈的容量大小。
类型:Int64
prop size
public prop size: Int64
功能:栈中元素的数量。
类型:Int64
func init()
public init()
功能:构造一个空的 ArrayStack,其初始容量为 8 。
func init(Int64)
public init(capacity: Int64)
功能:构造一个空的 ArrayStack,其初始容量为指定的值。当 capacity 小于默认容量 8 时,构造的 ArrayStack 初始容量为 8 。
参数:
- capacity: Int64 - 初始容量大小。
异常:
- IllegalArgumentException - 当入参为负数时,抛出此异常。
func add(T)
public func add(element: T): Unit
功能:在栈顶添加元素。
参数:
- element: T - 添加的元素。
func clear()
public func clear(): Unit
功能:清空当前的 ArrayStack。
func isEmpty()
public func isEmpty(): Bool
功能:判断此 ArrayStack 是否为空。
返回值:
- Bool - 如果为空,返回 true,否则返回 false。
func iterator()
public func iterator(): Iterator<T>
功能:返回此 ArrayStack 中元素的迭代器,其顺序为出栈的顺序。
返回值:
- Iterator<T> - 栈中元素的迭代器。
func peek()
public func peek(): ?T
功能:获取栈顶的元素,该操作不会做出栈操作,只查看栈顶的元素。当栈为空时,返回 None。
返回值:
- ?T - 栈顶的元素。
func remove()
public func remove(): ?T
功能:出栈操作,删除栈顶的元素并且返回这个元素。当栈为空时,返回 None。
返回值:
- ?T - 被删除的栈顶元素。
func reserve(Int64)
public func reserve(additional: Int64): Unit
功能:为当前 ArrayStack 预留出相应的空间。当 additional 小于等于零时,不发生扩容;如果当前剩余空间大小大于等于 additional,不进行扩容操作,否则当前 ArrayStack 会扩容至 size + additional 大小。
参数:
- additional: Int64 - 预留的剩余容量大小。
func toArray()
public func toArray(): Array<T>
功能:返回一个数组,其中元素为栈中的元素,顺序为栈的出栈顺序。
返回值:
- Array<T> - T 类型数组。
extend<T> ArrayStack<T> <: ToString where T <: ToString
extend<T> ArrayStack<T> <: ToString where T <: ToString
功能:为 ArrayStack 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:获取当前 ArrayStack<T> 实例的字符串表示。
该字符串包含栈内每个元素的字符串表示,其顺序为从后到前的顺序。形如:"[elem1, elem2, elem3]"。
返回值:
- String - 当前栈的字符串表示。
class HashMapIterator<K, V> where K <: Hashable & Equatable<K>
public class HashMapIterator<K, V> <: Iterator<(K, V)> where K <: Hashable & Equatable<K> {
public init(map: HashMap<K, V>)
}
功能:此类主要实现 HashMap 的迭代器功能。
父类型:
- Iterator<(K, V)>
init(HashMap<K, V>)
public init(map: HashMap<K, V>)
功能:创建 HashMapIterator<K, V> 实例。
参数:
func next()
public func next(): ?(K, V)
功能:返回迭代器中的下一个元素。
返回值:
- ?(K, V) - 迭代器中的下一个元素,用 Option 封装。
异常:
- ConcurrentModificationException - 当函数检测到不同步的并发修改,抛出异常。
func remove()
public func remove(): Option<(K, V)>
功能:删除此 HashMap 迭代器的 next 函数返回的元素,此函数只能在 next 函数调用时调用一次。
返回值:
- Option<(K, V)> - 返回被删除的元素。
异常:
- ConcurrentModificationException - 当函数检测到不同步的并发修改,抛出异常。
class HashMap<K, V> where K <: Hashable & Equatable<K>
public class HashMap<K, V> <: Map<K, V> where K <: Hashable & Equatable<K> {
public init()
public init(elements: Array<(K, V)>)
public init(elements: Collection<(K, V)>)
public init(capacity: Int64)
public init(size: Int64, initElement: (Int64) -> (K, V))
}
功能:Map 接口的哈希表实现。
哈希表是一种常用的数据结构,它可以用来快速地查找、插入和删除数据。哈希表的基本原理是将数据映射到一个数组中,这个数组称为哈希表。每个数据元素都有一个对应的哈希值,这个哈希值可以用来确定该元素在哈希表中的位置。
哈希表的特点是快速的查找、插入和删除操作,时间复杂度通常是O(1)。由于哈希表底层的数组大小是动态的,所以哈希表不能保证元素的顺序不可变。
父类型:
- Map<K, V>
prop capacity
public prop capacity: Int64
功能:返回 HashMap 的容量。
返回值:
prop size
public prop size: Int64
功能:返回键值对的个数。
类型:Int64
init()
public init()
功能:构造一个具有默认初始容量为16和默认负载因子为空的 HashMap。
init(Array<(K, V)>)
public init(elements: Array<(K, V)>)
功能:通过传入的键值对数组构造一个 HashMap。
该构造函数根据传入数组的 size 设置 HashMap 的容量。由于HashMap 内部不允许键重复,当 Array 中存在重复的键时,按照迭代器顺序,出现在后面的键值对将会覆盖前面的键值对。
参数:
init(Collection<(K, V)>)
public init(elements: Collection<(K, V)>)
功能:通过传入的键值对集合构造一个 HashMap。
该构造函数根据传入集合 elements 的 size 设置 HashMap 的容量。由于HashMap 内部不允许键重复,当 Array 中存在重复的键时,按照迭代器顺序,出现在后面的键值对将会覆盖前面的键值对。
参数:
- elements: Collection<(K, V)> - 初始化该 HashMap 的键值对集合。
init(Int64)
public init(capacity: Int64)
功能:构造一个带有传入容量大小的 HashMap。
参数:
- capacity: Int64 - 初始化容量大小。
异常:
- IllegalArgumentException - 如果 capacity 小于 0 则抛出异常。
init(Int64, (Int64) -> (K, V))
public init(size: Int64, initElement: (Int64) -> (K, V))
功能:通过传入的元素个数 size 和函数规则来构造 HashMap。
构造出的 HashMap 的容量受 size 大小影响。由于HashMap 内部不允许键重复,当函数 initElement 生成相同的键时,后构造的键值对将会覆盖之前出现的键值对。
参数:
异常:
- IllegalArgumentException - 如果 size 小于 0 则抛出异常。
func add(K, V)
public func add(key: K, value: V): Option<V>
功能:将键值对放入 HashMap 中。
对于 HashMap 中已有的键,该键的值将被新值替换,并且返回旧的值。
参数:
- key: K - 要放置的键。
- value: V - 要分配的值。
返回值:
示例:
使用示例见 HashMap 的 get/add/contains 函数。
func add(Collection<(K, V)>)
public func add(all!: Collection<(K, V)>): Unit
功能:按照 elements 的迭代器顺序将新的键值对集合放入 HashMap 中。
对于 HashMap 中已有的键,该键的值将被新值替换。
参数:
- all!: Collection<(K, V)> - 需要添加进 HashMap 的键值对集合。
示例:
使用示例见 HashMap 的 add/remove/clear 函数。
func addIfAbsent(K, V)
func addIfAbsent(key: K, value: V): ?V
功能:如果 key 不在当前 HashMap 中,添加指定键值对 key-value。否则不做修改。
参数:
- key: K - 待添加键值对的键。
- value: V - 待添加键值对的值。
返回值:
- ?V - 如果调用该函数时当前 HashMap 中已有指定的 key,返回该 key 对应的旧值,否则返回 None。
func clear()
public func clear(): Unit
功能:清除所有键值对。
示例:
使用示例见 HashMap 的 add/remove/clear 函数。
func clone()
public func clone(): HashMap<K, V>
功能:克隆 HashMap。
返回值:
func contains(K)
public func contains(key: K): Bool
功能:判断是否包含指定键的映射。
参数:
- key: K - 传递要判断的 key。
返回值:
- Bool - 如果存在,则返回 true;否则,返回 false。
示例:
使用示例见 HashMap 的 get/add/contains 函数。
func contains(Collection<K>)
public func contains(all!: Collection<K>): Bool
功能:判断是否包含指定集合中所有键的映射。
参数:
- all!: Collection<K> - 键传递待判断的 keys。
返回值:
- Bool - 如果都包含,则返回 true;否则,返回 false。
func entryView(K)
public func entryView(key: K): MapEntryView<K, V>
功能:如果不包含特定键,返回一个空的引用视图。如果包含特定键,则返回该键对应的元素的引用视图。
参数:
- key: K - 要添加的键值对的键。
返回值:
- MapEntryView<K, V> - 一个引用视图。
func get(K)
public func get(key: K): ?V
功能:返回指定键映射到的值,如果 HashMap 不包含指定键的映射,则返回 Option<V>.None。
参数:
- key: K - 传入的键。
返回值:
- ?V - 键对应的值。用 Option 封装。
示例:
使用示例见 HashMap 的 get/add/contains 函数。
func isEmpty()
public func isEmpty(): Bool
功能:判断 HashMap 是否为空,如果是,则返回 true;否则,返回 false。
返回值:
func iterator()
public func iterator(): HashMapIterator<K, V>
功能:返回 HashMap 的迭代器。
返回值:
- HashMapIterator<K, V> - 返回 HashMap 的迭代器。
func keys()
public func keys(): EquatableCollection<K>
功能:返回 HashMap 中所有的 key,并将所有 key 存储在一个 Keys 容器中。
返回值:
- EquatableCollection<K> - 保存所有返回的 key。
func remove(Collection<K>)
public func remove(all!: Collection<K>): Unit
功能:从此 HashMap 中删除指定集合中键的映射(如果存在)。
参数:
- all!: Collection<K> - 传入要删除的键的集合。
func remove(K)
public func remove(key: K): Option<V>
功能:从此 HashMap 中删除指定键的映射(如果存在)。
参数:
- key: K - 传入要删除的 key。
返回值:
示例:
使用示例见 HashMap 的 add/remove/clear 函数。
func removeIf((K, V) -> Bool)
public func removeIf(predicate: (K, V) -> Bool): Unit
功能:传入 lambda 表达式,如果满足条件,则删除对应的键值对。
该函数会遍历整个HashMap,所以满足 predicate(K, V) == true 的键值对都会被删除。
参数:
- predicate: (K, V) ->Bool - 传递一个 lambda 表达式进行判断。
异常:
- ConcurrentModificationException - 当
predicate中增删或者修改 HashMap 内键值对时,抛出异常。
func replace(K, V)
func replace(key: K, value: V): ?V
功能:如果当前 HashMap 中已有指定 key,将其值修改为 value。否则不做修改。
参数:
- key: K - 待修改键值对的键。
- value: V - 待修改键值对的新值。
返回值:
- ?V - 如果当前 HashMap 中已有指定 key,返回其旧值。否则返回 None。
func reserve(Int64)
public func reserve(additional: Int64): Unit
功能:扩容当前的HashMap。
将 HashMap 扩容 additional 大小,当 additional 小于等于零时,不发生扩容;当 HashMap 剩余容量大于等于 additional 时,不发生扩容;当 HashMap 剩余容量小于 additional 时,取(原始容量的1.5倍向下取整)与(additional + 已使用容量)中的最大值进行扩容。
参数:
- additional: Int64 - 将要扩容的大小。
异常:
- OverflowException - 当additional + 已使用容量超过Int64.Max时,抛出异常。
func toArray()
public func toArray(): Array<(K, V)>
功能:构造一个包含 HashMap 内键值对的数组,并返回。
返回值:
- Array<(K, V)> - 包含容器内所有键值对的数组。
func values()
public func values(): Collection<V>
功能:返回 HashMap 中包含的值,并将所有的 value 存储在一个 Values 容器中。
返回值:
- Collection<V> - 保存所有返回的 value。
operator func [](K, V)
public operator func [](key: K, value!: V): Unit
功能:运算符重载 add 方法,如果键存在,新 value 覆盖旧 value,如果键不存在,添加此键值对。
参数:
- key: K - 传递值进行判断。
- value!: V - 传递要设置的值。
operator func [](K)
public operator func [](key: K): V
功能:运算符重载 get 方法,如果键存在,返回键对应的值。
参数:
- key: K - 传递值进行判断。
返回值:
- V - 与键对应的值。
异常:
- NoneValueException - 如果该 HashMap 不存在该键,抛此异常。
extend<K, V> HashMap<K, V> <: Equatable<HashMap<K, V>> where V <: Equatable<V>
extend<K, V> HashMap<K, V> <: Equatable<HashMap<K, V>> where V <: Equatable<V>
功能:为 HashMap<K, V> 类型扩展 Equatable<HashMap<K, V>> 接口,支持判等操作。
父类型:
operator func ==(HashMap<K, V>)
public operator func ==(right: HashMap<K, V>): Bool
功能:判断当前实例与参数指向的 HashMap<K, V> 实例是否相等。
两个 HashMap<K, V> 相等指的是其中包含的键值对完全相等。
参数:
- right: HashMap<K, V> - 被比较的对象。
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
operator func !=(HashMap<K, V>)
public operator func !=(right: HashMap<K, V>): Bool
功能:判断当前实例与参数指向的 HashMap<K, V> 实例是否不等。
参数:
- right: HashMap<K, V> - 被比较的对象。
返回值:
- Bool - 如果不等,则返回 true,否则返回 false。
extend<K, V> HashMap<K, V> <: ToString where V <: ToString, K <: ToString
extend<K, V> HashMap<K, V> <: ToString where V <: ToString, K <: ToString
功能:为 HashMap<K, V> 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将当前 HashMap<K, V> 实例转换为字符串。
该字符串包含 HashMap<K, V> 内每个键值对的字符串表示,形如:"[(k1, v1), (k2, v2), (k3, v3)]"。
返回值:
- String - 转换得到的字符串。
class HashSet<T> where T <: Hashable & Equatable<T>
public class HashSet<T> <: Set<T> where T <: Hashable & Equatable<T> {
public init()
public init(elements: Collection<T>)
public init(elements: Array<T>)
public init(capacity: Int64)
public init(size: Int64, initElement: (Int64) -> T)
}
HashSet中的元素是无序的,不允许有重复元素。当我们向HashSet中添加元素时,HashSet会根据元素的哈希值来确定该元素在哈希表中的位置。
提示:
HashSet 是基于 HashMap 实现的,因此 HashSet 的容量、内存布局、时间性能等都和 HashMap 相同。
父类型:
- Set<T>
prop size
public prop size: Int64
功能:返回此 HashSet 的元素个数。
类型:Int64
init(Int64, (Int64) -> T)
public init(size: Int64, initElement: (Int64) -> T)
功能:通过传入的函数元素个数 size 和函数规则来构造 HashSet。构造出的 HashSet 的容量受 size 大小影响。
参数:
异常:
- IllegalArgumentException - 如果 size 小于 0,抛出异常。
init()
public init()
功能:构造一个空的 HashSet ,初始容量为 16 。
init(Array<T>)
public init(elements: Array<T>)
功能:使用传入的数组构造 HashSet。该构造函数根据传入数组 elements 的 size 设置 HashSet 的容量。
参数:
init(Collection<T>)
public init(elements: Collection<T>)
功能:使用传入的集合构造 HashSet。该构造函数根据传入集合 elements 的 size 设置 HashSet 的容量。
参数:
- elements: Collection<T> - 初始化 HashSet 的集合。
init(Int64)
public init(capacity: Int64)
功能:使用传入的容量构造一个 HashSet。
参数:
- capacity: Int64 - 初始化容量大小。
异常:
- IllegalArgumentException - 如果 capacity 小于 0,抛出异常。
func add(T)
public func add(element: T): Bool
功能:将指定的元素添加到 HashSet 中, 若添加的元素在 HashSet 中存在, 则添加失败。
参数:
- element: T - 指定的元素。
返回值:
- Bool - 如果添加成功,则返回 true;否则,返回 false。
示例:
使用示例见 HashSet 的 add/iterator/remove 函数。
func add(Collection<T>)
public func add(all!: Collection<T>): Unit
功能:添加 Collection 中的所有元素至此 HashSet 中,如果元素存在,则不添加。
参数:
- all!: Collection<T> - 需要被添加的元素的集合。
prop capacity
public prop capacity: Int64
功能:返回此 HashSet 的内部数组容量大小。
注意:
容量大小不一定等于 HashSet 的 size。
返回值:
func clear()
public func clear(): Unit
功能:从此 HashSet 中移除所有元素。
func clone()
public func clone(): HashSet<T>
功能:克隆 HashSet。
返回值:
func contains(T)
public func contains(element: T): Bool
功能:判断 HashSet 是否包含指定元素。
参数:
- element: T - 指定的元素。
返回值:
- Bool - 如果包含指定元素,则返回 true;否则,返回 false。
func contains(Collection<T>)
public func contains(all!: Collection<T>): Bool
功能:判断 HashSet 是否包含指定 Collection 中的所有元素。
参数:
- all!: Collection<T> - 指定的元素集合。
返回值:
- Bool - 如果此 HashSet 包含 Collection 中的所有元素,则返回 true;否则,返回 false。
func isEmpty()
public func isEmpty(): Bool
功能:判断 HashSet 是否为空。
返回值:
- Bool - 如果为空,则返回 true;否则,返回 false。
func iterator()
public func iterator(): Iterator<T>
功能:返回此 HashSet 的迭代器。
返回值:
示例:
使用示例见 HashSet 的 add/iterator/remove 函数。
func remove(T)
public func remove(element: T): Bool
功能:如果指定元素存在于此 HashSet 中,则将其移除。
参数:
- element: T - 需要被移除的元素。
返回值:
- Bool - true,表示移除成功;false,表示移除失败。
示例:
使用示例见 HashSet 的 add/iterator/remove 函数。
func remove(Collection<T>)
public func remove(all!: Collection<T>): Unit
功能:移除此 HashSet 中那些也包含在指定 Collection 中的所有元素。
参数:
- all!: Collection<T> - 需要从此 HashSet 中移除的元素的集合。
func removeIf((T) -> Bool)
public func removeIf(predicate: (T) -> Bool): Unit
功能:传入 lambda 表达式,如果满足 true 条件,则删除对应的元素。
参数:
- predicate: (T) ->Bool - 是否删除元素的判断条件。
异常:
- ConcurrentModificationException - 当
predicate中增删或者修改 HashSet 内元素时,抛出异常。
func reserve(Int64)
public func reserve(additional: Int64): Unit
功能:将 HashSet 扩容 additional 大小,当 additional 小于等于零时,不发生扩容;当 HashSet 剩余容量大于等于 additional 时,不发生扩容;当 HashSet 剩余容量小于 additional 时,取(原始容量的1.5倍向下取整)与(additional + 已使用容量)中的最大值进行扩容。
参数:
- additional: Int64 - 将要扩容的大小。
异常:
- OverflowException - 当additional + 已使用容量超过Int64.Max时,抛出异常。
func retain(Set<T>)
public func retain(all!: Set<T>): Unit
参数:
func subsetOf(ReadOnlySet<T>)
public func subsetOf(other: ReadOnlySet<T>): Bool
功能:检查该集合是否为其他 ReadOnlySet 的子集。
参数:
- other: ReadOnlySet<T> - 传入集合,此函数将判断当前集合是否为 other 的子集。
返回值:
- Bool - 如果该 Set 是指定 ReadOnlySet 的子集,则返回 true;否则返回 false。
func toArray()
public func toArray(): Array<T>
功能:返回一个包含容器内所有元素的数组。
返回值:
- Array<T> - T 类型数组。
operator func &(ReadOnlySet<T>)
public operator func &(other: ReadOnlySet<T>): HashSet<T>
功能:返回包含两个集合交集的元素的新集合。
参数:
- other: ReadOnlySet<T> - 传入集合。
返回值:
- HashSet<T> - T 类型集合。
operator func |(ReadOnlySet<T>)
public operator func |(other: ReadOnlySet<T>): HashSet<T>
功能:返回包含两个集合并集的元素的新集合。
参数:
- other: ReadOnlySet<T> - 传入集合。
返回值:
- HashSet<T> - T 类型集合。
operator func -(ReadOnlySet<T>)
public operator func -(other: ReadOnlySet<T>): HashSet<T>
功能:返回包含两个集合差集的元素的新集合。
参数:
- other: ReadOnlySet<T> - 传入集合。
返回值:
- HashSet<T> - T 类型集合。
extend<T> HashSet<T> <: Equatable<HashSet<T>>
extend<T> HashSet<T> <: Equatable<HashSet<T>>
功能:为 HashSet<T> 类型扩展 Equatable<HashSet<T>> 接口,支持判等操作。
父类型:
operator func ==(HashSet<T>)
public operator func ==(that: HashSet<T>): Bool
功能:判断当前实例与参数指向的 HashSet<T> 实例是否相等。
两个 HashSet<T> 相等指的是其中包含的元素完全相等。
参数:
- that: HashSet<T> - 被比较的对象。
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
operator func !=(HashSet<T>)
public operator func !=(that: HashSet<T>): Bool
功能:判断当前实例与参数指向的 HashSet<T> 实例是否不等。
参数:
- that: HashSet<T> - 被比较的对象。
返回值:
- Bool - 如果不等,则返回 true,否则返回 false。
extend<T> HashSet<T> <: ToString where T <: ToString
extend<T> HashSet<T> <: ToString where T <: ToString
功能:为 HashSet<T> 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将当前 HashSet<T> 实例转换为字符串。
该字符串包含 HashSet<T> 内每个元素的字符串表示,形如:"[elem1, elem2, elem3]"。
返回值:
- String - 转换得到的字符串。
class LinkedListNode<T>
public class LinkedListNode<T>
功能:LinkedListNode 是 LinkedList 上的节点。
可以通过 LinkedListNode 对 LinkedList 进行前向后向遍历操作,也可以访问和修改元素的值。
LinkedListNode 只能通过对应 LinkedList 的 'nodeAt'、'firstNode'、'lastNode' 获得,当 LinkedList 删除掉对应的节点时,会造成一个悬空的节点,对悬空的节点进行任何操作都会抛 'IllegalStateException' 异常。
prop next
public prop next: Option<LinkedListNode<T>>
功能:获取当前节点的下一个节点,如果没有则返回 None。
类型:Option<LinkedListNode<T>>
异常:
- IllegalStateException - 如果该节点不属于任何链表实例,抛此异常。
prop prev
public prop prev: Option<LinkedListNode<T>>
功能:获取当前节点的前一个节点,如果没有则返回 None。
类型:Option<LinkedListNode<T>>
异常:
- IllegalStateException - 如果该节点不属于任何链表实例,抛此异常。
prop value
public mut prop value: T
功能:获取或者修改元素的值。
类型:T
异常:
- IllegalStateException - 如果该节点不属于任何链表实例,抛此异常。
class LinkedList<T>
public class LinkedList<T> <: Collection<T> {
public init()
public init(elements: Collection<T>)
public init(elements: Array<T>)
public init(size: Int64, initElement: (Int64)-> T)
}
功能:实现双向链表的数据结构。
双向链表是一种常见的数据结构,它由一系列节点组成,每个节点都包含两个指针,一个指向前一个节点,另一个指向后一个节点。这种结构允许在任何一个节点上进行双向遍历,即可以从头节点开始向后遍历,也可以从尾节点开始向前遍历。
LinkedList 不支持并发操作,并且对集合中元素的修改不会使迭代器失效,只有在添加和删除元素的时候会使迭代器失效。
父类型:
- Collection<T>
prop first
public prop first: ?T
功能:链表中第一个元素的值,如果是空链表则返回 None。
类型:?T
prop firstNode
public prop firstNode: ?LinkedListNode<T>
功能:获取链表中的第一个元素的节点。
类型:?LinkedListNode<T>
prop last
public prop last: ?T
功能:链表中最后一个元素的值,如果是空链表则返回 None。
类型:?T
prop lastNode
public prop lastNode: ?LinkedListNode<T>
功能:获取链表中的最后一个元素的节点。
类型:?LinkedListNode<T>
prop size
public prop size: Int64
功能:链表中的元素数量。
类型:Int64
init
public init()
功能:构造一个空的链表。
init(Array<T>)
public init(elements: Array<T>)
功能:按照数组的遍历顺序构造一个包含指定集合元素的 LinkedList 实例。
参数:
- elements: Array<T> - 将要放入此链表中的元素数组。
init(Collection<T>)
public init(elements: Collection<T>)
功能:按照集合迭代器返回元素的顺序构造一个包含指定集合元素的链表。
参数:
- elements: Collection<T> - 将要放入此链表中的元素集合。
init(Int64, (Int64)-> T)
public init(size: Int64, initElement: (Int64)-> T)
功能:创建一个包含 size 个元素,且第 n 个元素满足 (Int64)-> T 条件的链表。
参数:
异常:
- IllegalArgumentException - 如果指定的链表长度小于 0 则抛此异常。
func addAfter(LinkedListNode<T>,T)
public func addAfter(node: LinkedListNode<T>, element: T): LinkedListNode<T>
功能:在链表中指定节点的后面插入一个元素,并且返回该元素的节点。
参数:
- node: LinkedListNode<T> - 指定的节点。
- element: T - 要添加到链表中的元素。
返回值:
- LinkedListNode<T> - 指向被插入元素的节点。
异常:
- IllegalArgumentException - 如果指定的节点不属于该链表,则抛此异常。
func addBefore(LinkedListNode<T>,T)
public func addBefore(node: LinkedListNode<T>, element: T): LinkedListNode<T>
功能:在链表中指定节点的前面插入一个元素,并且返回该元素的节点。
参数:
- node: LinkedListNode<T> - 指定的节点。
- element: T - 要添加到链表中的元素。
返回值:
- LinkedListNode<T> - 指向被插入元素的节点。
异常:
- IllegalArgumentException - 如果指定的节点不属于该链表,则抛此异常。
func addFirst(T)
public func addFirst(element: T): LinkedListNode<T>
功能:在链表的头部位置插入一个元素,并且返回该元素的节点。
参数:
- element: T - 要添加到链表中的元素。
返回值:
- LinkedListNode<T> - 指向该元素的节点。
func addLast(T)
public func addLast(element: T): LinkedListNode<T>
功能:在链表的尾部位置添加一个元素,并且返回该元素的节点。
参数:
- element: T - 要添加到链表中的元素。
返回值:
- LinkedListNode<T> - 指向该元素的节点。
func backward(LinkedListNode<T>)
public func backward(mark: LinkedListNode<T>): Iterator<T>
功能:获取一个从 mark 节点开始,到所对应链表的头部节点的所有元素的迭代器。
参数:
- mark: LinkedListNode<T> - 开始的元素节点。
返回值:
- Iterator<T> - 对应元素的迭代器。
异常:
- IllegalStateException - 如果该节点不属于任何链表实例,抛此异常。
func clear()
public func clear(): Unit
功能:删除链表中的所有元素。
func forward(LinkedListNode<T>)
public func forward(mark: LinkedListNode<T>): Iterator<T>
功能:获取一个从 mark 节点开始,到所对应链表的尾部节点的所有元素的迭代器。
参数:
- mark: LinkedListNode<T> - 开始的元素节点。
返回值:
- Iterator<T> - 对应元素的迭代器。
异常:
- IllegalStateException - 如果该节点不属于任何链表实例,抛此异常。
func isEmpty()
public func isEmpty(): Bool
功能:返回此链表是否为空链表的判断。
返回值:
- Bool - 如果此链表中不包含任何元素,返回 true。
func iterator()
public func iterator(): Iterator<T>
功能:返回当前集合中元素的迭代器,其顺序是从链表的第一个节点到链表的最后一个节点。
返回值:
- Iterator<T> - 当前集合中元素的迭代器。
func nodeAt(Int64)
public func nodeAt(index: Int64): Option<LinkedListNode<T>>
功能:获取链表中的第 index 个元素的节点,编号从 0 开始。
该函数的时间复杂度为 O(n)。
参数:
- index: Int64 - 指定获取第 index 个元素的节点。
返回值:
- Option<LinkedListNode<T>> - 编号为 index 的节点,如果没有则返回 None。
func removeFirst()
public func removeFirst() : ?T
功能:移除链表的第一个元素,并返回该元素的值。
返回值:
- ?T - 被删除的元素的值,若链表为空则返回 None。
func removeLast()
public func removeLast() : ?T
功能:移除链表的最后一个元素,并返回该元素的值。
返回值:
- ?T - 被删除的元素的值,若链表为空则返回 None。
func remove(LinkedListNode<T>)
public func remove(node: LinkedListNode<T>): T
功能:删除链表中指定节点。
参数:
- node: LinkedListNode<T> - 要被删除的节点。
返回值:
- T - 被删除的节点的值。
异常:
- IllegalArgumentException - 如果指定的节点不属于该链表,则抛此异常。
func removeIf((T)-> Bool)
public func removeIf(predicate: (T)-> Bool): Unit
功能:删除此链表中满足给定 lambda 表达式或函数的所有元素。
参数:
- predicate: (T) ->Bool - 对于要删除的元素,返回值为 true。
异常:
- ConcurrentModificationException - 当
predicate中增删或者修改 LinkedList 内节点时,抛出异常。
func reverse()
public func reverse(): Unit
功能:反转此链表中的元素顺序。
func splitOff(LinkedListNode<T>)
public func splitOff(node: LinkedListNode<T>): LinkedList<T>
功能:从指定的节点 node 开始,将链表分割为两个链表,如果分割成功,node 不在当前的链表内,而是作为首个节点存在于新的链表内部。
参数:
- node: LinkedListNode<T> - 要分割的位置。
返回值:
- LinkedList<T> - 原链表分割后新产生的链表。
异常:
- IllegalArgumentException - 如果指定的节点不属于该链表,则抛此异常。
func toArray()
public func toArray(): Array<T>
功能:返回一个数组,数组包含该链表中的所有元素,并且顺序与链表的顺序相同。
返回值:
- Array<T> - T 类型数组。
extend<T> LinkedList<T> <: Equatable<LinkedList<T>> where T <: Equatable<T>
extend<T> LinkedList<T> <: Equatable<LinkedList<T>> where T <: Equatable<T>
功能:为 LinkedList<T> 类型扩展 Equatable<LinkedList<T>> 接口,支持判等操作。
父类型:
- Equatable<LinkedList<T>>
operator func ==(LinkedList<T>)
public operator func ==(right: LinkedList<T>): Bool
功能:判断当前实例与参数指向的 LinkedList<T> 实例是否相等。
两个 LinkedList<T> 相等指的是其中包含的元素完全相等。
参数:
- right: LinkedList<T> - 被比较的对象。
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
operator func !=(LinkedList<T>)
public operator func !=(right: LinkedList<T>): Bool
功能:判断当前实例与参数指向的 LinkedList<T> 实例是否不等。
参数:
- right: LinkedList<T> - 被比较的对象。
返回值:
- Bool - 如果不等,则返回 true,否则返回 false。
extend<T> LinkedList<T> <: ToString where T <: ToString
extend<T> LinkedList<T> <: ToString where T <: ToString
功能:为 LinkedList<T> 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将当前 LinkedList<T> 实例转换为字符串。
该字符串包含 LinkedList<T> 内每个元素的字符串表示,形如:"[elem1, elem2, elem3]"。
返回值:
- String - 转换得到的字符串。
class TreeMap<K, V> where K <: Comparable<K>
public class TreeMap<K, V> <: OrderedMap<K, V> where K <: Comparable<K> {
public init()
public init(elements: Collection<(K, V)>)
public init(elements: Array<(K,V)>)
public init(size: Int64, initElement: (Int64) -> (K, V))
}
功能:基于平衡二叉搜索树实现的 OrderedMap 接口实例。
这个类的主要目的是提供一个有序的 key-value 存储结构,它可以快速地插入、删除、查找元素。
TreeMap 可以用于任何需要有序键值对存储的场景,例如数据库、缓存、查找表等。
父类型:
- OrderedMap<K, V>
prop first
public prop first: ?(K, V)
功能:获取 TreeMap 的第一个元素。
返回值:
prop last
public prop last: ?(K, V)
功能:获取 TreeMap 的最后一个元素。
返回值:
prop size
public prop size: Int64
功能:返回键值的个数。
类型:Int64
init()
public init()
功能:构造一个空的 TreeMap。
init(Array<(K,V)>)
public init(elements: Array<(K,V)>)
功能:通过传入的键值对数组构造一个 TreeMap。
按照 elements 的先后顺序将元素插入到 TreeMap 内,由于 TreeMap 中不允许出现相同的键,如果 elements 中有相同的键时,后出现的键值对将会覆盖先出现的键值对。
参数:
init(Collection<(K, V)>)
public init(elements: Collection<(K, V)>)
功能:通过传入的键值对集合构造一个 TreeMap。
按照 elements 的迭代器顺序将元素插入到 TreeMap 内,由于 TreeMap 中不允许出现相同的键,如果 elements 中有相同的键时,后出现(迭代器顺序)的键值对将会覆盖先出现的键值对。
参数:
- elements: Collection<(K, V)> - 初始化该 TreeMap 的键值对集合。
init(Int64, (Int64) -> (K, V))
public init(size: Int64, initElement: (Int64) -> (K, V))
功能:通过传入的元素个数 size 和函数规则来构造 TreeMap。
参数:
异常:
- IllegalArgumentException - 如果 size 小于 0 则抛出异常。
func add(K, V)
public func add(key: K, value: V): Option<V>
功能:将新的键值对放入 TreeMap 中。对于 TreeMap 中已有的键,该键的值将被新值替换。
参数:
- key: K - 要放置的键。
- value: V - 要分配的值。
返回值:
func add(Collection<(K, V)>)
public func add(all!: Collection<(K, V)>): Unit
功能:将新的键值对集合放入 TreeMap 中。对于 TreeMap 中已有的键,该键的值将被新值替换。
参数:
- all!: Collection<(K, V)> - 需要添加进 TreeMap 的键值对集合。
func backward(K, Bool)
public func backward(mark: K, inclusive!: Bool = true): Iterator<(K, V)>
功能:获取从第一个键小于等于 mark 的节点按降序遍历到 first 的迭代器。如果该节点的键等于 mark ,那么根据 inclusive! 确定是否包含该键对应的节点。
参数:
- mark: K - 用于确定从哪里开始的键。
- inclusive!: Bool - 当
mark是迭代器的首个元素的 key 时,指定是否包含 mark 作为起始点,默认为true。
返回值:
- Iterator<(K, V)> - 对应元素的迭代器。
func clear()
public func clear(): Unit
功能:清除所有键值对。
func clone()
public func clone(): TreeMap<K, V>
功能:克隆 TreeMap。
返回值:
func contains(K)
public func contains(key: K): Bool
功能:判断是否包含指定键的映射。
参数:
- key: K - 传递要判断的 key。
返回值:
- Bool - 如果存在,则返回 true;否则,返回 false。
func contains(Collection<K>)
public func contains(all!: Collection<K>): Bool
功能:判断是否包含指定集合键的映射。
参数:
- all!: Collection<K> - 键的集合。
返回值:
- Bool - 如果存在,则返回 true;否则,返回 false。
func entryView(K)
public func entryView(k: K): MapEntryView<K, V>
功能:如果不包含特定键,返回一个空的引用视图。如果包含特定键,则返回该键对应的元素的引用视图。
参数:
- k: K - 要添加的键值对的键。
返回值:
- MapEntryView<K, V> - 一个引用视图。
func forward(K, Bool)
public func forward(mark: K, inclusive!: Bool = true): Iterator<(K, V)>
功能:获取从第一个键大于等于 mark 的节点按升序遍历到 last 结束的一个迭代器。如果该节点的键等于 mark ,那么根据 inclusive! 确定是否包含该键对应的节点。
参数:
- mark: K - 用于确定从哪里开始的键。
- inclusive!: Bool - 当
mark是迭代器的首个元素的 key 时,指定是否包含 mark 作为起始点,默认为true。
返回值:
- Iterator<(K, V)> - 对应元素的迭代器。
func get(K)
public func get(key: K): ?V
功能:返回指定键映射的值。
参数:
- key: K - 指定的键。
返回值:
func isEmpty()
public func isEmpty(): Bool
功能:判断 TreeMap 是否为空。
返回值:
- Bool - 如果为空,返回 true,否则返回 false。
func iterator()
public func iterator(): Iterator<(K, V)>
功能:返回 TreeMap 的迭代器,迭代器按 Key 值从小到大的顺序迭代。
返回值:
func keys()
public func keys(): EquatableCollection<K>
功能:返回 TreeMap 中所有的 key,并将所有 key 存储在一个容器中。
返回值:
- EquatableCollection<K> - 包含所有键的集合。
func removeFirst()
public func removeFirst(): ?(K, V)
功能:删除 TreeMap 的第一个元素。
返回值:
func removeLast()
public func removeLast(): ?(K, V)
功能:删除 TreeMap 的最后一个元素。
返回值:
func remove(K)
public func remove(key: K): Option<V>
功能:从此映射中删除指定键的映射(如果存在)。
参数:
- key: K - 传入要删除的 key。
返回值:
func remove(Collection<K>)
public func remove(all!: Collection<K>): Unit
功能:从此映射中删除指定集合的映射(如果存在)。
参数:
- all!: Collection<K> - 传入要删除的键的集合。
func removeIf((K, V) -> Bool)
public func removeIf(predicate: (K, V) -> Bool): Unit
功能:传入 lambda 表达式,如果满足条件,则删除对应的键值。
参数:
- predicate: (K, V) ->Bool - 传递一个 lambda 表达式进行判断。
异常:
- ConcurrentModificationException - 当
predicate中增删或者修改 TreeMap 内键值对时,抛出异常。
func values()
public func values(): Collection<V>
功能:返回 TreeMap 中包含的值,并将所有的 value 存储在一个容器中。
返回值:
- Collection<V> - 包含所有值的集合。
operator func [](K, V)
public operator func [](key: K, value!: V): Unit
功能:运算符重载集合,如果键存在,新 value 覆盖旧 value,如果键不存在,添加此键值对。
参数:
- key: K - 传递值进行判断。
- value!: V - 传递要设置的值。
operator func [](K)
public operator func [](key: K): V
功能:运算符重载集合,如果键存在,返回键对应的值。
参数:
- key: K - 传递值进行判断。
返回值:
- V - 与键对应的值。
异常:
- NoneValueException - 如果该 HashMap 不存在该键,抛出异常。
extend<K, V> TreeMap<K, V> <: Equatable<TreeMap<K, V>> where V <: Equatable<V>
extend<K, V> TreeMap<K, V> <: Equatable<TreeMap<K, V>> where V <: Equatable<V>
功能:为 TreeMap<K, V> 类型扩展 Equatable<TreeMap<K, V>> 接口,支持判等操作。
父类型:
operator func ==(TreeMap<K, V>)
public operator func ==(right: TreeMap<K, V>): Bool
功能:判断当前实例与参数指向的 TreeMap<K, V> 实例是否相等。
两个 TreeMap<K, V> 相等指的是其中包含的键值对完全相等。
参数:
- right: TreeMap<K, V> - 被比较的对象。
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
operator func !=(TreeMap<K, V>)
public operator func !=(right: TreeMap<K, V>): Bool
功能:判断当前实例与参数指向的 TreeMap<K, V> 实例是否不等。
参数:
- right: TreeMap<K, V> - 被比较的对象。
返回值:
- Bool - 如果不等,则返回 true,否则返回 false。
extend<K, V> TreeMap<K, V> <: ToString where V <: ToString, K <: ToString & Comparable<K>
extend<K, V> TreeMap<K, V> <: ToString where V <: ToString, K <: ToString & Comparable<K>
功能:为 TreeMap<K, V> 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将当前 TreeMap<K, V> 实例转换为字符串。
该字符串包含 TreeMap<K, V> 内每个键值对的字符串表示,形如:"[(k1, v1), (k2, v2), (k3, v3)]"。
返回值:
- String - 转换得到的字符串。
class TreeSet<T> where T <: Comparable<T>
public class TreeSet<T> <: OrderedSet<T> where T <: Comparable<T> {
public init()
public init(elements: Collection<T>)
public init(size: Int64, initElement: (Int64) -> T)
}
这个类的主要目的是提供一个有序的元素存储结构,它可以快速地插入、删除、查找元素。
TreeSet 可以用于任何需要有序元素存储的场景,例如数据库、缓存、查找表等。
父类型:
- OrderedSet<T>
prop first
public prop first: ?T
功能:获取 TreeSet 的第一个元素。
类型:?T - 如果存在第一个元素,用 Option 封装该元素并返回;否则返回 Option<T>.None。
prop last
public prop last: ?T
功能:获取 TreeSet 的最后一个元素。
类型:?T - 如果存在最后一个元素,用 Option 封装该元素并返回;否则返回 Option<T>.None。
prop size
public prop size: Int64
功能:返回元素的个数。
类型:Int64
init()
public init()
功能:构造一个空的 TreeSet。
init(Collection<T>)
public init(elements: Collection<T>)
功能:通过传入的元素集合构造一个 TreeSet。
按照 elements 的迭代器顺序将元素插入到 TreeSet 内,由于 TreeSet 中不允许出现相同的元素,如果 elements 中有多个相同的元素时,TreeSet 只会保留一个元素。
参数:
- elements: Collection<T> - 初始化该 TreeSet 的元素集合。
init(Int64, (Int64) -> T)
public init(size: Int64, initElement: (Int64) -> T)
功能:通过传入的元素个数 size 和函数规则来构造 TreeSet。
参数:
异常:
- IllegalArgumentException - 如果 size 小于 0 则抛出异常。
static func of(Array<T>)
public static func of(elements: Array<T>): TreeSet<T>
功能:构造一个包含指定数组中所有元素的 TreeSet。
按照 elements 的先后顺序将元素插入到 TreeSet 内,由于 TreeSet 中不允许出现相同的元素,如果 elements 中有多个相同的元素时,TreeSet 只会保留一个元素。
参数:
- elements: Array<T> - 传入数组。
返回值:
func add(T)
public func add(element: T): Bool
功能:将新的元素放入 TreeSet 中。若添加的元素在 TreeSet 中存在, 则添加失败。
参数:
- element: T - 指定的元素。
返回值:
- Bool - 如果添加成功,则返回 true;否则,返回 false。
func add(Collection<T>)
public func add(all!: Collection<T>): Unit
功能:添加 Collection 中的所有元素至此 TreeSet 中,如果元素存在,则不添加。
参数:
- all!: Collection<T> - 需要被添加的元素的集合。
func backward(T, Bool)
public func backward(mark: T, inclusive!: Bool = true): Iterator<T>
功能:获取从第一个键小于等于 mark 的节点按降序遍历到 first 的迭代器。如果该节点的键等于 mark ,那么根据 inclusive! 确定是否包含该键对应的节点。
参数:
- mark: T - 用于确定从哪里开始的元素。
- inclusive!: Bool - 当
mark是迭代器的首个元素时,指定是否包含 mark 作为起始点,默认为true。
返回值:
- Iterator<T> - 对应元素的迭代器。
func clear()
public func clear(): Unit
功能:清除所有元素。
func clone()
public func clone(): TreeSet<T>
功能:克隆 TreeSet。
返回值:
func contains(T)
public func contains(element: T): Bool
功能:判断是否包含指定元素。
参数:
- element: T - 指定的元素。
返回值:
- Bool - 如果包含指定元素,则返回 true;否则,返回 false。
func contains(Collection<T>)
public func contains(all!: Collection<T>): Bool
功能:判断 TreeSet 是否包含指定 Collection 中的所有元素。
参数:
- all!: Collection<T> - 指定的元素集合。
返回值:
- Bool - 如果此 TreeSet 包含 Collection 中的所有元素,则返回 true;否则,返回 false。
func forward(T, Bool)
public func forward(mark: T, inclusive!: Bool = true): Iterator<T>
功能:获取从第一个元素大于等于 mark 的节点按升序遍历到 last 结束的一个迭代器。如果该节点的元素等于 mark ,那么根据 inclusive! 确定是否包含该元素对应的节点。
参数:
- mark: T - 用于确定从哪里开始的元素。
- inclusive!: Bool - 当
mark是迭代器的首个元素时,指定是否包含 mark 作为起始点,默认为true。
返回值:
- Iterator<T> - 对应元素的迭代器。
func isEmpty()
public func isEmpty(): Bool
功能:判断 TreeSet 是否为空。
返回值:
- Bool - 如果为空,返回 true,否则返回 false。
func iterator()
public func iterator(): Iterator<T>
功能:返回 TreeSet 的迭代器,迭代器按元素值从小到大的顺序迭代。
返回值:
func removeFirst()
public func removeFirst(): ?T
功能:删除 TreeSet 的第一个元素。
返回值:
func removeLast()
public func removeLast(): ?T
功能:删除 TreeSet 的最后一个元素。
返回值:
func remove(T)
public func remove(element: T): Bool
功能:如果指定元素存在于此 TreeSet 中,则将其移除。
参数:
- element: T - 需要被移除的元素。
返回值:
- Bool - true,表示移除成功;false,表示移除失败。
func remove(Collection<T>)
public func remove(all!: Collection<T>): Unit
功能:移除此 TreeSet 中那些也包含在指定 Collection 中的所有元素。
参数:
- all!: Collection<T> - 需要从此TreeSet 中移除的元素的集合。
func removeIf((T) -> Bool)
public func removeIf(predicate: (T) -> Bool): Unit
功能:传入 lambda 表达式,如果满足 true 条件,则删除对应的元素。
参数:
- predicate: (T) ->Bool - 是否删除元素的判断条件。
异常:
- ConcurrentModificationException - 当
predicate中增删或者修改 TreeSet 内元素时,抛出异常。
func retain(Set<T>)
public func retain(all!: Set<T>): Unit
功能:从此 TreeSet 中保留 Set 中的元素,其他元素将被移除。
参数:
func subsetOf(ReadOnlySet<T>)
public func subsetOf(other: ReadOnlySet<T>): Bool
功能:检查该集合是否为其他 ReadOnlySet 的子集。
参数:
- other: ReadOnlySet<T> - 传入集合,此函数将判断当前集合是否为 other 的子集。
返回值:
- Bool - 如果该 TreeSet 是指定 ReadOnlySet 的子集,则返回 true;否则返回 false。
func toArray()
public func toArray(): Array<T>
功能:返回一个包含容器内所有元素的数组。
返回值:
- Array<T> - T 类型数组。
operator func &(ReadOnlySet<T>)
public operator func &(other: ReadOnlySet<T>): TreeSet<T>
功能:返回包含两个集合交集的元素的新集合。
参数:
- other: ReadOnlySet<T> - 传入集合。
返回值:
- TreeSet<T> - T 类型集合。
operator func |(ReadOnlySet<T>)
public operator func |(other: ReadOnlySet<T>): TreeSet<T>
功能:返回包含两个集合并集的元素的新集合。
参数:
- other: ReadOnlySet<T> - 传入集合。
返回值:
- TreeSet<T> - T 类型集合。
operator func -(ReadOnlySet<T>)
public operator func -(other: ReadOnlySet<T>): TreeSet<T>
功能:返回包含两个集合差集的元素的新集合。
参数:
- other: ReadOnlySet<T> - 传入集合。
返回值:
- TreeSet<T> - T 类型集合。
extend<T> TreeSet<T> <: Equatable<TreeSet<T>>
extend<T> TreeSet<T> <: Equatable<TreeSet<T>>
功能:为 TreeSet<T> 类型扩展 Equatable<TreeSet<T>> 接口,支持判等操作。
父类型:
operator func ==(TreeSet<T>)
public operator func ==(that: TreeSet<T>): Bool
功能:判断当前实例与参数指向的 TreeSet<T> 实例是否相等。
两个 TreeSet<T> 相等指的是其中包含的元素完全相等。
参数:
- that: TreeSet<T> - 被比较的对象。
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
operator func !=(TreeSet<T>)
public operator func !=(that: TreeSet<T>): Bool
功能:判断当前实例与参数指向的 TreeSet<T> 实例是否不等。
参数:
- that: TreeSet<T> - 被比较的对象。
返回值:
- Bool - 如果不等,则返回 true,否则返回 false。
extend<T> TreeSet<T> <: ToString where T <: ToString
extend<T> TreeSet<T> <: ToString where T <: ToString
功能:为 TreeSet<T> 扩展 ToString 接口,支持转字符串操作。
父类型:
func toString()
public func toString(): String
功能:将当前 TreeSet<T> 实例转换为字符串。
该字符串包含 TreeSet<T> 内每个元素的字符串表示,形如:"[elem1, elem2, elem3]"。
返回值:
- String - 转换得到的字符串。
异常
class ConcurrentModificationException
public class ConcurrentModificationException <: Exception {
public init()
public init(message: String)
}
功能:并发修改异常类。当函数检测到不同步的并发修改,抛出异常。
由于 collection 包提供的容器类都不支持并发修改,因此在执行某些操作时,会抛出 ConcurrentModificationException。
典型的抛出异常场景有:
- 使用 for-in 遍历一个容器过程中对容器进行修改时(HashMapIterator的remove() 方法除外)。
- 在使用声明周期较短的类型,如 MapEntryView 时,如果其所在的容器内容被修改,也会抛出异常。
父类型:
init()
public init()
功能:构造一个不带异常信息的实例。
init(String)
public init(message: String)
功能:根据异常信息构造异常实例。
参数:
- message: String - 异常信息。
ArrayList 的 add 函数
ArrayList 中添加元素的方法如下:
import std.collection.*
main() {
var list: ArrayList<Int64> = ArrayList<Int64>(10) // 创建一个容量为 10 的 ArrayList
var arr: Array<Int64> = [1, 2, 3]
list.add(all: arr) // list: [1, 2, 3]
list[1] = 120 // list: [1, 120, 3]
var b = list.get(2)
print("b=${b.getOrThrow()},")
list.add(12, at: 1) // list: [1, 12, 120, 3]
var c = list.get(2)
print("c=${c.getOrThrow()},")
var arr1: Array<Int64> = [1,2,3]
list.add(all: arr1, at: 1) // list: [1, 1, 2, 3, 12, 120, 3]
var d = list.get(2)
print("d=${d.getOrThrow()}")
return 0
}
运行结果:
b=3,c=120,d=2
ArrayList 的 get/set 函数
此用例展示了如何使用 get 方法获取 ArrayList 中对应索引的值,以及如何修改值。
代码如下:
import std.collection.*
main() {
var list = ArrayList<Int64>([97, 100]) // list: [97, 100]
// 修改值
list[1] = 120 // list: [97, 120]
// 获取值
var b = list.get(1)
print("b=${b.getOrThrow()}")
return 0
}
运行结果:
b=120
ArrayList 的 remove/clear/slice 函数
此用例展示了 ArrayList 的 remove/clear/slice 函数的使用方法。
代码如下:
import std.collection.*
main() {
var list: ArrayList<Int64> = ArrayList<Int64>([97, 100, 99]) // Function call syntactic sugar of variable-length
list.remove(at: 1) // list: [97, 99]
var b = list.get(1)
print("b=${b.getOrThrow()},")
list.clear()
list.add(11) // list: [97, 99, 11]
var arr: Array<Int64> = [1, 2, 3]
list.add(all: arr, at: 0) // list: [1, 2, 3, 97, 99]
var g = list.get(0)
print("g=${g.getOrThrow()},")
let r: Range<Int64> = 1..=2 : 1
var sublist: ArrayList<Int64> = list.slice(r) // sublist: [2, 3]
var m = sublist.get(0)
print("m=${m.getOrThrow()}")
return 0
}
运行结果:
b=99,g=1,m=2
HashMap 的 get/add/contains 函数
此用例展示了 HashMap 的基本使用方法。
代码如下:
import std.collection.*
main() {
var map: HashMap<String, Int64> = HashMap<String, Int64>()
map.add("a", 99) // map : [("a", 99)]
map.add("b", 100) // map : [("a", 99), ("b", 100)]
var a = map.get("a")
var bool = map.contains("a")
print("a=${a.getOrThrow()} ")
print("bool=${bool.toString()}")
return 0
}
运行结果:
a=99 bool=true
HashMap 的 add/remove/clear 函数
此用例展示了 HashMap 的基本使用方法。
代码如下:
import std.collection.*
main() {
var map: HashMap<String, Int64> = HashMap<String, Int64>()
var arr: Array<(String, Int64)> = [("d", 11), ("e", 12)]
map.add("a", 13)
print("a=${map.get("a").getOrThrow()} ")
map.add(all: arr) // map : [("d", 11), ("e", 12)]
var d = map.get("d")
print("d=${d.getOrThrow()} ")
map.remove("d") // map : [("e", 12)]
var bool = map.contains("d")
print("bool=${bool.toString()} ")
map.clear() // map: []
var bool1 = map.contains("e")
print("bool1=${bool1.toString()}")
return 0
}
运行结果:
a=13 d=11 bool=false bool1=false
HashSet 的 add/iterator/remove 函数
此用例展示了 HashSet 的基本使用方法。
代码如下:
import std.collection.*
/* 测试 */
main() {
var set: HashSet<String> = HashSet<String>() // set: []
set.add("apple") // set: ["apple"]
set.add("banana") // set: ["apple", "banana"], not in order
set.add("orange") // set: ["apple", "banana", "orange"], not in order
set.add("peach") // set: ["apple", "banana", "orange", "peach"], not in order
var itset = set.iterator()
while(true) {
var value = itset.next()
match(value) {
case Some(v) =>
if (!set.contains(v)) {
print("Operation failed")
return 1
} else { println(v) }
case None => break
}
}
set.remove("apple") // set: ["banana", "orange", "peach"], not in order
println(set)
return 0
}
由于 Set 中的顺序不是固定的,因此运行结果可能如下:
apple
banana
orange
peach
[banana, orange, peach]
TreeSet 的 add/iterator/remove 函数
此用例展示了 TreeSet 的基本使用方法。
代码如下:
import std.collection.*
/* 测试 */
main() {
var set: TreeSet<String> = TreeSet<String>()
set.add("peach")
set.add("banana")
set.add("apple")
set.add("orange")
var itset = set.iterator()
for (e in itset) {
println(e)
}
set.remove("banana")
println(set)
return 0
}
运行结果:
apple
banana
orange
peach
[apple, orange, peach]
迭代器操作函数
此用例展示了迭代器操作函数结合 pipeline 表达式的使用方法。
代码如下:
import std.collection.*
main() {
let arr = [-1, 2, 3, 4, 5, 6, 7, 8, 9]
arr |> filter{a: Int64 => a > 0} |> // filter -1
step<Int64>(2) |> // [2, 4, 6, 8]
skip<Int64>(2) |> // [6, 8]
forEach<Int64>(println)
let str = arr |> filter{a: Int64 => a % 2 == 1} |> collectString<Int64>(delimiter: ">")
println(str)
println(arr |> contains(6_i64))
return 0
}
运行结果:
6
8
3>5>7>9
true
std.collection.concurrent
功能介绍
collection.concurrent 包提供了并发安全的集合类型实现。
本包实现了以下几种并发安全的集合类型:
-
ArrayBlockingQueue:以数组的形式实现的具有固定大小的有界队列。
-
ConcurrentHashMap:线程安全的哈希表实现,支持高并发的读写操作。
-
ConcurrentLinkedQueue:一种线程安全的队列数据结构,特点是在添加元素时,如果当前的尾部 Block 已满,那么会创建一个新的 Block,而不是阻塞等待。这样可以保证在多线程环境下,队列的操作不会因为阻塞而导致线程的阻塞,从而提高了程序的性能。
-
LinkedBlockingQueue:一种阻塞队列,它支持在队列为空时阻塞获取元素的操作,以及在队列已满时阻塞添加元素的操作。
API 列表
类型别名
| 类型别名 | 功能 |
|---|---|
| BlockingQueue<E> (deprecated) | LinkedBlockingQueue 的别名。 |
| NonBlockingQueue<E> (deprecated) | ConcurrentLinkedQueue 的别名。 |
接口
| 接口名 | 功能 |
|---|---|
| ConcurrentMap<K, V> | 保证线程安全和操作原子性的 Map 接口定义。 |
类
| 类名 | 功能 |
|---|---|
| ArrayBlockingQueue<E> | 基于数组实现的 Blocking Queue 数据结构及相关操作函数。 |
| ConcurrentHashMapIterator<K, V> where K <: Hashable & Equatable<K> | 此类主要实现 Concurrent HashMap 的迭代器功能。 |
| ConcurrentHashMap<K, V> where K <: Hashable & Equatable<K> | 此类用于实现并发场景下线程安全的哈希表 ConcurrentHashMap 数据结构及相关操作函数。 |
| ConcurrentLinkedQueue<E> | 提供一个线程安全的队列,可以在多线程环境下安全地进行元素的添加和删除操作。 |
| LinkedBlockingQueue<E> | 实现是带阻塞机制并支持用户指定容量上界的并发队列。 |
类型别名
type BlockingQueue<E> (deprecated)
public type BlockingQueue<E> = LinkedBlockingQueue<E>
功能:LinkedBlockingQueue<E> 的别名。
注意:
未来版本即将废弃,使用 LinkedBlockingQueue<E> 替代。
type NonBlockingQueue<E> (deprecated)
public type NonBlockingQueue<E> = ConcurrentLinkedQueue<E>
功能:ConcurrentLinkedQueue<E> 的别名。
注意:
未来版本即将废弃,使用 ConcurrentLinkedQueue<E> 替代。
接口
interface ConcurrentMap<K, V>
public interface ConcurrentMap<K, V> {
func add(key: K, value: V): ?V
func addIfAbsent(key: K, value: V): ?V
func entryView(key: K, fn: (MapEntryView<K, V>) -> Unit): ?V
func get(key: K): ?V
func contains(key: K): Bool
func put(key: K, value: V): ?V
func putIfAbsent(key: K, value: V): ?V
func remove(key: K): ?V
func remove(key: K, predicate: (V) -> Bool): ?V
func replace(key: K, value: V): ?V
func replace(key: K, eval: (V) -> V): ?V
func replace(key: K, predicate: (V) -> Bool, eval: (V) -> V): ?V
operator func [](key: K): V
operator func [](key: K, value!: V): Unit
}
功能:保证线程安全和操作原子性的 Map 接口定义。
ConcurrentMap 接口中声明了并发场景下线程安全的 Map 必须保证原子性的方法,我们希望定义的线程安全 Map 类都能实现 ConcurrentMap 接口。例如我们在该包中定义的 ConcurrentHashMap 就实现了 ConcurrentMap 接口,并提供了 ConcurrentMap 中所声明方法的保证原子性的实现。
ConcurrentMap 接口中声明了并发 Map 在并发场景下需要保证原子性的方法。
并发 Map 为“键”到“值”的映射,其中 K 为键的类型,V 为值的类型。
func add(K, V)
func add(key: K, value: V): ?V
功能:将指定的值 value 与此 Map 中指定的键 key 关联。如果 Map 中已经包含键 key 的关联,则旧值将被替换;如果 Map 中不包含键 key 的关联,则添加键 key 与值 value 的关联。
参数:
- key: K - 要放置的键。
- value: V - 要关联的值。
返回值:
- ?V - 如果赋值之前 key 存在,则返回旧的值 Some(V);当赋值前 key 不存在时,返回 None。
func addIfAbsent(K, V)
func addIfAbsent(key: K, value: V): ?V
功能:当此 Map 中不存在键 key 时,在 Map 中添加指定的值 value 与指定的键 key 的关联。如果 Map 已经包含键 key,则不执行赋值操作。
参数:
- key: K - 要放置的键。
- value: V - 要分配的值。
返回值:
- ?V - 如果赋值之前 key 存在,则返回当前 key 对应的值 Some(V),且不执行赋值操作;当赋值前 key 不存在时,返回 None。
func contains(K)
func contains(key: K): Bool
功能:判断 Map 中是否包含指定键 key 的关联。
参数:
- key: K - 传递要判断的 key。
返回值:
- Bool - 当 key 存在时返回 true;当 key 不存在时返回 false。
func entryView(K, (MapEntryView<K, V>) -> Unit)
func entryView(key: K, fn: (MapEntryView<K, V>) -> Unit): ?V
功能:根据指定键 key 获取当前映射中相应的键值对视图 entryView,并调用函数 fn 对该键值对进行增、删、改操作,并返回最终映射中键 key 对应的值。
如果当前映射中不包含键 key,则将获取一个空视图 entryView,如果将其 value 置为非 None 值,则将在当前映射中增加 key-value 键值对。
如果当前映射中包含键 key,则将获取 key-value 的视图,如果将 value 置为 None,则相当于从当前映射中删除该键值对;如果将 value 置为新的非 None 值,则相当于修改当前映射中键 key 对应的值。
参数:
- key: K - 待获取其相应视图的键。
- fn: (MapEntryView<K, V>) -> Unit - 对指定视图进行的自定义操作,可用于对映射中键值对进行增、删、改操作。
返回值:
- ?V - 函数 fn 调用结束后当前映射中键 key 对应的值,如果 key 不存在,返回 None。
func get(K)
func get(key: K): ?V
功能:返回 Map 中键 key 所关联的值。
参数:
- key: K - 传递 key,获取 value。
返回值:
- ?V - 当 key 存在时,返回其关联的值 Some(V);当 key 不存在时,返回 None。
func put(K, V) (deprecated)
func put(key: K, value: V): ?V
功能:将指定的值 value 与此 Map 中指定的键 key 关联。如果 Map 中已经包含键 key 的关联,则旧值将被替换;如果 Map 中不包含键 key 的关联,则添加键 key 与值 value 的关联。
注意:
未来版本即将废弃,使用 add(K, V) 替代。
参数:
- key: K - 要放置的键。
- value: V - 要关联的值。
返回值:
- ?V - 如果赋值之前 key 存在,则返回旧的值 Some(V);当赋值前 key 不存在时,返回 None。
func putIfAbsent(K, V) (deprecated)
func putIfAbsent(key: K, value: V): ?V
功能:当此 Map 中不存在键 key 时,在 Map 中添加指定的值 value 与指定的键 key 的关联。如果 Map 已经包含键 key,则不执行赋值操作。
注意:
未来版本即将废弃,使用 addIfAbsent(K, V) 替代。
参数:
- key: K - 要放置的键。
- value: V - 要分配的值。
返回值:
- ?V - 如果赋值之前 key 存在,则返回当前 key 对应的值 Some(V),且不执行赋值操作;当赋值前 key 不存在时,返回 None。
func remove(K)
func remove(key: K): ?V
功能:从此映射中删除指定键 key 的映射(如果存在)。
参数:
- key: K - 传入要删除的 key。
返回值:
- ?V - 如果移除之前 key 存在,则返回 key 对应的值 Some(V);当移除时 key 不存在时,返回 None。
func remove(K, (V) -> Bool) (deprecated)
func remove(key: K, predicate: (V) -> Bool): ?V
功能:如果 Map 中存在键 key 且 key 所关联的值 v 满足条件 predicate,则从 Map 中删除 key 的关联。
注意:
未来版本即将废弃,使用 entryView(K, (MapEntryView<K, V>) -> Unit) 替代。
参数:
- key: K - 传入要删除的 key。
- predicate: (V) ->Bool - 传递一个 lambda 表达式进行判断。
返回值:
func replace(K, (V) -> Bool, (V) -> V) (deprecated)
func replace(key: K, predicate: (V) -> Bool, eval: (V) -> V): ?V
功能:如果 Map 中存在键 key(假设其关联的值为 v),且 v 满足条件 predicate,则将 Map 中键 key 关联的值替换为 eval(v) 的计算结果;如果 Map 中不存在键 key,或者存在键 key 但关联的值不满足 predicate,则不对 Map 做任何修改。
注意:
未来版本即将废弃,使用 entryView(K, (MapEntryView<K, V>) -> Unit) 替代。
参数:
- key: K - 传入要替换所关联值的键。
- predicate: (V) ->Bool - 传递一个 lambda 表达式进行判断。
- eval: (V) ->V - 传入计算用于替换的新值的函数。
返回值:
- ?V - 如果 key 存在,则返回 key 对应的旧值 Some(V);当 key 不存在时,或者 key 关联的值不满足 predicate 时,返回 None。
func replace(K, (V) -> V) (deprecated)
func replace(key: K, eval: (V) -> V): ?V
功能:如果 Map 中存在键 key(假设其关联的值为 v),则将 Map 中键 key 关联的值替换为 eval(v) 的计算结果;如果 Map 中不存在键 key,则不对 Map 做任何修改。
注意:
未来版本即将废弃,使用 entryView(K, (MapEntryView<K, V>) -> Unit) 替代。
参数:
- key: K - 传入要替换所关联值的键。
- eval: (V) ->V - 传入计算用于替换的新值的函数。
返回值:
- ?V - 如果 key 存在,则返回 key 对应的旧值 Some(V);当 key 不存在时,返回 None。
func replace(K, V)
func replace(key: K, value: V): ?V
功能:如果 Map 中存在 key,则将 Map 中键 key 关联的值替换为 value;如果 Map 中不存在 key,则不对 Map 做任何修改。
参数:
- key: K - 传入要替换所关联值的键。
- value: V - 传入要替换成的新值。
返回值:
- ?V - 如果 key 存在,则返回 key 对应的旧值 Some(V);当 key 不存在时,返回 None。
operator func [](K)
operator func [](key: K): V
功能:根据指定键 key 获取值。如果键 key 存在,返回对应的值;如果不存在,抛出异常。
参数:
- key: K - 待获取其值的键。
返回值:
- V - 键 key 对应的值。
异常:
- NoneValueException - 当前映射中不存在键 key。
operator func [](K, V)
operator func [](key: K, value!: V): Unit
功能:设置指定键 key 的值为 value。如果键 key 存在,新 value 覆盖旧 value;如果键不存在,添加此键值对。
参数:
- key: K - 待设置其值的键。
- value!: V - 待设置的值。
类
class ArrayBlockingQueue<E>
public class ArrayBlockingQueue<E> {
public let capacity: Int64
public init(capacity: Int64)
public init(capacity: Int64, elements: Collection<E>)
}
功能:基于数组实现的 Blocking Queue 数据结构及相关操作函数。
ArrayBlockingQueue 是带阻塞机制且需要用户指定容量上界的并发队列。
prop size
public prop size: Int64
功能:返回此 ArrayBlockingQueue 的元素个数。
注意:
此方法不保证并发场景下的原子性,建议在环境中没有其他线程并发地修改 ArrayBlockingQueue 时调用。
类型:Int64
let capacity
public let capacity: Int64
功能:此 ArrayBlockingQueue 的容量。
类型:Int64
init(Int64)
public init(capacity: Int64)
功能:构造一个带有传入容量大小的 ArrayBlockingQueue。
参数:
- capacity: Int64 - 初始化容量大小。
异常:
- IllegalArgumentException - 如果 capacity 小于等于 0 则抛出异常。
init(Int64, Collection<E>) (deprecated)
public init(capacity: Int64, elements: Collection<E>)
功能:构造一个带有传入容量大小,并带有传入迭代器的 ArrayBlockingQueue。
注意:
未来版本即将废弃,同等功能替代写法为:创建空队列,再将 elements 中元素依次添加到队列中。
参数:
- capacity: Int64 - 初始化容量大小。
- elements: Collection<E> - 初始化迭代器元素。
异常:
- IllegalArgumentException - 如果 capacity 小于等于 0 或小于迭代器元素 elements 的 size 则抛出异常。
func add(E)
public func add(element: E): Unit
功能:阻塞的入队操作,将元素添加到队列尾部。如果队列已满,则阻塞等待。
参数:
- element: E - 要添加的元素。
示例:
import std.collection.concurrent.*
main() {
var blockArr: ArrayBlockingQueue<Int64> = ArrayBlockingQueue<Int64>(2)
blockArr.add(10)
println(blockArr.peek())
}
运行结果:
Some(10)
func add(E, Duration)
public func add(element: E, timeout: Duration): Bool
功能:阻塞的入队操作,将元素添加到队列尾部,如果队列满了,将等待指定的时间。如果 timeout 为负,则会立即执行入队操作并且返回操作结果。
参数:
- element: E - 要添加的元素。
- timeout: Duration - 等待时间。
返回值:
- Bool - 成功添加元素返回 true,超出等待时间还未成功添加元素返回 false。
示例:
import std.collection.concurrent.*
import std.sync.*
import std.time.*
main() {
let blockArr: ArrayBlockingQueue<Int64> = ArrayBlockingQueue<Int64>(2)
/* 创建新线程,填满阻塞队列,休眠 1 秒后移除阻塞队列队首元素 */
spawn {
=>
blockArr.add(0)
blockArr.add(1)
sleep(1000 * Duration.millisecond)
println("New thread moves out of blocked queue head element.")
blockArr.remove()
}
/* 主线程立即让出执行权,唤醒后阻塞的添加 */
sleep(-1 * Duration.millisecond)
println("The main thread is woken up.")
let isSuccess: Bool = blockArr.add(2, 2000 * Duration.millisecond)
println(isSuccess)
}
运行结果:
The main thread is woken up.
New thread moves out of blocked queue head element.
true
func dequeue() (deprecated)
public func dequeue(): E
功能:阻塞的出队操作,获得队首元素并删除。
注意:
未来版本即将废弃,使用 remove() 替代。
返回值:
- E - 返回队首元素。
func dequeue(Duration) (deprecated)
public func dequeue(timeout: Duration): Option<E>
功能:阻塞的出队操作,获得队首元素并删除,如果队列为空,将等待指定的时间。如果 timeout 为负,则会立即执行出队操作并且返回操作结果。
注意:
未来版本即将废弃,使用 remove(Duration) 替代。
参数:
- timeout: Duration - 等待时间。
返回值:
- Option<E> - 返回队首元素。如果超出等待时间还未成功获取队首元素,则返回 None。
func enqueue(E) (deprecated)
public func enqueue(element: E): Unit
功能:阻塞的入队操作,将元素添加到队列尾部。
注意:
未来版本即将废弃,使用 add(E) 替代。
参数:
- element: E - 要添加的元素。
func enqueue(E, Duration) (deprecated)
public func enqueue(element: E, timeout: Duration): Bool
功能:阻塞的入队操作,将元素添加到队列尾部,如果队列满了,将等待指定的时间。如果 timeout 为负,则会立即执行入队操作并且返回操作结果。
注意:
未来版本即将废弃,使用 add(E, Duration) 替代。
参数:
- element: E - 要添加的元素。
- timeout: Duration - 等待时间。
返回值:
- Bool - 成功添加元素返回 true,超出等待时间还未成功添加元素返回 false。
func head() (deprecated)
public func head(): Option<E>
功能:获取队首元素。
该函数是非阻塞的。
注意:
未来版本即将废弃,使用 peek() 替代。
返回值:
- Option<E> - 返回队首元素,队列为空时返回 None。
func peek()
public func peek(): Option<E>
功能:非阻塞的获取队首元素。
返回值:
- Option<E> - 返回队首元素,队列为空时返回 None。
示例:
import std.collection.concurrent.*
main() {
let blockArr: ArrayBlockingQueue<Int64> = ArrayBlockingQueue<Int64>(2)
blockArr.add(2)
blockArr.add(3)
println(blockArr.peek())
}
运行结果:
Some(2)
func remove()
public func remove(): E
功能:阻塞的出队操作,获得队首元素并删除。如果队列为空,则阻塞等待。
返回值:
- E - 返回队首元素。
示例:
import std.collection.concurrent.*
main() {
let blockArr: ArrayBlockingQueue<Int64> = ArrayBlockingQueue<Int64>(2)
blockArr.add(2)
blockArr.add(3)
println(blockArr.remove())
println(blockArr.size)
}
运行结果:
2
1
func remove(Duration)
public func remove(timeout: Duration): Option<E>
功能:阻塞的出队操作,获得队首元素并删除,如果队列为空,将等待指定的时间。如果 timeout 为负,则会立即执行出队操作并且返回操作结果。
参数:
- timeout: Duration - 等待时间。
返回值:
- Option<E> - 返回队首元素。如果超出等待时间还未成功获取队首元素,则返回 None。
示例:
import std.collection.concurrent.*
import std.sync.*
import std.time.*
main() {
let blockArr: ArrayBlockingQueue<Int64> = ArrayBlockingQueue<Int64>(2)
/* 创建新线程,休眠 1 秒后向队列添加元素 */
spawn {
=>
sleep(1000 * Duration.millisecond)
println("This new thread adds new elements to the queue.")
blockArr.add(3)
}
/* 主线程立即让出执行权,唤醒后阻塞的取出队首元素 */
sleep(-1 * Duration.millisecond)
println("The main thread is woken up.")
let num: Option<Int64> = blockArr.remove(2000 * Duration.millisecond)
println(num)
}
运行结果:
The main thread is woken up.
This new thread adds new elements to the queue.
Some(3)
func tryAdd(E)
public func tryAdd(element: E): Bool
功能:非阻塞的入队操作,将元素添加到队列尾部。
参数:
- element: E - 要添加的元素。
返回值:
- Bool - 成功添加返回 true;如果队列满了,添加失败返回 false。
示例:
import std.collection.concurrent.*
main() {
let blockArr: ArrayBlockingQueue<Int64> = ArrayBlockingQueue<Int64>(2)
blockArr.tryAdd(2)
blockArr.tryAdd(3)
println(blockArr.size)
}
运行结果:
2
func tryDequeue() (deprecated)
public func tryDequeue(): Option<E>
功能:非阻塞的出队操作,获得队首元素并删除。
注意:
未来版本即将废弃,使用 tryRemove() 替代。
返回值:
- Option<E> - 返回队首元素,队列为空时返回 None。
func tryEnqueue(E) (deprecated)
public func tryEnqueue(element: E): Bool
功能:非阻塞的入队操作,将元素添加到队列尾部。
注意:
未来版本即将废弃,使用 tryAdd(E) 替代。
参数:
- element: E - 要添加的元素。
返回值:
- Bool - 成功添加返回 true;如果队列满了,添加失败返回 false。
func tryRemove()
public func tryRemove(): Option<E>
功能:非阻塞的出队操作,获得队首元素并删除。
返回值:
- Option<E> - 返回队首元素,队列为空时返回 None。
示例:
import std.collection.concurrent.*
main() {
let blockArr: ArrayBlockingQueue<Int64> = ArrayBlockingQueue<Int64>(2)
blockArr.tryAdd(2)
println(blockArr.tryRemove())
println(blockArr.tryRemove())
}
运行结果:
Some(2)
None
class ConcurrentHashMap<K, V> where K <: Hashable & Equatable<K>
public class ConcurrentHashMap<K, V> <: ConcurrentMap<K, V> & Collection<(K, V)> where K <: Hashable & Equatable<K> {
public init(concurrencyLevel!: Int64 = 16)
public init(capacity: Int64, concurrencyLevel!: Int64 = 16)
public init(elements: Collection<(K, V)>, concurrencyLevel!: Int64 = 16)
public init(size: Int64, initElement: (Int64) -> (K, V), concurrencyLevel!: Int64 = 16)
}
功能:此类用于实现并发场景下线程安全的哈希表 ConcurrentHashMap 数据结构及相关操作函数。
当 ConcurrentHashMap 中出现键值对数量大于“桶”数量的情况时,会进行“扩容”。
构造函数中的参数 concurrencyLevel 表示“并发度”,即:最多允许多少个线程并发修改 ConcurrentHashMap。查询键值对的操作是非阻塞的,不受所指定的并发度 concurrencyLevel 的限制。参数 concurrencyLevel 默认等于 16。它只影响 ConcurrentHashMap 在并发场景下的性能,不影响功能。
注意:
如果用户传入的 concurrencyLevel 小于 16,则并发度会被设置为 16。
concurrencyLevel 并非越大越好,更大的 concurrencyLevel 会导致更大的内存开销(甚至可能导致 out of memory 异常),用户需要在内存开销和运行效率之间进行平衡。
父类型:
- ConcurrentMap<K, V>
- Collection<(K, V)>
示例:
使用示例见 ConcurrentHashMap 使用示例。
prop size
public prop size: Int64
功能:返回键值的个数。
注意:
此方法不保证并发场景下的原子性,建议在环境中没有其他线程并发地修改 ConcurrentHashMap 时调用。
类型:Int64
init(Collection<(K, V)>, Int64)
public init(elements: Collection<(K, V)>, concurrencyLevel!: Int64 = 16)
功能:构造一个带有传入迭代器和指定并发度的 ConcurrentHashMap。该构造函数根据传入迭代器元素 elements 的 size 设置 ConcurrentHashMap 的容量。
参数:
- elements: Collection<(K, V)> - 初始化迭代器元素。
- concurrencyLevel!: Int64 - 用户指定的并发度。
init(Int64)
public init(concurrencyLevel!: Int64 = 16)
功能:构造一个具有默认初始容量(16)和指定并发度(默认等于 16)的 ConcurrentHashMap。
参数:
- concurrencyLevel!: Int64 - 用户指定的并发度。
init(Int64, (Int64) -> (K, V), Int64)
public init(size: Int64, initElement: (Int64) -> (K, V), concurrencyLevel!: Int64 = 16)
功能:构造具有传入大小和初始化函数元素以及指定并发度的 ConcurrentHashMap。该构造函数根据参数 size 设置 ConcurrentHashMap 的容量。
参数:
- size: Int64 - 初始化函数元素的大小。
- initElement: (Int64) -> (K, V) - 初始化函数元素。
- concurrencyLevel!: Int64 - 用户指定并发度。
异常:
- IllegalArgumentException - 如果 size 小于 0 则抛出异常。
init(Int64, Int64)
public init(capacity: Int64, concurrencyLevel!: Int64 = 16)
功能:构造一个带有传入容量大小和指定并发度(默认等于 16)的 ConcurrentHashMap。
参数:
异常:
- IllegalArgumentException - 如果 capacity 小于 0 则抛出异常。
func add(K, V)
public func add(key: K, value: V): ?V
功能:将指定的值 value 与此 ConcurrentHashMap中指定的键 key 关联。如果 ConcurrentHashMap 中已经包含键 key 的关联,则旧值将被替换;如果 ConcurrentHashMap 中不包含键 key 的关联,则添加键 key 与值 value 的关联。
参数:
- key: K - 要放置的键。
- value: V - 要关联的值。
返回值:
- ?V - 如果赋值之前 key 存在,则返回旧的值 Some(V);当赋值前 key 不存在时,返回 None。
示例:
import std.collection.concurrent.*
main() {
let map: ConcurrentHashMap<Int64, Int64> = ConcurrentHashMap<Int64, Int64>(3, {value => (value, value)})
let oldValue = map.add(2, 3)
println(oldValue)
let newValue = map.add(3, 3)
println(newValue)
let iter = ConcurrentHashMapIterator<Int64, Int64>(map)
while (true) {
match (iter.next()) {
case Some(i) => println("(${i[0]},${i[1]})")
case None => break
}
}
}
运行结果:
Some(2)
None
(0,0)
(1,1)
(2,3)
(3,3)
func addIfAbsent(K, V)
public func addIfAbsent(key: K, value: V): ?V
功能:当此 ConcurrentHashMap中不存在键 key 时,在 ConcurrentHashMap 中添加指定的值 value 与指定的键 key 的关联。如果 ConcurrentHashMap 已经包含键 key,则不执行赋值操作。
参数:
- key: K - 要放置的键。
- value: V - 要分配的值。
返回值:
- ?V - 如果赋值之前 key 存在,则返回当前 key 对应的值 Some(V),且不执行赋值操作;当赋值前 key 不存在时,返回 None。
示例:
import std.collection.concurrent.*
main() {
let map: ConcurrentHashMap<Int64, Int64> = ConcurrentHashMap<Int64, Int64>(3, {value => (value, value)})
let oldValue = map.addIfAbsent(2, 3)
println(oldValue)
let newValue = map.addIfAbsent(3, 3)
println(newValue)
let iter = ConcurrentHashMapIterator<Int64, Int64>(map)
while (true) {
match (iter.next()) {
case Some(i) => println("(${i[0]},${i[1]})")
case None => break
}
}
}
运行结果:
Some(2)
None
(0,0)
(1,1)
(2,2)
(3,3)
func contains(K)
public func contains(key: K): Bool
功能:判断此映射中是否包含指定键 key 的映射。
参数:
- key: K - 传递要判断的 key。
返回值:
- Bool - 是否包含指定键 key 的映射,包含为true,不包含为false。
示例:
import std.collection.concurrent.*
main() {
let map: ConcurrentHashMap<Int64, Int64> = ConcurrentHashMap<Int64, Int64>(3, {value => (value, value)})
map.add(3, 3)
println(map.contains(3))
println(map.contains(6))
}
运行结果:
true
false
func entryView(K, (MapEntryView<K, V>) -> Unit)
public func entryView(key: K, fn: (MapEntryView<K, V>) -> Unit): ?V
功能:根据指定键 key 获取当前映射中相应的键值对视图 entryView,并调用函数 fn 对该键值对进行增、删、改操作,并返回最终映射中键 key 对应的值。
如果当前映射中不包含键 key,则将获取一个空视图 entryView,如果将其 value 置为非 None 值,则将在当前映射中增加 key-value 键值对。
如果当前映射中包含键 key,则将获取 key-value 的视图,如果将 value 置为 None,则相当于从当前映射中删除该键值对;如果将 value 置为新的非 None 值,则相当于修改当前映射中键 key 对应的值。
注意参数 fn 中不能并发调用函数 entryView、remove、replace,如:
map.entryView(1) { _ =>
let f = spawn {
map.entryView(17) { _ => () }
}
f.get()
}
说明:
该操作具有原子性。
回调 fn 调用过程中对 key-value 键值对的修改不会即时更新到当前映射中,等到 entryView 函数调用结束再将修改整体更新到当前映射中。
参数:
- key: K - 待获取其相应视图的键。
- fn: (MapEntryView<K, V>) -> Unit - 对指定视图进行的自定义操作,可用于对映射中键值对进行增、删、改操作。
返回值:
- ?V - 函数 fn 调用结束后当前映射中键 key 对应的值,如果 key 不存在,返回 None。
示例:
import std.collection.concurrent.*
main() {
let map: ConcurrentHashMap<Int64, Int64> = ConcurrentHashMap<Int64, Int64>(2, {value => (value, value)})
map.add(2, 2)
/* 当前映射不包含 key 为 3 的键值对,对 entryView.value 设置新值 7,等价于添加新的键值对 (3,7) */
let num1 = map.entryView(3, {view => view.value = 7})
println(num1)
/* 当前映射包含 key 为 2 的键值对,对 entryView.value 设置新值 6,等价更新 key 为 1 的值为 6 */
let num2 = map.entryView(1, {view => view.value = 6})
println(num2)
/* 当前映射包含 key 为 0 的键值对,对 entryView.value 设置新值 None,等价删除 key 为 0 的键值对 */
let num3 = map.entryView(0, {view => view.value = None})
println(num3)
let iter = ConcurrentHashMapIterator<Int64, Int64>(map)
while (true) {
match (iter.next()) {
case Some(i) => println("(${i[0]},${i[1]})")
case None => break
}
}
}
运行结果:
Some(7)
Some(6)
None
(1,6)
(2,2)
(3,7)
func get(K)
public func get(key: K): ?V
功能:返回此映射中键 key 所关联的值。
参数:
- key: K - 传递 key,获取 value。
返回值:
- ?V - 此映射中键 key 所关联的值。
func isEmpty()
public func isEmpty(): Bool
功能:判断 ConcurrentHashMap 是否为空。
注意:
此方法不保证并发场景下的原子性,建议在环境中没有其他线程并发地修改 ConcurrentHashMap 时调用。
返回值:
- Bool - 如果是,则返回 true,否则,返回 false。
func iterator()
public func iterator(): ConcurrentHashMapIterator<K, V>
功能:获取 ConcurrentHashMap 的迭代器。
返回值:
- ConcurrentHashMapIterator<K, V> - ConcurrentHashMap 的迭代器
示例:
import std.collection.concurrent.*
main() {
let map: ConcurrentHashMap<Int64, Int64> = ConcurrentHashMap<Int64, Int64>(3, {value => (value, value)})
let iter = map.iterator()
while (true) {
match (iter.next()) {
case Some(i) => println("(${i[0]},${i[1]})")
case None => break
}
}
}
运行结果:
(0,0)
(1,1)
(2,2)
func put(K, V) (deprecated)
public func put(key: K, value: V): ?V
功能:将指定的值 value 与此 ConcurrentHashMap中指定的键 key 关联。如果 ConcurrentHashMap 中已经包含键 key 的关联,则旧值将被替换;如果 ConcurrentHashMap 中不包含键 key 的关联,则添加键 key 与值 value 的关联。
注意:
未来版本即将废弃,使用 add(K, V) 替代。
参数:
- key: K - 要放置的键。
- value: V - 要关联的值。
返回值:
- ?V- 如果赋值之前 key 存在,则返回旧的值 Some(V);当赋值前 key 不存在时,返回 None。
func putIfAbsent(K, V) (deprecated)
public func putIfAbsent(key: K, value: V): ?V
功能:当此 ConcurrentHashMap中不存在键 key 时,在 ConcurrentHashMap 中添加指定的值 value 与指定的键 key 的关联。如果 ConcurrentHashMap 已经包含键 key,则不执行赋值操作。
注意:
未来版本即将废弃,使用 addIfAbsent(K, V) 替代。
参数:
- key: K - 要放置的键。
- value: V - 要分配的值。
返回值:
- ?V - 如果赋值之前 key 存在,则返回当前 key 对应的值 Some(V),且不执行赋值操作;当赋值前 key 不存在时,返回 None。
func remove((K, (V) -> Bool)) (deprecated)
public func remove(key: K, predicate: (V) -> Bool): ?V
功能:如果此映射中存在键 key 且 key 所映射的值 v 满足条件 predicate,则从此映射中删除 key 的映射。
注意:
未来版本即将废弃,使用 entryView(K, (MapEntryView<K, V>) -> Unit) 替代。
参数:
- key: K - 传入要删除的 key。
- predicate: (V) ->Bool - 传递一个 lambda 表达式进行判断。
返回值:
- ?V - 如果映射中存在 key,则返回 key 对应的旧值;当映射中不存在 key 时,或者 key 关联的值不满足 predicate 时,返回 None。
func remove(K)
public func remove(key: K): ?V
功能:从此映射中删除指定键 key 的映射(如果存在)。
参数:
- key: K - 传入要删除的 key。
返回值:
- ?V - 如果移除之前 key 存在,则返回 key 对应的值 Some(V);当移除时 key 不存在时,返回 None。
示例:
import std.collection.concurrent.*
main() {
let map: ConcurrentHashMap<Int64, Int64> = ConcurrentHashMap<Int64, Int64>(3, {value => (value, value)})
let num = map.remove(0)
println(num)
let iter = map.iterator()
while (true) {
match (iter.next()) {
case Some(i) => println("(${i[0]},${i[1]})")
case None => break
}
}
}
运行结果:
Some(0)
(1,1)
(2,2)
func replace(K, (V) -> Bool, (V) -> V) (deprecated)
public func replace(key: K, predicate: (V) -> Bool, eval: (V) -> V): ?V
功能:如果 ConcurrentHashMap 中存在键 key(假设其关联的值为 v),且 v 满足条件 predicate,则将 ConcurrentHashMap 中键 key 关联的值替换为 eval(v) 的计算结果;如果 ConcurrentHashMap 中不存在键 key,或者存在键 key 但关联的值不满足 predicate,则不对 ConcurrentHashMap 做任何修改。
注意:
未来版本即将废弃,使用 entryView(K, (MapEntryView<K, V>) -> Unit) 替代。
参数:
- key: K - 传入要替换所关联值的键。
- predicate: (V) ->Bool - 传递一个 lambda 表达式进行判断。
- eval: (V) ->V - 传入计算用于替换的新值的函数。
返回值:
- ?V - 如果 key 存在,则返回 key 对应的旧值 Some(V);当 key 不存在时,或者 key 关联的值不满足 predicate 时,返回 None。
func replace(K, (V) -> V) (deprecated)
public func replace(key: K, eval: (V) -> V): ?V
功能:如果 ConcurrentHashMap 中存在键 key(假设其关联的值为 v),则将 ConcurrentHashMap 中键 key 关联的值替换为 eval(v) 的计算结果;如果 ConcurrentHashMap中不存在键 key,则不对 ConcurrentHashMap 做任何修改。
注意:
未来版本即将废弃,使用 entryView(K, (MapEntryView<K, V>) -> Unit) 替代。
参数:
- key: K - 传入要替换所关联值的键。
- eval: (V) ->V - 传入计算用于替换的新值的函数。
返回值:
- ?V - 如果 key 存在,则返回 key 对应的旧值 Some(V);当 key 不存在时,返回 None。
func replace(K, V)
public func replace(key: K, value: V): ?V
功能:如果 ConcurrentHashMap 中存在 key,则将 ConcurrentHashMap 中键 key 关联的值替换为 value;如果 ConcurrentHashMap 中不存在 key,则不对 ConcurrentHashMap 做任何修改。
参数:
- key: K - 传入要替换所关联值的键。
- value: V - 传入要替换成的新值。
返回值:
- ?V - 如果 key 存在,则返回 key 对应的旧值 Some(V);当 key 不存在时,返回 None。
示例:
import std.collection.concurrent.*
main() {
let map: ConcurrentHashMap<Int64, Int64> = ConcurrentHashMap<Int64, Int64>(3, {value => (value, value)})
let num = map.replace(0, 2)
println(num)
let iter = map.iterator()
while (true) {
match (iter.next()) {
case Some(i) => println("(${i[0]},${i[1]})")
case None => break
}
}
}
运行结果:
Some(0)
(0,2)
(1,1)
(2,2)
operator func [](K)
public operator func [](key: K): V
功能:运算符重载集合,如果键存在,返回键对应的值;如果不存在,抛出异常。
参数:
- key: K - 传递值进行判断。
返回值:
- V - 与键对应的值。
异常:
- NoneValueException - 关联中不存在键 key。
operator func [](K, V)
public operator func [](key: K, value!: V): Unit
功能:运算符重载集合,如果键 key 存在,新 value 覆盖旧 value;如果键不存在,添加此键值对。
参数:
- key: K - 传递值进行判断。
- value!: V - 传递要设置的值。
class ConcurrentHashMapIterator<K, V> where K <: Hashable & Equatable<K>
public class ConcurrentHashMapIterator<K, V> <: Iterator<(K, V)> where K <: Hashable & Equatable<K> {
public init(cmap: ConcurrentHashMap<K, V>)
}
功能:此类主要实现 ConcurrentHashMap 的迭代器功能。
注意:
这里定义的 ConcurrentHashMap 迭代器:
- 不保证迭代结果为并发 HashMap 某一时刻的 “快照”,建议在环境中没有其他线程并发地修改 ConcurrentHashMap 时调用;
- 迭代器在迭代过程中,不保证可以感知环境线程对目标 ConcurrentHashMap 的修改。
父类型:
- Iterator<(K, V)>
init(ConcurrentHashMap<K, V>)
public init(cmap: ConcurrentHashMap<K, V>)
功能:创建 ConcurrentHashMapIterator<K, V> 实例。
参数:
- cmap: ConcurrentHashMap<K, V> - 待获取其迭代器的 ConcurrentHashMap<K, V> 实例。
func next()
public func next(): Option<(K, V)>
功能:返回迭代中的下一个元素。
返回值:
示例:
import std.collection.concurrent.*
main() {
let map: ConcurrentHashMap<Int64, Int64> = ConcurrentHashMap<Int64, Int64>(3, {value => (value, value)})
let iter = ConcurrentHashMapIterator<Int64, Int64>(map)
while (true) {
match (iter.next()) {
case Some(i) => println("(${i[0]},${i[1]})")
case None => break
}
}
}
运行结果:
(0,0)
(1,1)
(2,2)
class ConcurrentLinkedQueue<E>
public class ConcurrentLinkedQueue<E> <: Collection<E> {
public init()
public init(elements: Collection<E>)
}
功能:提供一个线程安全的队列,可以在多线程环境下安全地进行元素的添加和删除操作。
非阻塞队列的目的是为了解决多线程环境下的同步问题,使得多个线程可以并发地进行队列的操作,而不会出现数据冲突或者死锁的问题。
非阻塞队列在多线程编程中非常常见,它可以用于任何需要线程安全队列的场景,例如生产者消费者模型、任务调度、线程池等。
父类型:
- Collection<E>
使用示例:
使用示例见 ConcurrentLinkedQueue 使用示例。
prop size
public prop size: Int64
功能:获取此 ConcurrentLinkedQueue 的元素个数。
注意:
此方法不保证并发场景下的原子性,建议在环境中没有其他线程并发地修改 ConcurrentLinkedQueue 时调用。
类型:Int64
init()
public init()
功能:构造一个默认的 ConcurrentLinkedQueue 实例。
init(Collection<E>) (deprecated)
public init(elements: Collection<E>)
功能:根据 Collection<E> 实例构造一个 ConcurrentLinkedQueue 实例。
注意:
未来版本即将废弃,如需实现等效功能,可先创建空队列,再依次将 Collection 中元素添加到队列中。
参数:
- elements: Collection<E> - 将该容器中元素放入新构造的 ConcurrentLinkedQueue
func add(E)
public func add(element: E): Bool
功能:非阻塞的入队操作,将元素添加到队列尾部。
注意:
该函数不会返回 false。
参数:
- element: E - 要添加的元素。
返回值:
- Bool - 成功添加元素则返回 true。
func dequeue() (deprecated)
public func dequeue(): Option<E>
功能:获取并删除队首元素。
注意:
未来版本即将废弃,使用 remove() 替代。
返回值:
- Option<E> - 成功删除则返回队首元素,队列为空则返回 None。
func enqueue(E) (deprecated)
public func enqueue(element: E): Bool
功能:非阻塞的入队操作,将元素添加到队列尾部。
注意:
- 该函数不会返回 false。
- 未来版本即将废弃,使用 add(E) 替代。
参数:
- element: E - 要添加的元素。
返回值:
- Bool - 成功添加元素则返回 true。
func head() (deprecated)
public func head(): Option<E>
功能:获取队首元素,不会删除该元素。
注意:
未来版本即将废弃,使用 peek() 替代。
返回值:
- Option<E> - 成功获取则返回队首元素,队列为空则返回 None。
func isEmpty()
public func isEmpty(): Bool
功能:判断当前队列是否为空。
返回值:
- Bool - 当前队列为空返回 true,否则返回 false。
func iterator()
public func iterator(): Iterator<E>
功能:获取当前队列的迭代器,用于遍历当前队列。
说明:
遍历操作不会删除队列中的元素。 遍历操作不保证原子性,如果有其他线程并发修改当前队列,不保遍历得到的元素是当前队列某一时刻的静态切片。
返回值:
- Iterator<E> - 当前队列的迭代器。
func peek()
public func peek(): Option<E>
功能:获取队首元素,不会删除该元素。
返回值:
- Option<E> - 成功获取则返回队首元素,队列为空则返回 None。
func remove()
public func remove(): Option<E>
功能:获取并删除队首元素。
返回值:
- Option<E> - 成功删除则返回队首元素,队列为空则返回 None。
func toArray()
public func toArray(): Array<E>
功能:将当前队列中所有元素按顺序存入数组,先入队的元素在数组下标较小的位置。
说明:
该操作不会删除队列中的元素。 该操作不保证原子性,如果有其他线程并发修改当前队列,不保证该操作得到的数组是当前队列某一时刻的静态切片。
返回值:
- Array<E> - 得到的数组,里面的元素为当前队列中的元素。
class LinkedBlockingQueue<E>
public class LinkedBlockingQueue<E> {
public let capacity: Int64
public init()
public init(capacity: Int64)
public init(capacity: Int64, elements: Array<E>)
public init(capacity: Int64, elements: Collection<E>)
}
功能:实现是带阻塞机制并支持用户指定容量上界的并发队列。
阻塞队列的特点是,当队列满时,尝试向队列中添加元素的线程会被阻塞,直到队列有空余位置;当队列空时,尝试从队列中获取元素的线程会被阻塞,直到队列有可取元素。
let capacity
public let capacity: Int64
功能:返回此 LinkedBlockingQueue 的容量。
类型:Int64
prop size
public prop size: Int64
功能:返回此 LinkedBlockingQueue 的元素个数。
注意:
此方法不保证并发场景下的原子性,建议在环境中没有其他线程并发地修改 LinkedBlockingQueue 时调用。
类型:Int64
init()
public init()
功能:构造一个具有默认初始容量(Int64.Max)的 LinkedBlockingQueue。
init(Int64)
public init(capacity: Int64)
功能:构造一个带有传入容量大小的 LinkedBlockingQueue。
参数:
- capacity: Int64 - 初始化容量大小。
异常:
- IllegalArgumentException - 如果 capacity 小于等于 0 则抛出异常。
init(Int64, Array<E>) (deprecated)
public init(capacity: Int64, elements: Array<E>)
功能:构造一个带有传入容量大小,并带有传入数组元素的 LinkedBlockingQueue。
注意:
未来版本即将废弃,如需实现等效功能,可先创建空队列,再依次将数组中的元素添加到队列中。
参数:
异常:
- IllegalArgumentException - 如果 capacity 小于等于 0 或小于数组元素elements 的 size 则抛出异常。
init(Int64, Collection<E>) (deprecated)
public init(capacity: Int64, elements: Collection<E>)
功能:构造一个带有传入容量大小,并带有传入迭代器的 LinkedBlockingQueue。
注意:
未来版本即将废弃,如需实现等效功能,可先创建空队列,再依次将 Collection 中的元素添加到队列中。
参数:
- capacity: Int64 - 初始化容量大小。
- elements: Collection<E> - 初始化迭代器元素。
异常:
- IllegalArgumentException - 如果 capacity 小于等于 0 或小于迭代器元素elements 的 size 则抛出异常。
func add(E)
public func add(element: E): Unit
功能:阻塞的入队操作,将元素添加到队列尾部。如果队列已满,则阻塞等待。
参数:
- element: E - 要添加的元素。
示例:
import std.collection.concurrent.*
main() {
var blockArr: LinkedBlockingQueue<Int64> = LinkedBlockingQueue<Int64>(2)
blockArr.add(10)
println(blockArr.peek())
}
运行结果:
Some(10)
func add(E, Duration)
public func add(element: E, timeout: Duration): Bool
功能:阻塞的入队操作,将元素添加到队列尾部,如果队列满了,将等待指定的时间。如果 timeout 为负,则会立即执行入队操作并且返回操作结果。
参数:
- element: E - 要添加的元素。
- timeout: Duration - 等待时间。
返回值:
- Bool - 成功添加元素返回 true。超出等待时间还未成功添加元素返回 false。
示例:
import std.collection.concurrent.*
import std.sync.*
import std.time.*
main() {
let blockArr: LinkedBlockingQueue<Int64> = LinkedBlockingQueue<Int64>(2)
/* 创建新线程,填满阻塞队列,休眠 1 秒后移除阻塞队列队首元素 */
spawn {
=>
blockArr.add(0)
blockArr.add(1)
sleep(1000 * Duration.millisecond)
println("New thread moves out of blocked queue head element.")
blockArr.remove()
}
/* 主线程立即让出执行权,唤醒后阻塞的添加 */
sleep(-1 * Duration.millisecond)
println("The main thread is woken up.")
let isSuccess: Bool = blockArr.add(2, 2000 * Duration.millisecond)
println(isSuccess)
}
运行结果:
The main thread is woken up.
New thread moves out of blocked queue head element.
true
func dequeue() (deprecated)
public func dequeue(): E
功能:阻塞的出队操作,获得队首元素并删除。
注意:
未来版本即将废弃,使用 remove() 替代。
返回值:
- E - 返回队首元素。
func dequeue(Duration) (deprecated)
public func dequeue(timeout: Duration): Option<E>
功能:阻塞的出队操作,获得队首元素并删除。如果队列为空,将等待指定的时间。如果 timeout 为负,则会立即执行出队操作并且返回操作结果。
注意:
未来版本即将废弃,使用 remove(Duration) 替代。
参数:
- timeout: Duration - 等待时间。
返回值:
- Option<E> - 返回队首元素。如果超出等待时间还未成功获取队首元素,则返回 None。
func enqueue(E) (deprecated)
public func enqueue(element: E): Unit
功能:阻塞的入队操作,将元素添加到队列尾部。
注意:
未来版本即将废弃,使用 add(E) 替代。
参数:
- element: E - 要添加的元素。
func enqueue(E, Duration) (deprecated)
public func enqueue(element: E, timeout: Duration): Bool
功能:阻塞的入队操作,将元素添加到队列尾部,如果队列满了,将等待指定的时间。如果 timeout 为负,则会立即执行入队操作并且返回操作结果。
注意:
未来版本即将废弃,使用 add(E, Duration) 替代。
参数:
- element: E - 要添加的元素。
- timeout: Duration - 等待时间。
返回值:
- Bool - 成功添加元素返回 true。超出等待时间还未成功添加元素返回 false。
func head() (deprecated)
public func head(): Option<E>
功能:获取队首元素。
注意:
- 该函数是非阻塞的。
- 未来版本即将废弃,使用 peek() 替代。
返回值:
- Option<E> - 返回队首元素,队列为空时返回 None。
func peek()
public func peek(): Option<E>
功能:获取队首元素。
注意:
该函数是非阻塞的。
返回值:
- Option<E> - 返回队首元素,队列为空时返回 None。
示例:
import std.collection.concurrent.*
main() {
let blockArr: LinkedBlockingQueue<Int64> = LinkedBlockingQueue<Int64>(2)
blockArr.add(2)
blockArr.add(3)
println(blockArr.peek())
}
运行结果:
Some(2)
func remove()
public func remove(): E
功能:阻塞的出队操作,获得队首元素并删除。
返回值:
- E - 返回队首元素。
示例:
import std.collection.concurrent.*
main() {
let blockArr: LinkedBlockingQueue<Int64> = LinkedBlockingQueue<Int64>(2)
blockArr.add(2)
blockArr.add(3)
println(blockArr.remove())
println(blockArr.size)
}
运行结果:
2
1
func remove(Duration)
public func remove(timeout: Duration): Option<E>
功能:阻塞的出队操作,获得队首元素并删除。如果队列为空,将等待指定的时间。如果 timeout 为负,则会立即执行出队操作并且返回操作结果。
参数:
- timeout: Duration - 等待时间。
返回值:
- Option<E> - 返回队首元素。如果超出等待时间还未成功获取队首元素,则返回 None。
示例:
import std.collection.concurrent.*
import std.sync.*
import std.time.*
main() {
let blockArr: LinkedBlockingQueue<Int64> = LinkedBlockingQueue<Int64>(2)
/* 创建新线程,休眠 1 秒后向队列添加元素 */
spawn {
=>
sleep(1000 * Duration.millisecond)
println("This new thread adds new elements to the queue.")
blockArr.add(3)
}
/* 主线程立即让出执行权,唤醒后阻塞的取出队首元素 */
sleep(-1 * Duration.millisecond)
println("The main thread is woken up.")
let num: Option<Int64> = blockArr.remove(2000 * Duration.millisecond)
println(num)
}
运行结果:
The main thread is woken up.
This new thread adds new elements to the queue.
Some(3)
func tryAdd(E)
public func tryAdd(element: E): Bool
功能:非阻塞的入队操作,将元素添加到队列尾部。
参数:
- element: E - 要添加的元素。
返回值:
- Bool - 成功添加返回 true;如果队列满了,添加失败返回 false。
示例:
import std.collection.concurrent.*
main() {
let blockArr: LinkedBlockingQueue<Int64> = LinkedBlockingQueue<Int64>(2)
blockArr.tryAdd(2)
blockArr.tryAdd(3)
println(blockArr.size)
}
运行结果:
2
func tryDequeue() (deprecated)
public func tryDequeue(): Option<E>
功能:非阻塞的出队操作,获得队首元素并删除。
注意:
未来版本即将废弃,使用 tryRemove() 替代。
返回值:
- Option<E> - 返回队首元素,队列为空时返回 None。
func tryEnqueue(E) (deprecated)
public func tryEnqueue(element: E): Bool
功能:非阻塞的入队操作,将元素添加到队列尾部。
注意:
未来版本即将废弃,使用 tryAdd(E) 替代。
参数:
- element: E - 要添加的元素。
返回值:
- Bool - 成功添加返回 true;如果队列满了,添加失败返回 false。
func tryRemove()
public func tryRemove(): Option<E>
功能:非阻塞的出队操作,获得队首元素并删除。
返回值:
- Option<E> - 返回队首元素,队列为空时返回 None。
示例:
import std.collection.concurrent.*
main() {
let blockArr: LinkedBlockingQueue<Int64> = LinkedBlockingQueue<Int64>(2)
blockArr.tryAdd(3)
println(blockArr.tryRemove())
println(blockArr.tryRemove())
}
运行结果:
Some(3)
None
ConcurrentHashMap 使用示例
示例:
import std.collection.*
import std.collection.concurrent.*
import std.sync.*
main() {
let threads = 8
let M = 1024
let cmap = ConcurrentHashMap<Int64, Int64>(concurrencyLevel: 64)
let jobs = Array<Future<Unit>>(threads, repeat: unsafe { zeroValue<Future<Unit>>() })
for (t in 0..threads) {
jobs[t] = spawn {
for (i in t..M : threads) {
cmap.put(i, i + 3)
}
}
}
for (t in 0..threads) {
jobs[t].get()
}
println("Size after put: ${cmap.size}")
for (t in 0..threads) {
jobs[t] = spawn {
for (i in t..M : threads) {
cmap.remove(i, {v => v % 2 == 0})
}
}
}
for (t in 0..threads) {
jobs[t].get()
}
println("Size after remove first: ${cmap.size}")
for (t in 0..threads) {
jobs[t] = spawn {
for (i in t..M : threads) {
cmap.remove(i)
}
}
}
for (t in 0..threads) {
jobs[t].get()
}
println("Size after remove second: ${cmap.size}")
}
运行结果:
Size after put: 1024
Size after remove first: 512
Size after remove second: 0
ConcurrentLinkedQueue 使用示例
示例:
import std.collection.*
import std.collection.concurrent.*
import std.sync.*
main() {
let threads = 8
let total: Int64 = 128
let bq = ConcurrentLinkedQueue<Int64>(Array<Int64>(total, {i => i}))
println("Total ${bq.size} after init")
let jobs = Array<Future<Unit>>(threads, repeat: unsafe { zeroValue<Future<Unit>>() })
for (t in 0..threads) {
jobs[t] = spawn {
for (i in t..total : threads) {
bq.dequeue()
}
}
}
for (t in 0..threads) {
jobs[t].get()
}
println("Total ${bq.size} after dequeue")
}
运行结果:
Total 128 after init
Total 0 after dequeue
std.console(deprecated)
注意:
未来版本即将废弃不再使用,可使用 env 包替代。
功能介绍
console 包提供和标准输入、标准输出、标准错误进行交互的方法。
本包提供 Console 类,用于获取这三个标准流。
- ConsoleReader 封装了标准输入流的相关功能,可以通过相关的
read方法从标准输入中读取数据。 - ConsoleWriter 封装了标准输出、标准错误流的相关功能,ConsoleWriter 封装了一系列的
write方法,提供了向标准输出、标准错误写入数据的能力。
标准输入(stdin)、标准输出(stdout)和标准错误(stderr)是计算机操作系统中常见的三个流。
标准输入是程序从用户获取输入数据的流,通常是键盘输入。标准输出是程序向用户输出结果的流,通常是屏幕输出。标准错误是程序在发生错误时输出错误信息的流,通常也是屏幕输出。
在 Unix/Linux 系统中,标准输入、标准输出和标准错误分别对应文件描述符 0、1 和 2。程序可以使用这些文件描述符来读取和写入数据。例如,可以使用重定向符号将标准输出重定向到文件中,或将标准错误输出重定向到另一个程序的标准输入中。
API 列表
类
| 类名 | 功能 |
|---|---|
| Console | 提供标准输入、标准输出和标准错误 Stream 的获取接口。 |
| ConsoleReader | 提供从标准输入读取字符或者字符串的功能。 |
| ConsoleWriter | 提供向标准输出或者标准错误流写入字符或者字符串的功能。 |
类
class Console (deprecated)
public class Console
功能:此类提供标准输入、标准输出和标准错误流的获取接口。
注意:
未来版本即将废弃,使用 env 包中相应函数替代。
static prop stdErr
public static prop stdErr: ConsoleWriter
功能:该成员属性为 ConsoleWriter 类型,它提供标准错误的获取功能。
static prop stdIn
public static prop stdIn: ConsoleReader
功能:该成员属性为 ConsoleReader 类型,它提供标准输入的获取功能。
static prop stdOut
public static prop stdOut: ConsoleWriter
功能:该成员属性为 ConsoleWriter 类型,它提供标准输出的获取功能。
class ConsoleReader (deprecated)
public class ConsoleReader <: InputStream
功能:提供从控制台读出数据并转换成字符或字符串的功能。
该类型无法构造实例,只能通过 Console.stdIn 获取实例。
读操作是同步的,内部设有缓存区来保存控制台输入的内容,当到达控制台输入流的结尾时,控制台读取函数将返回None。
ConsoleReader 只有一个实例,所有方法共享同一个缓存区,相关read方法返回None的情形有:
- 将标准输入重定向到文件时,读取到文件结尾EOF。
- Linux 环境,按下
Ctrl+D。 - Windows 环境,按下
Ctrl+Z后加回车。
注意:
未来版本即将废弃,使用 ConsoleReader 替代。
父类型:
func read()
public func read(): ?Rune
功能:从标准输入中读取下一个字符。
返回值:
异常:
- IllegalArgumentException:当输入不符合
UTF-8编码的字符串时,抛此异常。
func read(Array<Byte>)
public func read(arr: Array<Byte>): Int64
功能:从标准输入中读取并放入 arr 中。
注意:
该函数存在风险,可能读取出来的结果恰好把
UTF-8 code point从中截断,如果发生截断,将导致该 Array<Byte> 转换成字符串的结果不正确或抛出异常。
参数:
返回值:
- Int64 - 返回读取到的字节长度。
func readToEnd()
public func readToEnd(): ?String
功能:从标准输入中读取所有字符。
直到读取到文件结束符 EOF,或者在 Linux 上键入 Ctrl+D 或在 Windows 上键入 Ctrl+Z + 回车结束。读取到字符,返回 ?String,否则返回 None。读取失败时会返回 None,该接口不会抛出异常,即使输入不符合 UTF-8 编码的字符串,也会构造出一个 String 并返回,其行为等同于 String.fromUtf8Uncheck(Array<Byte>)。
返回值:
func readUntil((Rune) -> Bool)
public func readUntil(predicate: (Rune) -> Bool): ?String
功能:从标准输入中读取数据直到读取到的字符满足predicate条件结束。
满足 predicate: (Rune) -> Bool 条件的字符包含在结果中,读取失败时会返回None。
参数:
- predicate: (Rune) ->Bool - 终止读取的条件。
返回值:
func readUntil(Rune)
public func readUntil(ch: Rune): ?String
功能:从标准输入中读取数据直到读取到字符 ch 结束。
ch包含在结果中,如果读取到文件结束符 EOF,将返回读取到的所有信息,读取失败时会返回 None。
参数:
- ch: Rune - 终止字符。
返回值:
func readln()
public func readln(): ?String
功能:从标准输入中读取一行字符串。
读取到字符,返回 ?String,结果不包含末尾换行符。该接口不会抛出异常,即使输入不符合UTF-8编码的字符串,也会构造出一个 String 并返回,其行为等同于 String.fromUtf8Uncheck(Array<Byte>)。
返回值:
- ?String - 读取到的行数据,读取失败返回
None。
class ConsoleWriter (deprecated)
public class ConsoleWriter <: OutputStream
功能:此类提供保证线程安全的标准输出功能。
每次 write 调用写到控制台的结果是完整的,不同的 write 函数调用的结果不会混合到一起。 该类型无法构造实例,只能通过 Console.stdOut 获取标准输出实例或者 Console.stdErr 获取标准错误的实例。
注意:
未来版本即将废弃,使用 ConsoleWriter 替代。
父类型:
func flush()
public func flush(): Unit
功能:刷新输出流。
func write(Array<Byte>)
public func write(buffer: Array<Byte>): Unit
功能:指定的将字节数组 buffer 写入标准输出或标准错误流中。
参数:
func write(Bool)
public func write(v: Bool): Unit
功能:将指定的布尔值的文本表示形式写入标准输出或标准错误流中。
参数:
- v: Bool - 要写入的值。
func write(Float16)
public func write(v: Float16): Unit
功能:将指定的 16 位浮点数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Float16 - 要写入的值。
func write(Float32)
public func write(v: Float32): Unit
功能:将指定的 32 位浮点数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Float32 - 要写入的值。
func write(Float64)
public func write(v: Float64): Unit
功能:将指定的 64 位浮点数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Float64 - 要写入的值。
func write(Int16)
public func write(v: Int16): Unit
功能:将指定的 16 位有符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Int16 - 要写入的值。
func write(Int32)
public func write(v: Int32): Unit
功能:将指定的 32 位有符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Int32 - 要写入的值。
func write(Int64)
public func write(v: Int64): Unit
功能:将指定的 64 位有符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Int64 - 要写入的值。
func write(Int8)
public func write(v: Int8): Unit
功能:将指定的 8 位有符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Int8 - 要写入的值。
func write(Rune)
public func write(v: Rune): Unit
功能:将指定的 Rune 的 Unicode 字符值写入标准输出或标准错误流中。
参数:
- v: Rune - 要写入的值。
func write(String)
public func write(v: String): Unit
功能:将指定的字符串值写入标准输出或标准错误流中。
参数:
- v: String - 要写入的值。
func write(UInt16)
public func write(v: UInt16): Unit
功能:将指定的 16 位无符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: UInt16 - 要写入的值。
func write(UInt32)
public func write(v: UInt32): Unit
功能:将指定的 32 位无符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: UInt32 - 要写入的值。
func write(UInt64)
public func write(v: UInt64): Unit
功能:将指定的 64 位无符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: UInt64 - 要写入的值。
func write(UInt8)
public func write(v: UInt8): Unit
功能:将指定的 8 位无符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: UInt8 - 要写入的值。
func write<T>(T) where T <: ToString
public func write<T>(v: T): Unit where T <: ToString
功能:将实现了 ToString 接口的数据类型写入标准输出或标准错误流中。
参数:
- v: T - 要被写入的 ToString 类型的实例。
func writeln(Array<Byte>)
public func writeln(buffer: Array<Byte>): Unit
功能:指定的将字节数组 buffer (后跟换行符)写入标准输出或标准错误流中。
参数:
func writeln(Bool)
public func writeln(v: Bool): Unit
功能:将指定的布尔值的文本表示形式(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Bool - 要写入的值。
func writeln(Float16)
public func writeln(v: Float16): Unit
功能:将指定的 16 位浮点数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Float16 - 要写入的值。
func writeln(Float32)
public func writeln(v: Float32): Unit
功能:将指定的 32 位浮点数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Float32 - 要写入的值。
func writeln(Float64)
public func writeln(v: Float64): Unit
功能:将指定的 64 位浮点数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Float64 - 要写入的值。
func writeln(Int16)
public func writeln(v: Int16): Unit
功能:将指定的 16 位有符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Int16 - 要写入的值。
func writeln(Int32)
public func writeln(v: Int32): Unit
功能:将指定的 32 位有符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Int32 - 要写入的值。
func writeln(Int64)
public func writeln(v: Int64): Unit
功能:将指定的 64 位有符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Int64 - 要写入的值。
func writeln(Int8)
public func writeln(v: Int8): Unit
功能:将指定的 8 位有符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Int8 - 要写入的值。
func writeln(Rune)
public func writeln(v: Rune): Unit
功能:将指定的 Unicode 字符值(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Rune - 要写入的值。
func writeln(String)
public func writeln(v: String): Unit
功能:将指定的字符串值(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: String - 要写入的值。
func writeln(UInt16)
public func writeln(v: UInt16): Unit
功能:将指定的 16 位无符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: UInt16 - 要写入的值。
func writeln(UInt32)
public func writeln(v: UInt32): Unit
功能:将指定的 32 位无符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。 参数:
- v: UInt32 - 要写入的值。
func writeln(UInt64)
public func writeln(v: UInt64): Unit
功能:将指定的 64 位无符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: UInt64 - 要写入的值。
func writeln(UInt8)
public func writeln(v: UInt8): Unit
功能:将指定的 8 位无符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: UInt8 - 要写入的值。
func writeln<T>(T) where T <: ToString
public func writeln<T>(v: T): Unit where T <: ToString
功能:将实现了 ToString 接口的数据类型转换成的字符串(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: T - 要写入的值。
Console 示例
下面是 Console 示例,示例中接收用户输入的两条信息,并将这些信息通过标准输出原样返回给用户。
示例:
import std.console.*
main() {
Console.stdOut.write("请输入信息1:")
var c = Console.stdIn.readln() // 输入:你好,请问今天星期几?
var r = c.getOrThrow()
Console.stdOut.writeln("输入的信息1为:" + r)
Console.stdOut.write("请输入信息2:")
c = Console.stdIn.readln() // 输入:你好,请问今天几号?
r = c.getOrThrow()
Console.stdOut.writeln("输入的信息2为:" + r)
return
}
运行结果:
请输入信息1:你好,请问今天星期几?
输入的信息1为:你好,请问今天星期几?
请输入信息2:你好,请问今天几号?
输入的信息2为:你好,请问今天几号?
std.convert
功能介绍
convert 包提供从字符串转到特定类型的 Convert 系列函数。
例如字符串 "true" 到布尔类型 true 的转换以及字符串 "123" 到整数类型 123 的转换等。
convert 包提供格式化能力,主要为将仓颉类型实例转换为格式化字符串。
定义了接口 Formattable,用于规定统一的格式化方法,并为 Int8、Int16 等一系列仓颉类型实现了该接口,用户也可以自行为其他类型实现该接口以获取格式化功能。
将仓颉类型转换为字符串时,可根据格式化参数规定字符串格式,如宽度、对齐方式等。(在 Formattable 接口定义的方法中,格式化参数将作为函数入参。)
格式化参数的详细语法说明如下:
format_spec := [flags][width][.precision][specifier]
flags := '-' | '+' | '#' | '0'
width := integer
precision := integer
specifier := 'b' | 'B' | 'o' | 'O' | 'x' | 'X' | 'e' | 'E' | 'g' | 'G'
参数 flags:
-
'-' 适用于 Int,UInt,Rune 和 Float,表示左对齐。
代码如下:
import std.convert.* main() { var c : Int32 = -20 print("\"${c.format("-10")}\"") }运行结果:
"-20 " -
'+' 适用于 Int,UInt 和 Float,如果数值为正数则打出 '+' 符号,如果数值为负数则忽略。
代码如下:
import std.convert.* main() { var c: Int32 = 20 print("\"${c.format("+10")}\"") }运行结果:
" +20" -
'#' 是针对进制打印的,对于二进制打印会补充一个 '0b' 或者 '0B',对于八进制打印会补充一个 '0o' 或者 '0O',对于十六进制会补充 '0x' 或者 '0X'。
代码如下:
import std.convert.* main() { var c: Int32 = 1 print("\"${c.format("#10x")}\"") }运行结果:
" 0x1" -
'0' 适用于 Int,UInt 和 Float,在空位补充 0。
代码如下:
import std.convert.* main() { var c: Int32 = -20 print("\"${c.format("010")}\"") }运行结果:
"-000000020"
参数 width 宽度:
-
宽度为正整数,适用于 Int,UInt,Rune 和 Float,宽度前有负号则表示左对齐,没有负号则是右对齐,如果数值小于数值本身的长度,不会发生截断。 如果前缀有
+或-符号会占用一个字符位,如果前缀有0x或0o等会占用两个字符位。代码如下:
import std.convert.* main() { var c: Int32 = 20 println("\"${c.format("1")}\"") println("\"${c.format("+4")}\"") }运行结果:
"20" " +20"
参数 precision 精度:
-
精度为正整数,适用于 Int,UInt 和 Float。 对于浮点数表示小数点后的有效数字位数,如果不指定,那么则打印六位小数,如果小于数值本身有效数字的长度,那就四舍五入,如果大于就补全,补全的不一定是 0。
-
对于整数类型,不指定或者指定的数字小于数值本身的长度,则无效果,如果大于数值本身的长度,则在前面补全'0'。
代码如下:
import std.convert.* main() { var e: Float32 = 1234.1 println("\"${e.format("20.20")}\"") var c: Int32 = -20 println("\"${c.format("10.8")}\"") }运行结果:
"1234.09997558593750000000" " -00000020"
参数 specifier:
-
'b' | 'B' | 'o' | 'O' | 'x' | 'X' 适用于 Int 和 UInt 类型。
'b' | 'B' : 表示二进制格式打印
'o' | 'O' : 表示八进制格式打印
'x' | 'X' : 表示十六进制格式打印
代码如下:
import std.convert.* main() { var a = 20 println("\"${a.format("b")}\"") println("\"${a.format("o")}\"") println("\"${a.format("x")}\"") println("\"${a.format("X")}\"") println("\"${a.format("#X")}\"") }运行结果:
"10100" "24" "14" "14" "0X14" -
'e' | 'E' | 'g' | 'G' 适用于 Float 类型。
'e' | 'E' : 科学计数法,小写和大写
'g' | 'G' : general,用十进制或者科学计数法表示,会选择精简的表示方式进行打印
代码如下:
import std.convert.* main() { var f: Float32 = 1234.1 var c: Float32 = 123412341234.1 println("\"${f.format("20.2e")}\"") println("\"${f.format("20G")}\"") println("\"${c.format("20G")}\"") println("\"${f.format("20")}\"") println("\"${c.format("20")}\"") }运行结果:
" 1.23e+03" " 1234.1" " 1.23412E+11" " 1234.099976" " 123412340736.000000"
API 列表
接口
| 接口名 | 功能 |
|---|---|
| Formattable | 该接口定义了格式化函数,即根据格式化参数将指定类型实例转换为对应格式的字符串。 |
| Parsable<T> | 将字符串解析为特定类型的接口。 |
| RadixConvertible<T> | 将指定字符串解析为特定类型的接口。 |
接口
interface Formattable
public interface Formattable {
func format(fmt: String): String
}
功能:该接口定义了格式化函数,即根据格式化参数将指定类型实例转换为对应格式的字符串。
格式化参数相关的说明请参见 convert 包中的功能介绍。
其他类型可通过实现该接口提供格式化功能。
func format(String)
func format(fmt: String): String
功能:根据格式化参数将当前实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
- String - 将当前实例格式化后得到的字符串。
extend Float16 <: Formattable
extend Float16 <: Formattable
功能:为 Float16 扩展 Formattable 接口,以实现将 Float16 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Float16 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend Float32 <: Formattable
extend Float32 <: Formattable
功能:为 Float32 扩展 Formattable 接口,以实现将 Float32 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Float32 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend Float64 <: Formattable
extend Float64 <: Formattable
功能:为 Float64 扩展 Formattable 接口,以实现将 Float64 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Float64 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend Int16 <: Formattable
extend Int16 <: Formattable
功能:为 Int16 扩展 Formattable 接口,以实现将 Int16 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Int16 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend Int32 <: Formattable
extend Int32 <: Formattable
功能:为 Int32 扩展 Formattable 接口,以实现将 Int32 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Int32 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend Int64 <: Formattable
extend Int64 <: Formattable
功能:为 Int64 扩展 Formattable 接口,以实现将 Int64 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Int64 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend Int8 <: Formattable
extend Int8 <: Formattable
功能:为 Int8 扩展 Formattable 接口,以实现将 Int8 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Int8 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend Rune <: Formattable
extend Rune <: Formattable
功能:为 Rune 扩展 Formattable 接口,以实现将 Rune 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Rune 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend UInt16 <: Formattable
extend UInt16 <: Formattable
功能:为 UInt16 扩展 Formattable 接口,以实现将 UInt16 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 UInt16 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend UInt32 <: Formattable
extend UInt32 <: Formattable
功能:为 UInt32 扩展 Formattable 接口,以实现将 UInt32 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 UInt32 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend UInt64 <: Formattable
extend UInt64 <: Formattable
功能:为 UInt64 扩展 Formattable 接口,以实现将 UInt64 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 UInt64 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend UInt8 <: Formattable
extend UInt8 <: Formattable
功能:为 UInt8 扩展 Formattable 接口,以实现将 UInt8 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 UInt8 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
interface Parsable<T>
public interface Parsable<T> {
static func parse(value: String): T
static func tryParse(value: String): Option<T>
}
功能:本接口提供了统一的方法,以支持将字符串解析为特定类型。
本接口提供了 parse 和 tryParse 两套方法,parse 方法将在解析失败时抛出异常,tryParse 方法将返回值用 Option 包裹,解析失败时将返回 None。 本包内已经为 Bool,Rune,Float16,Int64 等基础类型实现该接口,可用于将字符串转换为这些类型。
static func parse(String)
static func parse(value: String): T
功能:从字符串中解析特定类型。
参数:
- value: String - 待解析的字符串。
返回值:
- T - 转换后的值。
static func tryParse(String)
static func tryParse(value: String): Option<T>
功能:从字符串中解析特定类型。
参数:
- value: String - 待解析的字符串。
返回值:
extend Bool <: Parsable<Bool>
extend Bool <: Parsable<Bool>
功能:此扩展主要用于实现将 Bool 类型字面量的字符串转换为 Bool 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Bool
功能:将 Bool 类型字面量的字符串转换为 Bool 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空或转换失败时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Bool>
功能:将 Bool 类型字面量的字符串转换为 Option<Bool> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend Float16 <: Parsable<Float16>
extend Float16 <: Parsable<Float16>
功能:此扩展主要用于实现将 Float16 类型字面量的字符串转换为 Float16 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Float16
功能:将 Float16 类型字面量的字符串转换为 Float16 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串不符合浮点数语法时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Float16>
功能:将 Float16 类型字面量的字符串转换为 Option<Float16> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend Float32 <: Parsable<Float32>
extend Float32 <: Parsable<Float32>
功能:此扩展主要用于实现将 Float32 类型字面量的字符串转换为 Float32 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Float32
功能:将 Float32 类型字面量的字符串转换为 Float32 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串不符合浮点数语法时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Float32>
功能:将 Float32 类型字面量的字符串转换为 Option<Float32> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend Float64 <: Parsable<Float64>
extend Float64 <: Parsable<Float64>
功能:此扩展主要用于实现将 Float64 类型字面量的字符串转换为 Float64 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Float64
功能:将 Float64 类型字面量的字符串转换为 Float64 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串不符合浮点数语法时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Float64>
功能:将 Float64 类型字面量的字符串转换为 Option<Float64> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend Int16 <: Parsable<Int16>
extend Int16 <: Parsable<Int16>
功能:此扩展主要用于实现将 Int16 类型字面量的字符串转换为 Int16 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Int16
功能:将 Int16 类型字面量的字符串转换为 Int16 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,首位为
+,转换失败,或转换后超出 Int16 范围,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Int16>
功能:将 Int16 类型字面量的字符串转换为 Option<Int16> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend Int32 <: Parsable<Int32>
extend Int32 <: Parsable<Int32>
功能:此扩展主要用于实现将 Int32 类型字面量的字符串转换为 Int32 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Int32
功能:将 Int32 类型字面量的字符串转换为 Int32 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,首位为
+,转换失败,或转换后超出 Int32 范围,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Int32>
功能:将 Int32 类型字面量的字符串转换为 Option<Int32> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend Int64 <: Parsable<Int64>
extend Int64 <: Parsable<Int64>
功能:此扩展主要用于实现将 Int64 类型字面量的字符串转换为 Int64 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Int64
功能:将 Int64 类型字面量的字符串转换为 Int64 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,首位为
+,转换失败,或转换后超出 Int64 范围,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Int64>
功能:将 Int64 类型字面量的字符串转换为 Option<Int64> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend Int8 <: Parsable<Int8>
extend Int8 <: Parsable<Int8>
功能:此扩展主要用于实现将 Int8 类型字面量的字符串转换为 Int8 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Int8
功能:将 Int8 类型字面量的字符串转换为 Int8 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,首位为
+,转换失败,或转换后超出 Int8 范围,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Int8>
功能:将 Int8 类型字面量的字符串转换为 Option<Int8> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend Rune <: Parsable<Rune>
extend Rune <: Parsable<Rune>
功能:此扩展主要用于实现将 Rune 类型字面量的字符串转换为 Rune 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): Rune
功能:将 Rune 类型字面量的字符串转换为 Rune 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,或转换失败时,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<Rune>
功能:将 Rune 类型字面量的字符串转换为 Option<Rune> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend UInt16 <: Parsable<UInt16>
extend UInt16 <: Parsable<UInt16>
功能:此扩展主要用于实现将 UInt16 类型字面量的字符串转换为 UInt16 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): UInt16
功能:将 UInt16 类型字面量的字符串转换为 UInt16 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,首位为
+或-,转换失败,或转换后超出 UInt16 范围,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<UInt16>
功能:将 UInt16 类型字面量的字符串转换为 Option<UInt16> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend UInt32 <: Parsable<UInt32>
extend UInt32 <: Parsable<UInt32>
功能:此扩展主要用于实现将 UInt32 类型字面量的字符串转换为 UInt32 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): UInt32
功能:将 UInt32 类型字面量的字符串转换为 UInt32 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,首位为
+或-,转换失败,或转换后超出 UInt32 范围,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<UInt32>
功能:将 UInt32 类型字面量的字符串转换为 Option<UInt32> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend UInt64 <: Parsable<UInt64>
extend UInt64 <: Parsable<UInt64>
功能:此扩展主要用于实现将 UInt64 类型字面量的字符串转换为 UInt64 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): UInt64
功能:将 UInt64 类型字面量的字符串转换为 UInt64 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,首位为
+或-,转换失败,或转换后超出 UInt64 范围,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<UInt64>
功能:将 UInt64 类型字面量的字符串转换为 Option<UInt64> 值。
参数:
- data: String - 要转换的字符串。
返回值:
extend UInt8 <: Parsable<UInt8>
extend UInt8 <: Parsable<UInt8>
功能:此扩展主要用于实现将 UInt8 类型字面量的字符串转换为 UInt8 值的相关操作函数。
父类型:
static func parse(String)
public static func parse(data: String): UInt8
功能:将 UInt8 类型字面量的字符串转换为 UInt8 值。
参数:
- data: String - 要转换的字符串。
返回值:
异常:
- IllegalArgumentException - 当字符串为空,首位为
+或-,转换失败,或转换后超出 UInt8 范围,或字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String)
public static func tryParse(data: String): Option<UInt8>
功能:将 UInt8 类型字面量的字符串转换为 Option<UInt8> 值。
参数:
- data: String - 要转换的字符串。
返回值:
interface RadixConvertible<T>
public interface RadixConvertible<T> {
static func parse(value: String, radix!: Int): T
static func tryParse(value: String, radix!: Int): Option<T>
func toString(radix!: Int): String
}
功能:本接口提供了统一的方法,以支持将指定进制的字符串解析为特定类型。
进制将以参数指定,不按字符串前缀指定,进制表示范围必须在 2-36 之间,否则会抛异常,超过十进制的表示按大或者小写英文字母序表示,即 10 个数字 + 26 个英文字母 = 36 进制,Int 系列的字符串可以以 +、- 开头,如果不以这两个符号开头则处理成 +,UInt 系列的字符串可以以 + 开头,如果以 - 开头会抛出异常。返回指定进制形式字符串,超过十进制的表示按小写英文字母序表示,即 10 个数字 + 26 个小写英文字母 = 36 进制。
本接口提供了 parse 和 tryParse 两套方法,parse 方法将在解析失败时抛出异常,tryParse 方法将返回值用 Option 包裹,解析失败时将返回 None。 本包内已经为Int64,UInt64 等基础类型实现该接口,可用于将字符串转换为这些类型。
static func parse(String, Int)
static func parse(value: String, radix!: Int): T
功能:从指定进制字符串中解析特定类型。
参数:
返回值:
- T - 转换后的值。
static func tryParse(String, Int)
static func tryParse(value: String, radix!: Int): Option<T>
功能:从指定进制字符串中解析特定类型。
参数:
返回值:
func toString(Int)
func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
extend Int8 <: RadixConvertible<Int8>
extend Int8 <: RadixConvertible<Int8>
功能:此扩展主要用于实现将 Int8 类型字面量的字符串转换为 Int8 值的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): Int8
功能:将 Int8 类型字面量的字符串转换为 Int8 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当字符串为空,进制超出范围,转换后超出 Int8 范围或字符串中含有无效的 UTF-8 字符,转换失败时,抛出异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): Option<Int8>
功能:将 Int8 类型字面量的字符串转换为 Option<Int8> 值。
参数:
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
异常:
- IllegalArgumentException - 当进制不合规时,抛出异常。
extend Int16 <: RadixConvertible<Int16>
extend Int16 <: RadixConvertible<Int16>
功能:此扩展主要用于实现将 Int16 类型字面量的字符串转换为 Int16 值的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): Int16
功能:将 Int16 类型字面量的字符串转换为 Int16 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当字符串为空、进制超出范围、转换后超出 Int16 范围、字符串中含有无效的 UTF-8 字符、转换失败时,抛出异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): Option<Int16>
功能:将 Int16 类型字面量的字符串转换为 Option<Int16> 值。
参数:
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
异常:
- IllegalArgumentException - 当进制不合规时,抛出异常。
extend Int32 <: RadixConvertible<Int32>
extend Int32 <: RadixConvertible<Int32>
功能:此扩展主要用于实现将 Int32 类型字面量的字符串转换为 Int32 值的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): Int32
功能:将 Int32 类型字面量的字符串转换为 Int32 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当字符串为空、进制超出范围、转换后超出 Int32 范围、字符串中含有无效的 UTF-8 字符、转换失败时,抛出异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): Option<Int32>
功能:将 Int32 类型字面量的字符串转换为 Option<Int32> 值。
参数:
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
异常:
- IllegalArgumentException - 当进制不合规时,抛出异常。
extend Int64 <: RadixConvertible<Int64>
extend Int64 <: RadixConvertible<Int64>
功能:此扩展主要用于实现将 Int64 类型字面量的字符串转换为 Int64 值的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): Int64
功能:将 Int64 类型字面量的字符串转换为 Int64 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当字符串为空、进制超出范围、转换后超出 Int64 范围、字符串中含有无效的 UTF-8 字符、转换失败时,抛出异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): Option<Int64>
功能:将 Int64 类型字面量的字符串转换为 Option<Int64> 值。
参数:
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
异常:
- IllegalArgumentException - 当进制不合规时,抛出异常。
extend UInt8 <: RadixConvertible<UInt8>
extend UInt8 <: RadixConvertible<UInt8>
功能:此扩展主要用于实现将 UInt8 类型字面量的字符串转换为 UInt8 值的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): UInt8
功能:将 UInt8 类型字面量的字符串转换为 UInt8 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当字符串为空、进制超出范围、首位为
-、转换后超出 UInt8 范围、字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): Option<UInt8>
功能:将 UInt8 类型字面量的字符串转换为 Option<UInt8> 值。
参数:
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
异常:
- IllegalArgumentException - 当进制不合规时,抛出异常。
extend UInt16 <: RadixConvertible<UInt16>
extend UInt16 <: RadixConvertible<UInt16>
功能:此扩展主要用于实现将 UInt16 类型字面量的字符串转换为 UInt16 值的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): UInt16
功能:将 UInt16 类型字面量的字符串转换为 UInt16 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当字符串为空、进制超出范围、首位为
-、转换后超出 UInt16 范围、字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): Option<UInt16>
功能:将 UInt16 类型字面量的字符串转换为 Option<UInt16> 值。
参数:
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
异常:
- IllegalArgumentException - 当进制不合规时,抛出异常。
extend UInt32 <: RadixConvertible<UInt32>
extend UInt32 <: RadixConvertible<UInt32>
功能:此扩展主要用于实现将 UInt32 类型字面量的字符串转换为 UInt32 值的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): UInt32
功能:将 UInt32 类型字面量的字符串转换为 UInt32 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当字符串为空、进制超出范围、首位为
-、转换后超出 UInt32 范围、字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): Option<UInt32>
功能:将 UInt32 类型字面量的字符串转换为 Option<UInt32> 值。
参数:
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
异常:
- IllegalArgumentException - 当进制不合规时,抛出异常。
extend UInt64 <: RadixConvertible<UInt64>
extend UInt64 <: RadixConvertible<UInt64>
功能:此扩展主要用于实现将 UInt64 类型字面量的字符串转换为 UInt64 值的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): UInt64
功能:将 UInt64 类型字面量的字符串转换为 UInt64 值。
参数:
返回值:
异常:
- IllegalArgumentException - 当字符串为空、进制超出范围、首位为
-、转换后超出 UInt64 范围、字符串中含有无效的 UTF-8 字符时,抛出异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): Option<UInt64>
功能:将 UInt64 类型字面量的字符串转换为 Option<UInt64> 值。
参数:
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:返回指定进制形式字符串。
参数:
- radix!: Int - 指定的进制。
返回值:
- String - 指定进制形式字符串。
异常:
- IllegalArgumentException - 当进制不合规时,抛出异常。
convert 包使用示例
format 使用示例
格式化整型
下面是格式化整型示例。
示例:
import std.convert.*
main(): Int64 {
var a: Int32 = -20
var res1 = a.format("-10")
var res2 = a.format("+10")
var res3 = (-20).format("10")
var res4 = a.format("-")
println("\"${res1}\"")
println("\"${res2}\"")
println("\"${res3}\"")
println("\"${res4}\"")
return 0
}
运行结果:
"-20 "
" -20"
" -20"
"-20"
格式化浮点型
下面是格式化浮点型示例。
示例:
import std.convert.*
main(): Int64 {
var a: Float16 = -0.34
var b: Float32 = .34
var c: Float64 = 3_0.3__4_
var d: Float64 = 20.00
/* 左对齐 */
var res1 = a.format("-20")
/* 右对齐 */
var res2 = b.format("+20")
/* 右对齐 */
var res3 = c.format("10")
/* 左对齐 */
var res4 = d.format("-10")
/* 正常输出 */
var res5 = d.format("-")
println("\"${res1}\"")
println("\"${res2}\"")
println("\"${res3}\"")
println("\"${res4}\"")
println("\"${res5}\"")
return 0
}
运行结果:
"-0.340088 "
" +0.340000"
" 30.340000"
"20.000000 "
"20.000000"
格式化字符型
下面是格式化字符型示例。
示例:
import std.convert.*
main(): Int64 {
var a: Rune = 'a'
var b: Rune = '-'
/* 左对齐 */
var res1 = a.format("-10")
/* 左对齐 */
var res2 = b.format("-10")
/* 右对齐 */
var res3 = a.format("10")
/* 右对齐 */
var res4 = b.format("10")
println("\"${res1}\"")
println("\"${res2}\"")
println("\"${res3}\"")
println("\"${res4}\"")
return 0
}
运行结果:
"a "
"- "
" a"
" -"
convert 使用示例
示例:
import std.convert.*
main(): Int64 {
var strBool_parse: String = "true"
var strBool_tryParse: String = "false"
var strChar_parse: String = "'a'"
var strChar_tryParse: String = "'\\u{00e2}'"
var strInt8_parse: String = "-128"
var strInt8_tryParse: String = "127"
var strInt16_parse: String = "-32768"
var strInt16_tryParse: String = "32767"
var strInt32_parse: String = "-2147483648"
var strInt32_tryParse: String = "2147483647"
var strInt64_parse: String = "-9223372036854775808"
var strInt64_tryParse: String = "9223372036854775807"
var strFloat16_parse: String = "-65504.0"
var strFloat16_tryParse: String = "65504.0"
var strFloat32_parse: String = "-3.14159"
var strFloat32_tryParse: String = "3.14159"
var strFloat64_parse: String = "-3.1415926"
var strFloat64_tryParse: String = "3.1415926"
var strUInt8_parse: String = "255"
var strUInt8_tryParse: String = "255"
var strUInt16_parse: String = "65535"
var strUInt16_tryParse: String = "65535"
var strUInt32_parse: String = "4294967295"
var strUInt32_tryParse: String = "4294967295"
var strUInt64_parse: String = "18446744073709551615"
var strUInt64_tryParse: String = "18446744073709551615"
println("After the conversion of parse, \"true\" became ${Bool.parse(strBool_parse)}")
println("After the conversion of tryParse, \"false\" became ${Bool.tryParse(strBool_tryParse)}")
println("After the conversion of parse, \"'a'\" became ${Rune.parse(strChar_parse)}")
println("After the conversion of tryParse, \"'\\u{00e2}'\" became ${Rune.tryParse(strChar_tryParse)}")
println("After the conversion of parse, \"-128\" became ${Int8.parse(strInt8_parse)}")
println("After the conversion of tryParse, \"127\" became ${Int8.tryParse(strInt8_tryParse)}")
println("After the conversion of parse, \"-32768\" became ${Int16.parse(strInt16_parse)}")
println("After the conversion of tryParse, \"32767\" became ${Int16.tryParse(strInt16_tryParse)}")
println("After the conversion of parse, \"-2147483648\" became ${Int32.parse(strInt32_parse)}")
println("After the conversion of tryParse, \"2147483647\" became ${Int32.tryParse(strInt32_tryParse)}")
println("After the conversion of parse, \"-9223372036854775808\" became ${Int64.parse(strInt64_parse)}")
println("After the conversion of tryParse, \"9223372036854775807\" became ${Int64.tryParse(strInt64_tryParse)}")
println("After the conversion of parse, \"-65504.0\" became ${Float16.parse(strFloat16_parse)}")
println("After the conversion of tryParse, \"65504.0\" became ${Float16.tryParse(strFloat16_tryParse)}")
println("After the conversion of parse, \"-3.14159\" became ${Float32.parse(strFloat32_parse)}")
println("After the conversion of tryParse, \"3.14159\" became ${Float32.tryParse(strFloat32_tryParse)}")
println("After the conversion of parse, \"-3.1415926\" became ${Float64.parse(strFloat64_parse)}")
println("After the conversion of tryParse, \"3.1415926\" became ${Float64.tryParse(strFloat64_tryParse)}")
println("After the conversion of parse, \"255\" became ${UInt8.parse(strUInt8_parse)}")
println("After the conversion of tryParse, \"255\" became ${UInt8.tryParse(strUInt8_tryParse)}")
println("After the conversion of parse, \"65535\" became ${UInt16.parse(strUInt16_parse)}")
println("After the conversion of tryParse, \"65535\" became ${UInt16.tryParse(strUInt16_tryParse)}")
println("After the conversion of parse, \"4294967295\" became ${UInt32.parse(strUInt32_parse)}")
println("After the conversion of tryParse, \"4294967295\" became ${UInt32.tryParse(strUInt32_tryParse)}")
println("After the conversion of parse, \"18446744073709551615\" became ${UInt64.parse(strUInt64_parse)}")
println("After the conversion of tryParse, \"18446744073709551615\" became ${UInt64.tryParse(strUInt64_tryParse)}")
return 0
}
运行结果:
After the conversion of parse, "true" became true
After the conversion of tryParse, "false" became Some(false)
After the conversion of parse, "'a'" became a
After the conversion of tryParse, "'\u{00e2}'" became Some(â)
After the conversion of parse, "-128" became -128
After the conversion of tryParse, "127" became Some(127)
After the conversion of parse, "-32768" became -32768
After the conversion of tryParse, "32767" became Some(32767)
After the conversion of parse, "-2147483648" became -2147483648
After the conversion of tryParse, "2147483647" became Some(2147483647)
After the conversion of parse, "-9223372036854775808" became -9223372036854775808
After the conversion of tryParse, "9223372036854775807" became Some(9223372036854775807)
After the conversion of parse, "-65504.0" became -65504.000000
After the conversion of tryParse, "65504.0" became Some(65504.000000)
After the conversion of parse, "-3.14159" became -3.141590
After the conversion of tryParse, "3.14159" became Some(3.141590)
After the conversion of parse, "-3.1415926" became -3.141593
After the conversion of tryParse, "3.1415926" became Some(3.141593)
After the conversion of parse, "255" became 255
After the conversion of tryParse, "255" became Some(255)
After the conversion of parse, "65535" became 65535
After the conversion of tryParse, "65535" became Some(65535)
After the conversion of parse, "4294967295" became 4294967295
After the conversion of tryParse, "4294967295" became Some(4294967295)
After the conversion of parse, "18446744073709551615" became 18446744073709551615
After the conversion of tryParse, "18446744073709551615" became Some(18446744073709551615)
std.crypto.cipher
功能介绍
std.crypto.cipher 包提供对称加解密通用接口。
API 列表
接口
| 接口名 | 功能 |
|---|---|
| BlockCipher | 此接口是分组加解密算法的通用接口。 |
接口
interface BlockCipher
public interface BlockCipher {
prop blockSize: Int64
prop algorithm: String
func encrypt(input: Array<Byte>): Array<Byte>
func decrypt(input: Array<Byte>): Array<Byte>
func encrypt(input: Array<Byte>, to!: Array<Byte>): Int64
func decrypt(input: Array<Byte>, to!: Array<Byte>): Int64
}
功能:分组加解密算法接口,继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
prop algorithm
prop algorithm: String
功能:获取分组加解密算法的算法名称。
类型:String
prop blockSize
prop blockSize: Int64
功能:分组块长度,单位字节。
类型:Int64
func encrypt(Array<Byte>)
func encrypt(input: Array<Byte>): Array<Byte>
功能:提供加密函数。
参数:
返回值:
func decrypt(Array<Byte>)
func decrypt(input: Array<Byte>): Array<Byte>
功能:提供解密函数。
参数:
返回值:
func encrypt(Array<Byte>, Array<Byte>)
func encrypt(input: Array<Byte>, to!: Array<Byte>): Int64
功能:提供加密函数。
参数:
返回值:
- Int64 - 输出长度。
func decrypt(Array<Byte>, Array<Byte>)
func decrypt(input: Array<Byte>, to!: Array<Byte>): Int64
功能:提供解密函数。
参数:
返回值:
- Int64 - 输出长度。
std.crypto.digest
功能介绍
std.crypto.digest 包提供常用摘要算法的通用接口,包括 MD5、SHA1、SHA224、SHA256、SHA384、SHA512、HMAC、SM3 等。
API 列表
函数
| 函数名 | 功能 |
|---|---|
| digest<T>(T, Array<Byte>) where T <: Digest | 提供 digest 泛型函数,实现用指定的摘要算法进行摘要运算。 |
| digest<T>(T, String) where T <: Digest (deprecated) | 提供 digest 泛型函数,实现用指定的摘要算法进行摘要运算。 |
| digest<T>(T, InputStream) where T <: Digest | 提供 digest 泛型函数,实现用指定的摘要算法对 InputStream 里的数据进行摘要运算。 |
接口
| 接口名 | 功能 |
|---|---|
| Digest | 此接口是摘要算法的通用接口。 |
函数
func digest<T>(T, Array<Byte>) where T <: Digest
public func digest<T>(algorithm: T, data: Array<Byte>): Array<Byte> where T <: Digest
功能:提供 digest 泛型函数,实现用指定的摘要算法进行摘要运算。
参数:
返回值:
示例:
import std.crypto.digest.*
main() {
let data: Array<Byte> = [1, 2, 3, 4, 5]
let mydigest = MyDigest()
let digestBytes = digest<MyDigest>(mydigest, data)
println(digestBytes)
}
// 自定义 Digest
class MyDigest <: Digest {
public prop size: Int64 {
get() { 0 }
}
public prop blockSize: Int64 {
get() { 0 }
}
public prop algorithm: String {
get() { "" }
}
public func write(buffer: Array<Byte>): Unit { println("buffer = ${buffer}") }
public func finish(to!: Array<Byte>): Unit { println("to = ${to}") }
public func finish(): Array<Byte> { [3,2,1] }
public func reset(): Unit {}
}
运行结果:
buffer = [1, 2, 3, 4, 5]
[3, 2, 1]
func digest<T>(T, String) where T <: Digest (deprecated)
public func digest<T>(algorithm: T, data: String): Array<Byte> where T <: Digest
功能:提供 digest 泛型函数,实现用指定的摘要算法进行摘要运算。
注意:
未来版本即将废弃不再使用,可使用 digest<T>(T, Array<Byte>) where T <: Digest 替代。
参数:
- algorithm: T - 具体的摘要算法。
- data: String - 待进行摘要运算的数据。
返回值:
func digest<T>(T, InputStream) where T <: Digest
public func digest<T>(algorithm: T, input: InputStream): Array<Byte> where T <: Digest
功能:提供 digest 泛型函数,实现用指定的摘要算法对 InputStream 里的数据进行摘要运算。
参数:
- algorithm: T - 具体的摘要算法。
- input: InputStream - 待进行摘要运算的 InputStream。
返回值:
示例:
import std.crypto.digest.*
import std.io.*
main() {
/* 将原始的字节数组 data 转换为一个输入流 BufferedInputStream */
let data: Array<Byte> = [1, 2, 3, 4, 5]
let byteBuffer = ByteBuffer(data)
let bufferedInputStream = BufferedInputStream(byteBuffer)
let mydigest = MyDigest()
let digestBytes = digest<MyDigest>(mydigest, bufferedInputStream)
println(digestBytes)
}
// 自定义 Digest
class MyDigest <: Digest {
public prop size: Int64 {
get() { 0 }
}
public prop blockSize: Int64 {
get() { 2 }
}
public prop algorithm: String {
get() { "" }
}
public func write(buffer: Array<Byte>): Unit { println("buffer = ${buffer}") }
public func finish(to!: Array<Byte>): Unit { println("to = ${to}") }
public func finish(): Array<Byte> { [3,2,1] }
public func reset(): Unit {}
}
运行结果:
buffer = [1, 2]
buffer = [3, 4]
buffer = [5]
[3, 2, 1]
接口
interface Digest
public interface Digest {
prop size: Int64
prop blockSize: Int64
prop algorithm: String
func write(buffer: Array<Byte>): Unit
func finish(to!: Array<Byte>): Unit
func finish(): Array<Byte>
func reset(): Unit
}
功能:摘要算法接口,继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
prop algorithm
prop algorithm: String
功能:获取摘要算法的算法名称。
类型:String
prop blockSize
prop blockSize: Int64
功能:返回 Block 块长度,单位字节。
类型:Int64
prop size
prop size: Int64
功能:返回生成的摘要信息长度,单位字节。
类型:Int64
func finish()
func finish(): Array<Byte>
功能:返回生成的 digest 值。
返回值:
func finish(Array<Byte>)
func finish(to!: Array<Byte>): Unit
功能:获取生成的信息摘要值,注意调用 finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。
参数:
func reset()
func reset(): Unit
功能:重置 digest 对象到初始状态。
func write(Array<Byte>)
func write(buffer: Array<Byte>): Unit
功能:使用给定的 buffer 更新 digest 对象。
std.database.sql
功能介绍
database.sql 包提供仓颉访问数据库的接口。
本包提供 SQL/CLI 的通用接口,配合数据库驱动 Driver 完成对数据库的各项操作。
注意:
当前仅支持 SQL/CLI 接口。
SQL 数据类型和仓颉数据类型对应表如下:
| SQL | CDBC/Cangjie | SqlDataType | 说明 |
|---|---|---|---|
RUNE | String | SqlChar | - |
VARCHAR | String | SqlVarchar | - |
CLOB | io.InputStream | SqlClob | - |
BINARY | Array<Byte> | SqlBinary | - |
VARBINARY | Array<Byte> | SqlVarBinary | - |
BLOB | io.InputStream | SqlBlob | - |
NUMERIC | Decimal | SqlDecimal | - |
DECIMAL | Decimal | SqlDecimal | - |
BOOLEAN | Bool | SqlBool | - |
TINYINT | Int8 | SqlByte | - |
SMALLINT | Int16 | SqlSmallInt | - |
INTEGER | Int32 | SqlInteger | - |
BIGINT | Int64 | SqlBigInt | - |
REAL | Float32 | SqlReal | - |
DOUBLE | Float64 | SqlDouble | - |
DATE | time.DateTime | SqlDate | 值支持 YEAR,MONTH,DAY。 |
TIME | time.DateTime | SqlTime | 值支持 HOUR,MINUTE,SECOND(不包括 TIME ZONE)。 |
TIMETZ | time.DateTime | SqlTimeTz | 值支持 HOUR,MINUTE,SECOND(包括 TIME ZONE)。 |
TIMESTAMP | time.DateTime | SqlTimestamp | 值支持 YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,TIME ZONE。 |
INTERVAL | time.Duration | SqlInterval | 年-月间隔或者日-时间隔。 |
API列表
接口
| 接口名 | 功能 |
|---|---|
| ColumnInfo | 执行 Select/Query 语句返回结果的列信息。 |
| Connection | 数据库连接接口。 |
| Datasource | 数据源接口。 |
| Driver | 数据库驱动接口。 |
| QueryResult | 执行 Select 语句产生的结果接口。 |
| SqlDbType (deprecated) | 所有 sql 数据类型的父类。 |
| SqlNullableDbType (deprecated) | 允许 null 值的 sql 数据类型父类。 |
| Statement | sql 语句预执行接口。 |
| Transaction | 定义数据库事务的核心行为。 |
| UpdateResult | 执行 Insert、Update、Delete 语句产生的结果接口。 |
类
| 类名 | 功能 |
|---|---|
| DriverManager | 支持运行时根据驱动名获取数据库驱动实例。 |
| PooledDatasource | 数据库连接池类,提供数据库连接池能力。 |
| SqlOption | 预定义的 sql 选项名称和值。 |
| SqlBigInt (deprecated) | 大整数,对应仓颉 Int64 类型。 |
| SqlBinary (deprecated) | 定长二进制字符串,对应仓颉 Array<Byte> 类型。 |
| SqlBlob (deprecated) | 变长超大二进制字符串(BINARY LARGE OBJECT),对应仓颉 InputStream 类型。 |
| SqlBool (deprecated) | 布尔类型,对应仓颉 Bool 类型。 |
| SqlByte (deprecated) | 字节,对应仓颉 Int8 类型。 |
| SqlChar (deprecated) | 定长字符串,对应仓颉 String 类型。 |
| SqlClob (deprecated) | 变长超大字符串(RUNE LARGE OBJECT),对应仓颉 InputStream 类型。 |
| SqlDate (deprecated) | 日期,仅年月日有效,对应仓颉 DateTime 类型。 |
| SqlDecimal (deprecated) | 高精度数,对应仓颉 Decimal 类型。 |
| SqlDouble (deprecated) | 双精度数,对应仓颉 Float64 类型。 |
| SqlInteger (deprecated) | 中整数,对应仓颉 Int32 类型。 |
| SqlInterval (deprecated) | 时间间隔,对应仓颉 Duration 类型。 |
| SqlReal (deprecated) | 浮点数,对应仓颉 Float32 类型。 |
| SqlSmallInt (deprecated) | 小整数,对应仓颉 Int16 类型。 |
| SqlTime (deprecated) | 时间,仅时分秒毫秒有效,对应仓颉 DateTime 类型。 |
| SqlTimestamp (deprecated) | 时间戳,对应仓颉 DateTime 类型。 |
| SqlTimeTz (deprecated) | 带时区的时间,仅时分秒毫秒时区有效,对应仓颉 DateTime 类型。 |
| SqlVarBinary (deprecated) | 变长二进制字符串,对应仓颉 Array<Byte> 类型。 |
| SqlVarchar (deprecated) | 变长字符串,对应仓颉 String 类型。 |
| SqlNullableBigInt (deprecated) | 大整数,对应仓颉 Int64 类型,可为数据库 Null 值。 |
| SqlNullableBinary (deprecated) | 定长二进制字符串,对应仓颉 Array<Byte> 类型,可为数据库 Null 值。 |
| SqlNullableBlob (deprecated) | 变长超大二进制字符串(BINARY LARGE OBJECT),对应仓颉 InputStream 类型,可为数据库 Null 值。 |
| SqlNullableBool (deprecated) | 布尔类型,对应仓颉 Bool 类型,可为数据库 Null 值。 |
| SqlNullableByte (deprecated) | 字节,对应仓颉 Int8 类型,可为数据库 Null 值。 |
| SqlNullableChar (deprecated) | 定长二进制字符串,对应仓颉 String 类型,可为数据库 Null 值。 |
| SqlNullableClob (deprecated) | 变长超大字符串(RUNE LARGE OBJECT),对应仓颉 InputStream 类型,可为数据库 Null 值。 |
| SqlNullableDate (deprecated) | 日期,仅年月日有效,对应仓颉 DateTime 类型,可为数据库 Null 值。 |
| SqlNullableDecimal (deprecated) | 高精度数,对应仓颉 Decimal 类型,可为数据库 Null 值。 |
| SqlNullableDouble (deprecated) | 双精度数,对应仓颉 Float64 类型,可为数据库 Null 值。 |
| SqlNullableInteger (deprecated) | 中整数,对应仓颉 Int32 类型,可为数据库 Null 值。 |
| SqlNullableInterval (deprecated) | 时间间隔,对应仓颉 Duration 类型,可为数据库 Null 值。 |
| SqlNullableReal (deprecated) | 浮点数,对应仓颉 Float32 类型,可为数据库 Null 值。 |
| SqlNullableSmallInt (deprecated) | 小整数,对应仓颉 Int16 类型,可为数据库 Null 值。 |
| SqlNullableTime (deprecated) | 时间,仅时分秒毫秒有效,对应仓颉 DateTime 类型,可为数据库 Null 值。 |
| SqlNullableTimestamp (deprecated) | 时间戳,对应仓颉 DateTime 类型,可为数据库 Null 值。 |
| SqlNullableTimeTz (deprecated) | 带时区的时间,仅时分秒毫秒时区有效,对应仓颉 DateTime 类型,可为数据库 Null 值。 |
| SqlNullableVarBinary (deprecated) | 变长二进制字符串,对应仓颉 Array<Byte> 类型,可为数据库 Null 值。 |
| SqlNullableVarchar (deprecated) | 变长字符串,对应仓颉 String 类型,可为数据库 Null 值。 |
枚举
| 枚举名 | 功能 |
|---|---|
| ConnectionState | 描述与数据源连接的当前状态。 |
| TransactionAccessMode | 事务的读写模式。 |
| TransactionDeferrableMode | 事务的延迟模式。 |
| TransactionIsoLevel | 定义了数据库系统中,一个事务中操作的结果在何时以何种方式对其他并发事务操作可见。 |
异常类
| 异常类名 | 功能 |
|---|---|
| SqlException | 用于处理 sql 相关的异常。 |
接口
interface ColumnInfo
public interface ColumnInfo {
prop displaySize: Int64
prop length: Int64
prop name: String
prop nullable: Bool
prop scale: Int64
prop typeName: String
}
功能:执行 Select/Query 语句返回结果的列信息。
prop displaySize
prop displaySize: Int64
功能:获取列值的最大显示长度,如果无限制,则应该返回 Int64.Max (仍然受数据库的限制)。
类型:Int64
prop length
prop length: Int64
功能:获取列值大小。
说明:
- 对于数值数据,表示最大精度。
- 对于字符数据,表示以字符为单位的长度。
- 对于日期时间数据类型,表示字符串表示形式的最大字符长度。
- 对于二进制数据,表示以字节为单位的长度。
- 对于 RowID 数据类型,表示以字节为单位的长度。
- 对于列大小不适用的数据类型,返回 0。
类型:Int64
prop name
prop name: String
功能:列名或者别名。
类型:String
prop nullable
prop nullable: Bool
功能:表示列值是否允许数据库 Null 值。
类型:Bool
prop scale
prop scale: Int64
功能:获取列值的小数长度,如果无小数部分,返回 0。
类型:Int64
prop typeName
prop typeName: String
功能:获取列类型名称,如果在仓颉中有对应数据类型的定义,返回对应类型的 toString 函数的返回值;如果在仓颉中无对应数据类型的定义,由数据库驱动定义。
类型:String
interface Connection
public interface Connection <: Resource {
prop state: ConnectionState
func createTransaction(): Transaction
func getMetaData(): Map<String, String>
func prepareStatement(sql: String): Statement
}
功能:数据库连接接口。
继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
父类型:
prop state
prop state: ConnectionState
功能:描述与数据源连接的当前状态。
func createTransaction()
func createTransaction(): Transaction
功能:创建事务对象。
返回值:
- Transaction - 事务对象。
异常:
- SqlException - 当已经处于事务状态,不支持并行事务时,抛出异常。
func getMetaData()
func getMetaData(): Map<String, String>
功能:返回连接到的数据源元数据。
返回值:
func prepareStatement(String)
func prepareStatement(sql: String): Statement
功能:通过传入的 sql 语句,返回一个预执行的 Statement 对象实例。
参数:
- sql: String - 预执行的 sql 语句,sql 语句的参数只支持
?符号占位符。
返回值:
- Statement - 一个可以执行 sql 语句的实例对象。
异常:
- SqlException - 当 sql 语句包含不认识的字符时,抛出异常。
interface Datasource
public interface Datasource <: Resource {
func connect(): Connection
func setOption(key: String, value: String): Unit
}
功能:数据源接口。
继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
父类型:
func connect()
func connect(): Connection
功能:返回一个可用的连接。
返回值:
- Connection - 数据库连接实例。
func setOption(String, String)
func setOption(key: String, value: String): Unit
功能:设置连接选项。
参数:
interface Driver
public interface Driver {
prop name: String
prop preferredPooling: Bool
prop version: String
func open(connectionString: String, opts: Array<(String, String)>): Datasource
}
功能:数据库驱动接口。
继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
prop name
prop name: String
功能:驱动名称。
类型:String
prop preferredPooling
prop preferredPooling: Bool
功能:指示驱动程序是否与连接池亲和。
当该属性为 false 时,不建议使用连接池进行管理。例如,对于某些数据库驱动(如 SQLite),连接池化的收益不明显,因此不建议使用连接池。
类型:Bool
prop version
prop version: String
功能:驱动版本。
类型:String
func open(String, Array<(String, String)>)
func open(connectionString: String, opts: Array<(String, String)>): Datasource
功能:通过 connectionString 和选项打开数据源。
参数:
返回值:
- Datasource - 数据源实例。
interface QueryResult
public interface QueryResult <: Resource {
prop columnInfos: Array<ColumnInfo>
func next(values: Array<SqlDbType>): Bool
func next(): Bool
func get<T>(index: Int): T
func getOrNull<T>(index: Int): ?T
}
功能:执行 Select 语句产生的结果接口。
继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
父类型:
prop columnInfos
prop columnInfos: Array<ColumnInfo>
功能:返回结果集的列信息,比如列名,列类型,列长度,是否允许数据库 Null 值等。
类型:Array<ColumnInfo>
func get<T>(Int)
func get<T>(index: Int): T
功能:从结果集的当前行检索指定列的值。
返回值:
- T -
T类型的实例。
func getOrNull<T>(Int)
func getOrNull<T>(index: Int): ?T
功能:从结果集的当前行检索指定列的值,数据库列允许 SQL NULL。
返回值:
- ?T -
T类型的实例,如果为空,返回 None。
异常:
- SqlException - 索引超出列范围,或者行数据未准备好时,抛出异常。
func next()
func next(): Bool
功能:向后移动一行,必须先调用一次 next() 才能移动到第一行,第二次调用移动到第二行,依此类推。当返回 true 时,驱动会在结果集的当前行填入数据,当返回 false 时结束,且不会修改结果集当前行的内容。
返回值:
- Bool - 下一行存在数据则返回
true,否则返回false。
func next(Array<SqlDbType>) (deprecated)
func next(values: Array<SqlDbType>): Bool
功能:向后移动一行,必须先调用一次 next 才能移动到第一行,第二次调用移动到第二行,依此类推。当返回 true 时,驱动会在 values 中填入行数据;当返回 false 时结束,且不会修改 values 的内容。
注意:
未来版本即将废弃不再使用,可使用 next() 替代。
参数:
- values: Array<SqlDbType (deprecated)> - sql 数据类型的数据列表。
返回值:
- Bool - 下一行存在数据则返回
true,否则返回false。
interface SqlDbType (deprecated)
public interface SqlDbType {
prop name: String
}
功能:所有 sql 数据类型的父类。
注意:
未来版本即将废弃不再使用。
要扩展用户定义的类型,请继承 SqlDbType (deprecated) 或 SqlNullableDbType (deprecated)。
说明:
SqlDbType (deprecated) 接口所有实现类型都必须具有公共
value属性。每种 sql 数据类型实现类,同时满足以下条件:
- 只有一个参数的构造函数,参数类型为
T(T为仓颉语言支持的类型)。public修饰的value属性,其类型必须上一条中使用的参数类型一致,其值为对应仓颉类型的值。- 如果数据类型允许
null值,继承 SqlNullableDbType (deprecated),null值时,value字段的值为 Option<T>.None。
prop name
prop name: String
功能:获取类型名称。
类型:String
interface SqlNullableDbType (deprecated)
public interface SqlNullableDbType <: SqlDbType
功能:允许 null 值的 sql 数据类型父类。
注意:
未来版本即将废弃不再使用。
如果为 null 值,value 属性值为 Option.None。
父类型:
interface Statement
public interface Statement <: Resource {
prop parameterColumnInfos: Array<ColumnInfo>
func query(params: Array<SqlDbType>): QueryResult
func setOption(key: String, value: String): Unit
func update(params: Array<SqlDbType>): UpdateResult
func set<T>(index: Int, value: T): Unit
func setNull(index: Int): Unit
func update(): UpdateResult
func query(): QueryResult
}
功能:sql 语句预执行接口。
Statement 绑定了一个 Connection ,继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
父类型:
prop parameterColumnInfos
prop parameterColumnInfos: Array<ColumnInfo>
功能:预执行 sql 语句中,占位参数的列信息,比如列名,列类型,列长度,是否允许数据库 Null 值等。
类型:Array<ColumnInfo>
func query()
func query(): QueryResult
功能:执行 sql 语句,得到查询结果。
返回值:
- QueryResult - 查询结果。
异常:
- SqlException - 当执行过程中发生了异常情况,比如网络中断,服务器超时,参数个数不正确时,抛出异常。
func query(Array<SqlDbType>) (deprecated)
func query(params: Array<SqlDbType>): QueryResult
功能:执行 sql 语句,得到查询结果。
注意:
未来版本即将废弃不再使用,可使用 query() 替代。
参数:
- params: Array<SqlDbType (deprecated)> - sql 数据类型的数据列表,用于替换 sql 语句中的
?占位符。
返回值:
- QueryResult - 查询结果。
异常:
- SqlException - 当执行过程中发生了异常情况,比如网络中断,服务器超时,参数个数不正确时,抛出异常。
func set<T>(Int, T)
func set<T>(index: Int, value: T): Unit
功能:设置 sql 参数,将仓颉的数据类型转成数据库的数据类型。
参数:
- index: Int - 参数所在序列。
- value: T - 参数值。
func setNull(Int)
func setNull(index: Int): Unit
功能:将指定位置处的语句参数设置为 SQL NULL。
参数:
- index: Int - 参数所在序列。
func setOption(String, String)
func setOption(key: String, value: String): Unit
功能:设置预执行 sql 语句选项。
参数:
func update(Array<SqlDbType>) (deprecated)
func update(params: Array<SqlDbType>): UpdateResult
功能:执行 sql 语句,得到更新结果。
注意:
未来版本即将废弃不再使用,可使用 update() 替代。
参数:
- params: Array<SqlDbType (deprecated)> - sql 数据类型的数据列表,用于替换 sql 语句中的
?占位符。
返回值:
- UpdateResult - 更新结果。
异常:
- SqlException - 当执行过程中发生了异常情况,比如网络中断、服务器超时,参数个数不正确时,抛出异常。
func update()
func update(): UpdateResult
功能:执行 sql 语句,得到更新结果。
返回值:
- UpdateResult - 更新结果。
异常:
- SqlException - 当执行过程中发生了异常情况,比如网络中断,服务器超时,参数个数不正确时,抛出异常。
interface Transaction
public interface Transaction {
mut prop accessMode: TransactionAccessMode
mut prop deferrableMode: TransactionDeferrableMode
mut prop isoLevel: TransactionIsoLevel
func begin(): Unit
func commit(): Unit
func release(savePointName: String): Unit
func rollback(): Unit
func rollback(savePointName: String): Unit
func save(savePointName: String): Unit
}
功能:定义数据库事务的核心行为。
继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
prop accessMode
mut prop accessMode: TransactionAccessMode
功能:获取数据库事务访问模式。
prop deferrableMode
mut prop deferrableMode: TransactionDeferrableMode
功能:获取数据库事务延迟模式。
prop isoLevel
mut prop isoLevel: TransactionIsoLevel
功能:获取数据库事务隔离级别。
func begin()
func begin(): Unit
功能:开始数据库事务。
异常:
- SqlException - 当提交事务时服务器端发生错误,以及当事务已提交或回滚或连接已断开时,抛出异常。
func commit()
func commit(): Unit
功能:提交数据库事务。
异常:
- SqlException - 当提交事务时服务器端发生错误,以及当事务已提交或回滚或连接已断开时,抛出异常。
func release(String)
func release(savePointName: String): Unit
功能:销毁先前在当前事务中定义的保存点。这允许系统在事务结束之前回收一些资源。
参数:
- savePointName: String - 保存点名称。
异常:
- SqlException - 当提交事务时服务器端发生错误,以及当事务已提交或回滚或连接已断开时,抛出异常。
func rollback()
func rollback(): Unit
功能:从挂起状态回滚事务。
异常:
- SqlException - 当提交事务时服务器端发生错误,以及当事务已提交或回滚或连接已断开时,抛出异常。
func rollback(String)
func rollback(savePointName: String): Unit
功能:回滚事务至指定保存点名称。
参数:
- savePointName: String - 保存点名称。
异常:
- SqlException - 当提交事务时服务器端发生错误,以及当事务已提交或回滚或连接已断开时,抛出异常。
func save(String)
func save(savePointName: String): Unit
功能:在事务中创建一个指定名称的保存点,可用于回滚此保存点之后的事务。
参数:
- savePointName: String - 保存点名称。
异常:
- SqlException - 当提交事务时服务器端发生错误,以及当事务已提交或回滚或连接已断开时,抛出异常。
interface UpdateResult
public interface UpdateResult {
prop lastInsertId: Int64
prop rowCount: Int64
}
功能:执行 Insert、Update、Delete 语句产生的结果接口。
继承该接口的 class、interface、struct 也需要遵守该接口中函数的入参及返回值定义。
prop lastInsertId
prop lastInsertId: Int64
功能:执行 Insert 语句自动生成的最后 row ID ,如果不支持则 row ID 为 0。
类型:Int64
prop rowCount
prop rowCount: Int64
功能:执行 Insert、Update、Delete 语句影响的行数。
类型:Int64
类
class DriverManager
public class DriverManager
功能:支持运行时根据驱动名获取数据库驱动实例。
static func deregister(String)
public static func deregister(driverName: String): Unit
功能:按名称取消注册数据库驱动(如果存在)。本函数并发安全。
参数:
- driverName: String - 驱动名称。
static func drivers()
public static func drivers(): Array<String>
功能:返回已注册数据库驱动名称的列表(名称已按照字典序排序)。本方法并发安全。
返回值:
static func getDriver(String)
public static func getDriver(driverName: String): Option<Driver>
功能:按名称获取已注册的数据库驱动,如果不存在返回 None。本函数并发安全。
参数:
- driverName: String - 驱动名称。
返回值:
static func register(String, Driver)
public static func register(driverName: String, driver: Driver): Unit
功能:按名称和驱动实例注册数据库驱动,名称和实例一一对应。本方法并发安全。
参数:
异常:
- SqlException - 当指定的驱动名称已经存在时,抛出异常。
class PooledDatasource
public class PooledDatasource <: Datasource {
public init(datasource: Datasource)
}
功能:数据库连接池类,提供数据库连接池能力。
父类型:
prop connectionTimeout
public mut prop connectionTimeout: Duration
功能:从池中获取连接的超时时间。
类型:Duration
异常:
- ArithmeticException - 当该属性被设置为 Duration.Max 或 Duration.Min 时,抛此异常。
- SqlException - 当获取连接超时后,抛出此异常。
prop idleTimeout
public mut prop idleTimeout: Duration
功能:允许连接在池中闲置的最长时间,超过这个时间的空闲连接可能会被回收。
类型:Duration
prop keepaliveTime
public mut prop keepaliveTime: Duration
功能:检查空闲连接健康状况的间隔时间,防止它被数据库或网络基础设施超时。
类型:Duration
prop maxIdleSize
public mut prop maxIdleSize: Int32
功能:最大空闲连接数量,超过这个数量的空闲连接会被关闭,负数或0表示无限制。
类型:Int32
prop maxLifeTime
public mut prop maxLifeTime: Duration
功能:自连接创建以来的最大持续时间,在该持续时间之后,连接将自动关闭。
类型:Duration
prop maxSize
public mut prop maxSize: Int32
功能:连接池最大连接数量,负数或0表示无限制。
类型:Int32
init(Datasource)
public init(datasource: Datasource)
功能:通过数据源 datasource 构造一个 PooledDatasource 实例,入参必须为 Datasource 对象。
参数:
- datasource: Datasource - 数据源。
func close()
public func close(): Unit
功能:关闭连接池中的所有连接并阻止其他连接请求。调用该方法会阻塞至所有连接关闭并归还到连接池。
func connect()
public func connect(): Connection
功能:获取一个连接。
返回值:
- Connection - 获取到的连接。
func isClosed()
public func isClosed(): Bool
功能:判断连接是否关闭。
返回值:
- Bool - 连接是否关闭。
func setOption(String, String)
public func setOption(key: String, value: String): Unit
功能:设置数据库驱动连接选项(公钥在 SqlOption 中预定义)。
参数:
class SqlBigInt (deprecated)
public class SqlBigInt <: SqlDbType {
public init(v: Int64)
}
功能:大整数,对应仓颉 Int64 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlBigInt (deprecated)。
类型:String
prop value
public mut prop value: Int64
功能:该数据的值。
类型:Int64
init(Int64)
public init(v: Int64)
功能:根据传入参数 v 构造一个 SqlBigInt (deprecated) 实例。
参数:
- v: Int64 - 传入的数据。
class SqlBinary (deprecated)
public class SqlBinary <: SqlDbType {
public init(v: Array<Byte>)
}
功能:定长二进制字符串,对应仓颉 Array<Byte> 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlBinary (deprecated)。
类型:String
prop value
public mut prop value: Array<Byte>
功能:该数据的值。
init(Array<Byte>)
public init(v: Array<Byte>)
功能:根据传入参数 v 构造一个 SqlBinary (deprecated) 实例。
参数:
class SqlBlob (deprecated)
public class SqlBlob <: SqlDbType {
public init(v: InputStream)
}
功能:变长超大二进制字符串(BINARY LARGE OBJECT),对应仓颉 InputStream 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlBlob (deprecated)。
类型:String
prop value
public mut prop value: InputStream
功能:该数据的值。
类型:InputStream
init(InputStream)
public init(v: InputStream)
功能:根据传入参数 v 构造一个 SqlBlob (deprecated) 实例。
参数:
- v: InputStream - 传入的数据。
class SqlBool (deprecated)
public class SqlBool <: SqlDbType {
public init(v: Bool)
}
功能:布尔类型,对应仓颉 Bool 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlBool(deprecated)。
类型:String
prop value
public mut prop value: Bool
功能:该数据的值。
类型:Bool
init(Bool)
public init(v: Bool)
功能:根据传入参数 v 构造一个 SqlBool(deprecated) 实例。
参数:
- v: Bool - 传入的数据。
class SqlByte (deprecated)
public class SqlByte <: SqlDbType {
public init(v: Int8)
}
功能:字节,对应仓颉 Int8 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlByte (deprecated)。
类型:String
prop value
public mut prop value: Int8
功能:该数据的值。
类型:Int8
init(Int8)
public init(v: Int8)
功能:根据传入参数 v 构造一个 SqlByte (deprecated) 实例。
参数:
- v: Int8 - 传入的数据。
class SqlChar (deprecated)
public class SqlChar <: SqlDbType {
public init(v: String)
}
功能:定长字符串,对应仓颉 String 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlChar (deprecated)。
类型:String
prop value
public mut prop value: String
功能:该数据的值。
类型:String
init(String)
public init(v: String)
功能:根据传入参数 v 构造一个 SqlChar (deprecated) 实例。
参数:
- v: String - 传入的数据。
class SqlClob (deprecated)
public class SqlClob <: SqlDbType {
public init(v: InputStream)
}
功能:变长超大字符串(RUNE LARGE OBJECT),对应仓颉 InputStream 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlClob。
类型:String
prop value
public mut prop value: InputStream
功能:该数据的值。
类型:InputStream
init(InputStream)
public init(v: InputStream)
功能:根据传入参数 v 构造一个 SqlClob 实例。
参数:
- v: InputStream - 传入的数据。
class SqlDate (deprecated)
public class SqlDate <: SqlDbType {
public init(v: DateTime)
}
功能:日期,仅年月日有效,对应仓颉 DateTime 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlDate (deprecated)。
类型:String
prop value
public mut prop value: DateTime
功能:该数据的值。
类型:DateTime
init(DateTime)
public init(v: DateTime)
功能:根据传入参数 v 构造一个 SqlDate (deprecated) 实例。
参数:
- v: DateTime - 传入的数据。
class SqlDecimal (deprecated)
public class SqlDecimal <: SqlDbType {
public init(v: Decimal)
}
功能:高精度数,对应仓颉 Decimal 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlDecimal (deprecated)。
类型:String
prop value
public mut prop value: Decimal
功能:该数据的值。
类型:Decimal
init(Decimal)
public init(v: Decimal)
功能:根据传入参数 v 构造一个 SqlDecimal (deprecated) 实例。
参数:
- v: Decimal - 传入的数据。
class SqlDouble (deprecated)
public class SqlDouble <: SqlDbType {
public init(v: Float64)
}
功能:双精度数,对应仓颉 Float64 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlDouble (deprecated)。
类型:String
prop value
public mut prop value: Float64
功能:该数据的值。
类型:Float64
init(Float64)
public init(v: Float64)
功能:根据传入参数 v 构造一个 SqlDouble (deprecated) 实例。
参数:
- v: Float64 - 传入的数据。
class SqlInteger (deprecated)
public class SqlInteger <: SqlDbType {
public init(v: Int32)
}
功能:中整数,对应仓颉 Int32 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlInteger (deprecated)。
类型:String
prop value
public mut prop value: Int32
功能:该数据的值。
类型:Int32
init(Int32)
public init(v: Int32)
功能:根据传入参数 v 构造一个 SqlInteger (deprecated) 实例。
参数:
- v: Int32 - 传入的数据。
class SqlInterval (deprecated)
public class SqlInterval <: SqlDbType {
public init(v: Duration)
}
功能:时间间隔,对应仓颉 Duration 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlInterval (deprecated)。
类型:String
prop value
public mut prop value: Duration
功能:该数据的值。
类型:Duration
init(Duration)
public init(v: Duration)
功能:根据传入参数 v 构造一个 SqlInterval (deprecated) 实例。
参数:
- v: Duration - 传入的数据。
class SqlNullableBigInt (deprecated)
public class SqlNullableBigInt <: SqlNullableDbType {
public init(v: ?Int64)
}
功能:大整数,对应仓颉 Int64 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableBigInt (deprecated)。
类型:String
prop value
public mut prop value: ?Int64
功能:该数据的值。
类型:?Int64
init(?Int64)
public init(v: ?Int64)
功能:根据传入参数 v 构造一个 SqlNullableBigInt (deprecated) 实例。
参数:
- v: ?Int64 - 传入的数据。
class SqlNullableBinary (deprecated)
public class SqlNullableBinary <: SqlNullableDbType {
public init(v: ?Array<Byte>)
}
功能:定长二进制字符串,对应仓颉 Array<Byte> 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableBinary (deprecated)。
类型:String
prop value
public mut prop value: ?Array<Byte>
功能:该数据的值。
init(?Array<Byte>)
public init(v: ?Array<Byte>)
功能:根据传入参数 v 构造一个 SqlNullableBinary (deprecated) 实例。
参数:
class SqlNullableBlob (deprecated)
public class SqlNullableBlob <: SqlNullableDbType {
public init(v: ?InputStream)
}
功能:变长超大二进制字符串(BINARY LARGE OBJECT),对应仓颉 InputStream 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableBlob (deprecated)。
类型:String
prop value
public mut prop value: ?InputStream
功能:该数据的值。
类型:?InputStream
init(?InputStream)
public init(v: ?InputStream)
功能:根据传入参数 v 构造一个 SqlNullableBlob (deprecated) 实例。
参数:
- v: ?InputStream - 传入的数据。
class SqlNullableBool (deprecated)
public class SqlNullableBool <: SqlNullableDbType {
public init(v: ?Bool)
}
功能:布尔类型,对应仓颉 Bool 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableBool (deprecated)。
类型:String
prop value
public mut prop value: ?Bool
功能:该数据的值。
类型:?Bool
init(?Bool)
public init(v: ?Bool)
功能:根据传入参数 v 构造一个 SqlNullableBool (deprecated) 实例。
参数:
- v: ?Bool - 传入的数据。
class SqlNullableByte (deprecated)
public class SqlNullableByte <: SqlNullableDbType {
public init(v: ?Int8)
}
功能:字节,对应仓颉 Int8 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableByte (deprecated)。
类型:String
prop value
public mut prop value: ?Int8
功能:该数据的值。
类型:?Int8
init(?Int8)
public init(v: ?Int8)
功能:根据传入参数 v 构造一个 SqlNullableByte (deprecated) 实例。
参数:
- v: ?Int8 - 传入的数据。
class SqlNullableChar (deprecated)
public class SqlNullableChar <: SqlNullableDbType {
public init(v: ?String)
}
功能:定长字符串,对应仓颉 String 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableChar (deprecated)。
类型:String
prop value
public mut prop value: ?String
功能:该数据的值。
类型:?String
init(?String)
public init(v: ?String)
功能:根据传入参数 v 构造一个 SqlNullableChar (deprecated) 实例。
参数:
- v: ?String - 传入的数据。
class SqlNullableClob (deprecated)
public class SqlNullableClob <: SqlNullableDbType {
public init(v: ?InputStream)
}
功能:变长超大字符串(RUNE LARGE OBJECT),对应仓颉 InputStream 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableClob (deprecated)。
类型:String
prop value
public mut prop value: ?InputStream
功能:该数据的值。
类型:?InputStream
init(?InputStream)
public init(v: ?InputStream)
功能:根据传入参数 v 构造一个 SqlNullableClob (deprecated) 实例。
参数:
- v: ?InputStream - 传入的数据。
class SqlNullableDate (deprecated)
public class SqlNullableDate <: SqlNullableDbType {
public init(v: ?DateTime)
}
功能:日期,仅年月日有效,对应仓颉 DateTime 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableDate (deprecated)。
类型:String
prop value
public mut prop value: ?DateTime
功能:该数据的值。
类型:?DateTime
init(?DateTime)
public init(v: ?DateTime)
功能:根据传入参数 v 构造一个 SqlNullableDate (deprecated) 实例。
参数:
- v: ?DateTime - 传入的数据。
class SqlNullableDecimal (deprecated)
public class SqlNullableDecimal <: SqlNullableDbType {
public init(v: ?Decimal)
}
功能:高精度数,对应仓颉 Decimal 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableDecimal (deprecated)。
类型:String
prop value
public mut prop value: ?Decimal
功能:该数据的值。
类型:?Decimal
init(?Decimal)
public init(v: ?Decimal)
功能:根据传入参数 v 构造一个 SqlNullableDecimal (deprecated) 实例。
参数:
- v: ?Decimal - 传入的数据。
class SqlNullableDouble (deprecated)
public class SqlNullableDouble <: SqlNullableDbType {
public init(v: ?Float64)
}
功能:双精度数,对应仓颉 Float64 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableDouble (deprecated)。
类型:String
prop value
public mut prop value: ?Float64
功能:该数据的值。
类型:?Float64
init(?Float64)
public init(v: ?Float64)
功能:根据传入参数 v 构造一个 SqlNullableDouble (deprecated) 实例。
参数:
- v: ?Float64 - 传入的数据。
class SqlNullableInteger (deprecated)
public class SqlNullableInteger <: SqlNullableDbType {
public init(v: ?Int32)
}
功能:中整数,对应仓颉 Int32 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableInteger (deprecated)。
类型:String
prop value
public mut prop value: ?Int32
功能:该数据的值。
类型:?Int32
init(?Int32)
public init(v: ?Int32)
功能:根据传入参数 v 构造一个 SqlNullableInteger (deprecated) 实例。
参数:
- v: ?Int32 - 传入的数据。
class SqlNullableInterval (deprecated)
public class SqlNullableInterval <: SqlNullableDbType {
public init(v: ?Duration)
}
功能:时间间隔,对应仓颉 Duration 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableInterval (deprecated)。
类型:String
prop value
public mut prop value: ?Duration
功能:该数据的值。
类型:?Duration
init(?Duration)
public init(v: ?Duration)
功能:根据传入参数 v 构造一个 SqlNullableInterval (deprecated) 实例。
参数:
- v: ?Duration - 传入的数据。
class SqlNullableReal (deprecated)
public class SqlNullableReal <: SqlNullableDbType {
public init(v: ?Float32)
}
功能:浮点数,对应仓颉 Float32 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableReal (deprecated)。
类型:String
prop value
public mut prop value: ?Float32
功能:该数据的值。
类型:?Float32
init(?Float32)
public init(v: ?Float32)
功能:根据传入参数 v 构造一个 SqlNullableReal (deprecated) 实例。
参数:
- v: ?Float32 - 传入的数据。
class SqlNullableSmallInt (deprecated)
public class SqlNullableSmallInt <: SqlNullableDbType {
public init(v: ?Int16)
}
功能:小整数,对应仓颉 Int16 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableSmallInt (deprecated)。
类型:String
prop value
public mut prop value: ?Int16
功能:该数据的值。
类型:?Int16
init(?Int16)
public init(v: ?Int16)
功能:根据传入参数 v 构造一个 SqlNullableSmallInt (deprecated) 实例。
参数:
- v: ?Int16 - 传入的数据。
class SqlNullableTime (deprecated)
public class SqlNullableTime <: SqlNullableDbType {
public init(v: ?DateTime)
}
功能:时间,仅时分秒毫秒有效,对应仓颉 DateTime 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableTime (deprecated)。
类型:String
prop value
public mut prop value: ?DateTime
功能:该数据的值。
类型:?DateTime
init(?DateTime)
public init(v: ?DateTime)
功能:根据传入参数 v 构造一个 SqlNullableTime (deprecated) 实例。
参数:
- v: ?DateTime - 传入的数据。
class SqlNullableTimeTz (deprecated)
public class SqlNullableTimeTz <: SqlNullableDbType {
public init(v: ?DateTime)
}
功能:带时区的时间,仅时分秒毫秒时区有效,对应仓颉 DateTime 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableTimeTz (deprecated)。
类型:String
prop value
public mut prop value: ?DateTime
功能:该数据的值。
类型:?DateTime
init(?DateTime)
public init(v: ?DateTime)
功能:根据传入参数 v 构造一个 SqlNullableTimeTz (deprecated) 实例。
参数:
- v: ?DateTime - 传入的数据。
class SqlNullableTimestamp (deprecated)
public class SqlNullableTimestamp <: SqlNullableDbType {
public init(v: ?DateTime)
}
功能:时间戳,对应仓颉 DateTime 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableTimestamp (deprecated)。
类型:String
prop value
public mut prop value: ?DateTime
功能:该数据的值。
类型:?DateTime
init(?DateTime)
public init(v: ?DateTime)
功能:根据传入参数 v 构造一个 SqlNullableTimestamp (deprecated) 实例。
参数:
- v: ?DateTime - 传入的数据。
class SqlNullableVarBinary (deprecated)
public class SqlNullableVarBinary <: SqlNullableDbType {
public init(v: ?Array<Byte>)
}
功能:变长二进制字符串,对应仓颉 Array<Byte> 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableVarBinary (deprecated)。
类型:String
prop value
public mut prop value: ?Array<Byte>
功能:该数据的值。
init(?Array<Byte>)
public init(v: ?Array<Byte>)
功能:根据传入参数 v 构造一个 SqlNullableVarBinary (deprecated) 实例。
参数:
class SqlNullableVarchar (deprecated)
public class SqlNullableVarchar <: SqlNullableDbType {
public init(v: ?String)
}
功能:变长字符串,对应仓颉 String 类型,可为数据库 Null 值。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlNullableVarchar (deprecated)。
类型:String
prop value
public mut prop value: ?String
功能:该数据的值。 类型:?String
init(?String)
public init(v: ?String)
功能:根据传入参数 v 构造一个 SqlNullableVarchar (deprecated) 实例。
参数:
- v: ?String - 传入的数据。
class SqlOption
public class SqlOption {
public static const URL = "url"
public static const Host = "host"
public static const Username = "username"
public static const Password = "password"
public static const Driver = "driver"
public static const Database = "database"
public static const Encoding = "encoding"
public static const ConnectionTimeout = "connection_timeout"
public static const UpdateTimeout = "update_timeout"
public static const QueryTimeout = "query_timeout"
public static const FetchRows = "fetch_rows"
public static const SSLMode = "ssl.mode"
public static const SSLModePreferred = "ssl.mode.preferred"
public static const SSLModeDisabled = "ssl.mode.disabled"
public static const SSLModeRequired = "ssl.mode.required"
public static const SSLModeVerifyCA = "ssl.mode.verify_ca"
public static const SSLModeVerifyFull = "ssl.mode.verify_full"
public static const SSLCA = "ssl.ca"
public static const SSLCert = "ssl.cert"
public static const SSLKey = "ssl.key"
public static const SSLKeyPassword = "ssl.key.password"
public static const SSLSni = "ssl.sni"
public static const Tls12Ciphersuites = "tls1.2.ciphersuites"
public static const Tls13Ciphersuites = "tls1.3.ciphersuites"
public static const TlsVersion = "tls.version"
}
功能:预定义的 sql 选项名称和值。如果需要扩展,请不要与这些名称和值冲突。
static const ConnectionTimeout
public static const ConnectionTimeout = "connection_timeout"
功能:获取 connect 操作的超时时间,单位 ms。
类型:String
static const Database
public static const Database = "database"
功能:获取数据库名称。
类型:String
static const Driver
public static const Driver = "driver"
功能:获取数据库驱动名称,比如 postgres,opengauss。
类型:String
static const Encoding
public static const Encoding = "encoding"
功能:获取数据库字符集编码类型。
类型:String
static const FetchRows
public static const FetchRows = "fetch_rows"
功能:获取每次获取额外数据时从数据库中提取的行数。
类型:String
static const Host
public static const Host = "host"
功能:获取数据库服务器主机名或者 IP 地址。
类型:String
static const Password
public static const Password = "password"
功能:获取连接数据库的密码。
类型:String
static const QueryTimeout
public static const QueryTimeout = "query_timeout"
功能:获取 query 操作的超时时间,单位 ms。
类型:String
static const SSLCA
public static const SSLCA = "ssl.ca"
功能:证书颁发机构( CA )证书文件的路径名。
类型:String
static const SSLCert
public static const SSLCert = "ssl.cert"
功能:客户端 SSL 公钥证书文件的路径名。
类型:String
static const SSLKey
public static const SSLKey = "ssl.key"
功能:客户端 SSL 私钥文件的路径名。
类型:String
static const SSLKeyPassword
public static const SSLKeyPassword = "ssl.key.password"
功能:客户端 SSL 私钥文件的密码。
类型:String
static const SSLMode
public static const SSLMode = "ssl.mode"
功能:获取 SSLMode 传输层加密模式。
类型:String
static const SSLModeDisabled
public static const SSLModeDisabled = "ssl.mode.disabled"
功能:建立未加密的连接。
类型:String
static const SSLModePreferred
public static const SSLModePreferred = "ssl.mode.preferred"
功能:如果服务器支持加密连接,则建立加密连接; 如果无法建立加密连接,则回退到未加密连接,这是 SSLMode 的默认值。
类型:String
static const SSLModeRequired
public static const SSLModeRequired = "ssl.mode.required"
功能:如果服务器支持加密连接,则建立加密连接。如果无法建立加密连接,则连接失败。
类型:String
static const SSLModeVerifyCA
public static const SSLModeVerifyCA = "ssl.mode.verify_ca"
功能:SSLModeVerifyCA 和 SSLModeRequired 类似,但是增加了校验服务器证书,如果校验失败,则连接失败。
类型:String
static const SSLModeVerifyFull
public static const SSLModeVerifyFull = "ssl.mode.verify_full"
功能:SSLModeVerifyFull 和 SSLModeVerifyCA 类似,但通过验证服务器证书中的标识与客户端连接的主机名是否匹配,来执行主机名身份验证。
类型:String
static const SSLSni
public static const SSLSni = "ssl.sni"
功能:客户端通过该标识在握手过程开始时试图连接到哪个主机名。
类型:String
static const Tls12Ciphersuites
public static const Tls12Ciphersuites = "tls1.2.ciphersuites"
功能:此选项指定客户端允许使用 TLSv1.2 及以下的加密连接使用哪些密码套件。 值为冒号分隔的字符串,比如 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:TLS_DHE_RSA_WITH_AES_128_CBC_SHA"。
类型:String
static const Tls13Ciphersuites
public static const Tls13Ciphersuites = "tls1.3.ciphersuites"
功能:此选项指定客户端允许使用 TLSv1.3 的加密连接使用哪些密码套件。 值为冒号分隔的字符串,比如 "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"。
类型:String
static const TlsVersion
public static const TlsVersion = "tls.version"
功能:支持的 TLS 版本号,值为逗号分隔的字符串,比如 "TLSv1.2,TLSv1.3"。
类型:String
static const URL
public static const URL = "url"
功能:获取数据库连接 URL 字符串。
类型:String
static const UpdateTimeout
public static const UpdateTimeout = "update_timeout"
功能:获取 update 操作的超时时间,单位 ms。
类型:String
static const Username
public static const Username = "username"
功能:获取连接数据库的用户名。
类型:String
class SqlReal (deprecated)
public class SqlReal <: SqlDbType {
public init(v: Float32)
}
功能:浮点数,对应仓颉 Float32 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlReal (deprecated)。
类型:String
prop value
public mut prop value: Float32
功能:该数据的值。
类型:Float32
init(Float32)
public init(v: Float32)
功能:根据传入参数 v 构造一个 SqlReal (deprecated) 实例。
参数:
- v: Float32 - 传入的数据。
class SqlSmallInt (deprecated)
public class SqlSmallInt <: SqlDbType {
public init(v: Int16)
}
功能:小整数,对应仓颉 Int16 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlSmallInt (deprecated)。
类型:String
prop value
public mut prop value: Int16
功能:该数据的值。
类型:Int16
init(Int16)
public init(v: Int16)
功能:根据传入参数 v 构造一个 SqlSmallInt (deprecated) 实例。
参数:
- v: Int16 - 传入的数据。
class SqlTime (deprecated)
public class SqlTime <: SqlDbType {
public init(v: DateTime)
}
功能:时间,仅时分秒毫秒有效,对应仓颉 DateTime 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlTime (deprecated)。
类型:String
prop value
public mut prop value: DateTime
功能:该数据的值。
类型:DateTime
init(DateTime)
public init(v: DateTime)
功能:根据传入参数 v 构造一个 SqlTime (deprecated) 实例。
参数:
- v: DateTime - 传入的数据。
class SqlTimeTz (deprecated)
public class SqlTimeTz <: SqlDbType {
public init(v: DateTime)
}
功能:带时区的时间,仅时分秒毫秒时区有效,对应仓颉 DateTime 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlTimeTz (deprecated)。
类型:String
prop value
public mut prop value: DateTime
功能:该数据的值。
类型:DateTime
init(DateTime)
public init(v: DateTime)
功能:根据传入参数 v 构造一个 SqlTimeTz (deprecated) 实例。
参数:
- v: DateTime - 传入的数据。
class SqlTimestamp (deprecated)
public class SqlTimestamp <: SqlDbType {
public init(v: DateTime)
}
功能:时间戳,对应仓颉 DateTime 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlTimestamp (deprecated)。
类型:String
prop value
public mut prop value: DateTime
功能:该数据的值。
类型:DateTime
init(DateTime)
public init(v: DateTime)
功能:根据传入参数 v 构造一个 SqlTimestamp (deprecated) 实例。
参数:
- v: DateTime - 传入的数据。
class SqlVarBinary (deprecated)
public class SqlVarBinary <: SqlDbType {
public init(v: Array<Byte>)
}
功能:变长二进制字符串,对应仓颉 Array<Byte> 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlVarBinary (deprecated)。
类型:String
prop value
public mut prop value: Array<Byte>
功能:该数据的值。
init(Array<Byte>)
public init(v: Array<Byte>)
功能:根据传入参数 v 构造一个 SqlVarBinary (deprecated) 实例。
参数:
class SqlVarchar (deprecated)
public class SqlVarchar <: SqlDbType {
public init(v: String)
}
功能:变长字符串,对应仓颉 String 类型。
注意:
未来版本即将废弃不再使用,使用仓颉原生类型替代。
父类型:
prop name
public prop name: String
功能:类型名称,即 SqlVarchar (deprecated)。
类型:String
prop value
public mut prop value: String
功能:该数据的值。
类型:String
init(String)
public init(v: String)
功能:根据传入参数 v 构造一个 SqlVarchar (deprecated) 实例。
参数:
- v: String - 传入的数据。
枚举
enum ConnectionState
public enum ConnectionState <: Equatable<ConnectionState> {
| Broken
| Closed
| Connecting
| Connected
}
功能:描述与数据源连接的当前状态。
父类型:
Broken
Broken
功能:表示与数据源的连接已中断。只有在 Connected 之后才可能发生这种情况。
Closed
Closed
功能:表示连接对象已关闭。
Connected
Connected
功能:表示连接对象已与数据源连接上。
Connecting
Connecting
功能:表示连接对象正在与数据源连接。
operator func !=(ConnectionState)
public operator func !=(rhs: ConnectionState): Bool
功能:判断数据源连接状态是否不同。
参数:
- rhs: ConnectionState - 数据源连接状态。
返回值:
- Bool - 传入数据源连接状态与当前状态相同则返回
false,否则返回true。
operator func ==(ConnectionState)
public operator func ==(rhs: ConnectionState): Bool
功能:判断数据源连接状态是否相同。
参数:
- rhs: ConnectionState - 数据源连接状态。
返回值:
- Bool - 传入数据源连接状态与当前状态相同则返回
true,否则返回false。
enum TransactionAccessMode
public enum TransactionAccessMode <: ToString & Hashable & Equatable<TransactionAccessMode> {
| ReadOnly
| ReadWrite
| Unspecified
}
功能:事务读写模式。
父类型:
ReadOnly
ReadOnly
功能:表示只读模式。
ReadWrite
ReadWrite
功能:表示读 + 写模式。
Unspecified
Unspecified
功能:表示未指定的事务读写模式。其行为取决于具体的数据库服务器。
func hashCode()
public func hashCode(): Int64
功能:获取事务读写模式的哈希值。
返回值:
- Int64 - 事务读写模式的哈希值。
func toString()
public func toString(): String
功能:返回事务读写模式的字符串表示。枚举值和字符串的对应关系如下表所示:
| 枚举值 | 字符串 |
|---|---|
| ReadOnly | "Read Only" |
| ReadWrite | "Read Write" |
| Unspecified | "Unspecified" |
返回值:
- String - 事务读写模式的字符串。
operator func !=(TransactionAccessMode)
public operator func != (rhs: TransactionAccessMode): Bool
功能:判断两个 TransactionAccessMode 是否不相等。
参数:
- rhs: TransactionAccessMode - 传入 TransactionAccessMode 的枚举值。
返回值:
- Bool - 如果不相等,则返回
true,否则返回false。
operator func ==(TransactionAccessMode)
public operator func == (rhs: TransactionAccessMode): Bool
功能:判断两个 TransactionAccessMode 是否相等。
参数:
- rhs: TransactionAccessMode - 传入 TransactionAccessMode 的枚举值。
返回值:
- Bool - 如果相等,则返回
true,否则返回false。
enum TransactionDeferrableMode
public enum TransactionDeferrableMode <: ToString & Hashable & Equatable<TransactionDeferrableMode> {
| Deferrable
| NotDeferrable
| Unspecified
}
功能:事务的延迟模式。
父类型:
Deferrable
Deferrable
功能:表示可延迟。
说明:
延迟事务是指在前滚阶段结束时未提交的事务,并且遇到了阻止其回滚的错误。因为事务无法回滚,所以它被延迟。
NotDeferrable
NotDeferrable
功能:表示不可延迟。
Unspecified
Unspecified
功能:未指定的事务延迟模式,其行为取决于具体的数据库服务器。
func hashCode()
public func hashCode(): Int64
功能:获取事务延迟模式的哈希值。
返回值:
- Int64 - 事务延迟模式的哈希值。
func toString()
public func toString(): String
功能:返回事务延迟模式的字符串表示。枚举值和字符串的对应关系如下表所示:
| 枚举值 | 字符串 |
|---|---|
| Deferrable | "Deferrable" |
| NotDeferrable | "Not Deferrable" |
| Unspecified | "Unspecified" |
返回值:
- String - 事务延迟模式的字符串。
operator func !=(TransactionDeferrableMode)
public operator func != (rhs: TransactionDeferrableMode): Bool
功能:判断两个 TransactionDeferrableMode 是否不相等。
参数:
- rhs: TransactionDeferrableMode - 传入 TransactionDeferrableMode 的枚举值。
返回值:
- Bool - 如果不相等,则返回
true,否则返回false。
operator func ==(TransactionDeferrableMode)
public operator func == (rhs: TransactionDeferrableMode): Bool
功能:判断两个 TransactionDeferrableMode 是否相等。
参数:
- rhs: TransactionDeferrableMode - 传入 TransactionDeferrableMode 的枚举值。
返回值:
- Bool - 如果相等,则返回
true,否则返回false。
enum TransactionIsoLevel
public enum TransactionIsoLevel <: ToString & Hashable & Equatable<TransactionIsoLevel> {
| Chaos
| Linearizable
| ReadCommitted
| ReadUncommitted
| RepeatableRead
| Serializable
| Snapshot
| Unspecified
}
功能:事务隔离级别。
说明:
事务隔离定义了数据库系统中,一个事务中操作的结果在何时以何种方式对其他并发事务操作可见。
父类型:
Chaos
Chaos
功能:表示无法覆盖来自隔离级别更高的事务的挂起更改。
Linearizable
Linearizable
功能:表示事务线性化。
说明:
区别于串行化(Serializable),线性化主要强调单个对象上(即 db 行或 nosql 记录)的一组单个操作(比如一系列读写操作),线性化保证这些操作严格按真实时间顺序执行。比如当您查看单个对象上的操作子集时,线性化是相关的。
ReadCommitted
ReadCommitted
功能:表示事务等待,直到其他事务写锁定的行被解锁;这将防止它读取任何“脏”数据。
ReadUncommitted
ReadUncommitted
功能:表示事务之间不隔离。
RepeatableRead
RepeatableRead
功能:表示事务可重复读。对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改。
Serializable
Serializable
功能:表示事务可串行化。此隔离级别下,所有事务顺序执行,因此,脏读、不可重复读、幻读都不会出现。
Snapshot
Snapshot
功能:表示快照隔离通过使用行版本控制避免了大多数锁定和阻止。
Unspecified
Unspecified
功能:未指定的事务隔离级别,其行为取决于具体的数据库服务器。
func hashCode()
public func hashCode(): Int64
功能:获取事务隔离级别的哈希值。
返回值:
- Int64 - 事务隔离级别的哈希值。
func toString()
public func toString(): String
功能:返回事务隔离级别的字符串表示。枚举值和字符串的对应关系如下表所示:
| 枚举值 | 字符串 |
|---|---|
| Chaos | "Chaos" |
| Linearizable | "Linearizable" |
| ReadCommitted | "Read Committed" |
| ReadUncommitted | "Read Uncommitted" |
| RepeatableRead | "Repeatable Read" |
| Serializable | "Serializable" |
| Snapshot | "Snapshot" |
| Unspecified | "Unspecified" |
返回值:
- String - 事务隔离级别的字符串。
operator func !=(TransactionIsoLevel)
public operator func != (rhs: TransactionIsoLevel): Bool
功能:判断两个 TransactionIsoLevel 是否不相等。
参数:
- rhs: TransactionIsoLevel - 传入的 TransactionIsoLevel。
返回值:
- Bool - 如果不相等,则返回
true,否则返回false。
operator func ==(TransactionIsoLevel)
public operator func == (rhs: TransactionIsoLevel): Bool
功能:判断两个 TransactionIsoLevel 是否相等。
参数:
- rhs: TransactionIsoLevel - 传入的 TransactionIsoLevel。
返回值:
- Bool - 如果相等,则返回
true,否则返回false。
异常类
class SqlException
public open class SqlException <: Exception {
public init()
public init(message: String)
public init(message: String, sqlState: String, errorCode: Int64)
}
功能:用于处理 sql 相关的异常。
父类型:
prop errorCode
public prop errorCode: Int64
功能:数据库供应商返回的整数错误代码。
类型:Int64
prop message
public override prop message: String
功能:获取异常信息字符串。
类型:String
prop sqlState
public prop sqlState: String
功能:长度为五个字符的字符串,是数据库系统返回的最后执行的 sql 语句状态。
类型:String
init()
public init()
功能:无参构造函数。
init(String)
public init(message: String)
功能:根据异常信息创建 SqlException 实例。
参数:
- message: String - 异常信息。
init(String, String, Int64)
public init(message: String, sqlState: String, errorCode: Int64)
功能:根据异常信息、SQL语句状态、错误码信息,创建 SqlException 实例。
参数:
- message: String - 异常信息。
- sqlState: String - 长度为五个字符的字符串,是数据库系统返回的最后执行的 sql 语句状态。
- errorCode: Int64 - 数据库供应商返回的整数错误代码。
获取数据库连接示例
import std.database.sql.*
main(): Unit {
// 获取已经注册的驱动
let drv = DriverManager.getDriver("opengauss") ?? return
// 设置打开数据源的选项
let opts = [
("cachePrepStmts", "true"),
("prepStmtCacheSize", "250"),
("prepStmtCacheSqlLimit", "2048")
]
// 通过连接路径和选项打开数据源
let ds = drv.open("opengauss://testuser:testpwd@localhost:5432/testdb", opts)
// 设置连接选项
ds.setOption(SqlOption.SSLMode, SqlOption.SSLModeVerifyCA)
ds.setOption(SqlOption.SSLCA, "ca.crt")
ds.setOption(SqlOption.SSLCert, "server.crt")
ds.setOption(SqlOption.SSLKey, "server.key")
ds.setOption(SqlOption.SSLKeyPassword, "key_password")
ds.setOption(SqlOption.TlsVersion, "TLSv1.2,TLSv1.3")
// 返回一个可用连接
ds.connect()
}
删除表、创建表示例
import std.database.sql.*
main() {
// 获取数据库链接示例
let drv = DriverManager.getDriver("opengauss") ?? return
let opts = [
("cachePrepStmts", "true"),
("prepStmtCacheSize", "250"),
("prepStmtCacheSqlLimit", "2048")
]
let ds = drv.open("opengauss://testuser:testpwd@localhost:5432/testdb", opts)
let conn = ds.connect()
// 删除和创建表
var stmt = conn.prepareStatement("DROP TABLE IF EXISTS test")
var ur = stmt.update()
println("Update Result: ${ur.rowCount} ${ur.lastInsertId}")
stmt.close()
stmt = conn.prepareStatement("CREATE TABLE test(id SERIAL PRIMARY KEY, name VARCHAR(20) NOT NULL, age INT)")
ur = stmt.update()
println("Update Result: ${ur.rowCount} ${ur.lastInsertId}")
stmt.close()
}
执行数据库操作语句示例
插入数据
import std.database.sql.*
main() {
// 获取数据库连接示例
let drv = DriverManager.getDriver("opengauss") ?? return
let ds = drv.open("opengauss://testuser:testpwd@localhost:5432/testdb", [])
let conn = ds.connect()
// 插入数据 1
var stmt = conn.prepareStatement("INSERT INTO test VALUES(?, ?)")
stmt.set<String>(0, "li lei")
stmt.set<Int32>(1, 12)
var ur = stmt.update()
println("Update Result: ${ur.rowCount} ${ur.lastInsertId}")
// 插入数据 2
stmt.set<String>(0, "han meimei")
stmt.set<Int32>(1, 13)
ur = stmt.update()
println("Update Result: ${ur.rowCount} ${ur.lastInsertId}")
// 如果需要在插入数据后返回插入的 id 值,可以参考如下方式:
let sql = "INSERT INTO test (name, age) VALUES (?,?) RETURNING id, name"
try (stmt = conn.prepareStatement(sql)) {
stmt.set<String>(0, "li lei")
stmt.set<Int32>(1, 12)
let qr = stmt.query()
while (qr.next()) {
println("id = ${qr.get<Int32>(0)}, name=${qr.get<String>(1)}")
}
} catch (e: Exception) {
e.printStackTrace()
}
stmt.close()
}
查询数据
import std.database.sql.*
main() {
// 获取数据库连接示例
let drv = DriverManager.getDriver("opengauss") ?? return
let ds = drv.open("opengauss://testuser:testpwd@localhost:5432/testdb", [])
let conn = ds.connect()
// 查询操作示例
var stmt = conn.prepareStatement("select * from test where name = ?")
stmt.set<String>(0, "li lei")
let qr = stmt.query()
while (qr.next()) {
println("id = ${qr.get<Int32>(0)}, name = ${qr.get<String>(1)}, age=${qr.get<Int32>(2)}")
}
stmt.close()
}
更新数据
import std.database.sql.*
main() {
// 获取数据库连接示例
let drv = DriverManager.getDriver("opengauss") ?? return
let ds = drv.open("opengauss://testuser:testpwd@localhost:5432/testdb", [])
let conn = ds.connect()
// 更新操作示例
var stmt = conn.prepareStatement("update test set age = ? where name = ?")
stmt.set<Int32>(0, 15)
stmt.set<String>(1, "li lei")
var ur = stmt.update()
println("Update Result: ${ur.rowCount} ${ur.lastInsertId}")
stmt.close()
}
删除数据
import std.database.sql.*
main() {
// 获取数据库连接示例
let drv = DriverManager.getDriver("opengauss") ?? return
let ds = drv.open("opengauss://testuser:testpwd@localhost:5432/testdb", [])
let conn = ds.connect()
// 删除操作示例
var stmt = conn.prepareStatement("delete from test where name = ?")
stmt.set<String>(0, "li lei")
var ur = stmt.update()
println("Update Result: ${ur.rowCount} ${ur.lastInsertId}")
stmt.close()
}
执行事务控制语句示例
普通数据库事务
import std.database.sql.*
import std.time.*
main() {
let SQL_INSERT = "INSERT INTO EMPLOYEE (NAME, SALARY, CREATED_DATE) VALUES (?, ?, ?)"
let drv = DriverManager.getDriver("opengauss") ?? return
let db = drv.open("opengauss://localhost:5432/testdb")
try(cn = db.connect()) {
let psInsert = cn.prepareStatement(SQL_INSERT)
// 创建事务对象
let tx = cn.createTransaction()
try {
// 插入第一条数据
psInsert.set<String>(0, "mkyong")
psInsert.set<Array<Byte>>(1, Array<Byte>(1, repeat: 10))
psInsert.set<DateTime>(2, DateTime.now())
psInsert.update()
// 插入第二条数据
psInsert.set<String>(0, "kungfu")
psInsert.set<Array<Byte>>(1, Array<Byte>(1, repeat: 20))
psInsert.set<DateTime>(2, DateTime.now())
psInsert.update()
// 如果连接到数据库,测试回滚 SQLException:未为参数3指定值。
psInsert.set<String>(0, "mkyong")
psInsert.set<Array<Byte>>(1, Array<Byte>(5, {i => UInt8(i + 1)}))
psInsert.update()
// 提交事务
tx.commit()
} catch (e1: SqlException) {
e1.printStackTrace()
try {
// 发生异常,回滚所有事务
tx.rollback()
} catch (e2: SqlException) {
// 如果回滚失败
e2.printStackTrace()
}
}
} catch (e: SqlException) {
// 如果连接失败
e.printStackTrace()
}
}
事务保存点
如果数据库事务支持保存点,可以参考如下样例:
import std.database.sql.*
import std.time.*
main() {
let SQL_INSERT = "INSERT INTO EMPLOYEE (NAME, SALARY, CREATED_DATE) VALUES (?, ?, ?)"
let drv = DriverManager.getDriver("opengauss") ?? return
let db = drv.open("opengauss://localhost:5432/testdb")
try(cn = db.connect()) {
let psInsert = cn.prepareStatement(SQL_INSERT)
let tx = cn.createTransaction()
try {
// 创建保存点 1
tx.save("save1")
psInsert.set<String>(0, "mkyong")
psInsert.set<Array<Byte>>(1, Array<Byte>(1, repeat: 10))
psInsert.set<DateTime>(2, DateTime.now())
psInsert.update()
// 创建保存点 2
tx.save("save2")
psInsert.set<String>(0, "kungfu")
psInsert.set<Array<Byte>>(1, Array<Byte>(1, repeat: 20))
psInsert.set<DateTime>(2, DateTime.now())
psInsert.update()
// 创建保存点 3
tx.save("save3")
psInsert.set<String>(0, "mkyong")
psInsert.set<Array<Byte>>(1, Array<Byte>(5, {i => UInt8(i + 1)}))
psInsert.update()
// 回滚到保存点 2
tx.rollback("save2")
// 提交事务
tx.commit()
} catch (e1: SqlException) {
e1.printStackTrace()
try {
// 发生异常,回滚所有事务
tx.rollback()
} catch (e2: SqlException) {
e2.printStackTrace()
}
}
} catch (e: SqlException) {
e.printStackTrace()
}
}
std.deriving
std.deriving 提供了一种根据类、结构体和枚举类型的字段、属性等自动生成接口实现的方法。
当前支持自动生成以下接口的实现:
更多示例详见 Deriving 用户手册。
API 列表
宏
| 宏名 | 功能 |
|---|---|
| Derive | Derive 是一个核心宏,其仅可修饰结构体、类或枚举等声明,对被修饰的声明自动扩展接口。 |
| DeriveExclude | DeriveExclude 可为已被 @Derive 宏修饰的声明排除不需要处理的字段,字段默认被 Deriving 处理。 |
| DeriveInclude | DeriveInclude 可为已被 @Derive 宏修饰的声明增加需要处理的属性,属性默认情况不会被 Deriving 处理。 |
| DeriveOrder | DeriveOrder 可为已被 @Derive 宏修饰的声明指定处理字段和属性的顺序,通常对 Comparable 接口有意义。 |
宏
@Derive 宏
功能:Derive 是一个核心宏,其仅可修饰结构体、类或枚举等声明,对被修饰的声明自动扩展接口。
@DeriveExclude 宏
功能:DeriveExclude 可为已被 @Derive 宏修饰的声明排除不需要处理的字段,字段默认被 Deriving 处理。
@DeriveInclude 宏
功能:DeriveInclude 可为已被 @Derive 宏修饰的声明增加需要处理的属性,属性默认情况不会被 Deriving 处理。
@DeriveOrder 宏
功能:DeriveOrder 可为已被 @Derive 宏修饰的声明指定处理字段和属性的顺序,通常对 Comparable 接口有意义。
Deriving
一个简单示例:
import std.deriving.*
@Derive[ToString]
class User {
User(
let name: String,
let id: Int
) {}
}
main() {
println(User("root", 0)) // -> "User(name = root, id = 0)"
}
当 @Derive[ToString] 应用于类或结构体时, Deriving 会收集和使用类或结构体的可变和不可变字段,包括在主构造函数中指定的字段,并自动实现 ToString 的方法。当 @Derive[ToString] 应用于枚举时, Deriving 将收集枚举的构造函数参数。静态字段和属性将不会被收集和使用,另外, Deriving 收集的字段不允许存在私有字段,否则将抛出编译错误。
收集到的字段用于 Deriving 时,其类型需要实现目标接口,以便将字段结果组合在一起。例如,当处理 ToString 时,生成的代码将在所有收集到的字段上调用 toString ,然后将结果与对应的字段名称连接成一个字符串。如果其中一个字段的类型不支持 ToString ,则会抛出编译错误并且 Deriving 无法完成。
注意:
标记为派生的类应该是最终的:它不应该是开放的、抽象的或
sealed的。
有些字段可能具有特殊含义,它们的值没有多大意义,则可通过在这些字段上应用 @DeriveExclude 来排除这些字段:
@Derive[ToString]
class User {
User(let name: String) {}
@DeriveExclude
let lazyHashCode = 0 // it will not be printed because it's excluded
}
默认情况 Deriving 仅使能字段,对于属性则需要通过 @DeriveInclude 来显式使能:
@Derive[ToString]
class User {
User(
let id: Int
) {}
@DeriveInclude
prop name: String {
get() { passwdFile.getUserName(id) }
}
}
main() {
println(User(0)) // -> "User(id = 0, name = root)"
}
请注意,因为属性 name 是在 id 之后声明的,因此打印的顺序为先 id 后 name 。
如果需要更改打印的顺序,可以使用 @DeriveOrder :
@Derive[ToString]
@DeriveOrder[name, id]
class User {
User(
let id: Int
) {}
@DeriveInclude
prop name: String {
get() { "s_${id}" }
}
}
main() {
println(User(0)) // -> "User(name = s_0, id = 0)"
}
常见的 Deriving 语法
@Derive 宏支持以逗号分隔的接口名称列表。此外,该宏可以重复多次被调用,但所有 @Derive 宏调用都应位于声明的顶部,而其他宏(如 @DeriveOrder )应始终位于其后。
支持的接口列表的顺序没有影响。
@Derive[ToString, Hashable]
@Derive[Equatable]
@DeriveOrder[currency,price,quantity]
struct Order {}
当 Deriving 多个相交的接口时,例如,Comparable 还包括 Equatable ,则允许两者同时存在,等同于仅有范围最广的一个:
@Derive[Comparable] // does also generate Equatable
等同于:
@Derive[Comparable, Equatable]
包含和排除
默认情况下会处理所有字段,包括定义为主构造函数参数的字段。
当需要排除某个字段时,可以对其应用 @DeriveExclude :
@Derive[ToString]
struct S {
S(let id: Int) { key = "s_${id}" }
@DeriveExclude
let key: String
}
默认情况下不处理属性,需要通过 @DeriveInclude 包含属性。
@Derive[ToString]
struct S {
S(let id: Int) {}
@DeriveInclude
prop key: String {
get() { "s_${id}" }
}
}
被 Deriving 的字段和属性都不能是 private 的。因此,private 的字段或者属性应被除外或者使其为包内可见属性。
注意:
静态的字段和属性始终会被忽略,因此它们都不能被
@DeriveInclude和@DeriveExclude修饰。
支持的接口
当前仅支持如下接口:
ToStringHashableEquatableComparable
暂不支持用户自定义的接口。
变更顺序
在对由多个字段组成的复杂类型的实例进行排序和比较时,测试字段的顺序通常很重要。默认情况下,所有字段都按声明顺序考虑。可以使用 @DeriveOrder 宏修改顺序。
@Derive[Comparable, ToString]
struct Floor {
Floor(
let level: Int,
let building: Int
) {}
}
main() {
let floors = [
Floor(1, 2),
Floor(3, 2),
Floor(2, 1)
]
floors.sort()
for (f in floors) { println(f) }
}
上述示例将打印以下内容,看起来顺序没有很大影响。
Floor(level = 1, building = 2)
Floor(level = 2, building = 1)
Floor(level = 3, building = 2)
但是当我实现 Comparable 时,不同的顺序将影响结果。
@Derive[Comparable, ToString]
@DeriveOrder[building, level]
struct Floor {
Floor(
let level: Int,
let building: Int
) {}
}
此时,结果将首先按 building 排序,然后按 level 排序:
Floor(building = 1, level = 2)
Floor(building = 2, level = 1)
Floor(building = 2, level = 3)
泛型
实现泛型类型的接口通常需要应用约束,以便类型仅在某些条件下实现接口。例如:
class Cell<T> {
Cell(let value: T) {}
}
此时可能希望仅当单元格的值可打印时才能够打印该单元格。为了实现它,编写一个带有约束的扩展:
extend <T> Cell<T> <: ToString where T <: ToString {
public func toString(): String {
"Cell(value = ${value})"
}
}
当使用 Deriving 时,它会默认尝试对所有泛型参数应用约束,因此以下内容与上面的扩展相同:
@Derive[ToString]
class Cell<T> {
Cell(let value: T) {}
}
然而在某些情况下,默认行为并不符合期望。此时,可使用 @Derive 内部的 where 来覆盖默认约束:
interface PrintableCellValue <: ToString { ... }
@Derive[ToString where T <: PrintableCellValue]
class Cell<T> {}
请注意,在上面的示例中,自定义约束仅适用于 ToString ,因此如果需要对所有接口进行约束,则应单独为每个接口重复此动作。
@Derive[ToString where T <: PrintableCellValue]
@Derive[Hashable where T <: PrintableCellValue & Hashable]
class Cell<T> {}
性能说明
由于 Deriving 是基于仓颉宏的,不涉及任何反射,因此 Deriving 实现的运行时性能与手写相当。但是,Deriving 涉及编译时的代码转换,因此它会影响编译时间。
std.env
功能介绍
env 包提供当前进程的相关信息与功能、包括环境变量、命令行参数、标准流、退出程序。也提供标准输入、标准输出、标准错误进行交互的方法。
本包提供多平台统一操控能力,目前支持 Linux 平台,macOS 平台,Windows 平台。
本包提供 getStdErr()、getStdIn() 、getStdOut(),用于获取这三个标准流。
- ConsoleReader 封装了标准输入流的相关功能,可以通过相关的
read方法从标准输入中读取数据。 - ConsoleWriter 封装了标准输出、标准错误流的相关功能,ConsoleWriter 封装了一系列的
write方法,提供了向标准输出、标准错误写入数据的能力。
标准输入(stdin)、标准输出(stdout)和标准错误(stderr)是计算机操作系统中常见的三个流。
标准输入是程序从用户获取输入数据的流,通常是键盘输入。标准输出是程序向用户输出结果的流,通常是屏幕输出。标准错误是程序在发生错误时输出错误信息的流,通常也是屏幕输出。
在 Unix/Linux 系统中,标准输入、标准输出和标准错误分别对应文件描述符 0、1 和 2。程序可以使用这些文件描述符来读取和写入数据。例如,可以使用重定向符号将标准输出重定向到文件中,或将标准错误输出重定向到另一个程序的标准输入中。
API 列表
类
| 类名 | 功能 |
|---|---|
| ConsoleReader | 提供从标准输入读取字符或者字符串的功能。 |
| ConsoleWriter | 提供向标准输出或者标准错误流写入字符或者字符串的功能。 |
函数
| 函数 | 功能 |
|---|---|
| atExit() | 注册回调函数,当前进程退出时执行注册函数。 |
| exit() | 进程退出函数。 |
| getCommand() | 获取当前进程命令。 |
| getCommandLine() | 获取当前进程命令行。 |
| getHomeDirectory() | 获取当前进程 home 目录的路径。 |
| getProcessId() | 获取当前进程 id。 |
| getStdErr() | 获取当前进程标准错误流。 |
| getStdIn() | 获取当前进程标准错误流。 |
| getStdOut() | 获取当前进程标准输出流。 |
| getTempDirectory() | 获取当前进程临时目录的路径。 |
| getVariable() | 获取当前进程指定名称的环境变量值。 |
| getVariables() | 获取当前进程进程环境变量。 |
| getWorkingDirectory() | 获取当前进程工作路径。 |
| removeVariable() | 通过指定环境变量名称移除环境变量。 |
| setVariable() | 设置当前进程一对环境变量。 |
异常类
| 异常类名 | 功能 |
|---|---|
| EnvException | env 包的异常类。 |
函数
func atExit(() -> Unit)
public func atExit(callback: () -> Unit): Unit
功能:注册回调函数,当前进程退出时执行注册函数。
注意:
请不要使用 C 语言 atexit 函数,避免出现不可期问题。
参数:
- callback: () ->Unit - 需要被注册回调的函数。
func exit(Int64)
public func exit(code: Int64): Nothing
功能:注册回调函数,当前进程退出时执行注册函数。
参数:
- code: Int64 - 当前进程退出状态码。
func getCommand()
public func getCommand(): String
功能:获取进程命令。
返回值:
- String - 当前进程命令。
异常:
- EnvException - 当进程不存在或对应进程为僵尸进程,无法获取进程名时,抛出异常。
func getCommandLine()
public func getCommandLine(): Array<String>
功能:获取当前进程命令行。Windows 平台当前进程可获取,其他场景下无法在非特权 API 下获取到本属性,暂不支持获取。
返回值:
异常:
- EnvException - 当进程不存在或对应进程为僵尸进程,或在 Windows 平台下暂不支持场景,无法获取进程命令行时,抛出异常。
func getHomeDirectory()
public func getHomeDirectory(): Path
功能:获取当前进程 home 目录的路径。
返回值:
- Path - 当前进程 home 目录的路径。
func getProcessId()
public func getProcessId(): Int
功能:获取当前进程 id。
返回值:
- Int - 当前进程 id。
func getStdErr()
public func getStdErr(): ConsoleWriter
功能:获取当前进程标准错误流。
返回值:
- ConsoleWriter - 进程标准错误流。
func getStdIn()
public func getStdIn(): ConsoleReader
功能:获取当前进程标准输入流。
返回值:
- ConsoleReader - 进程标准输入流。
func getStdOut()
public func getStdOut(): ConsoleWriter
功能:获取当前进程标准输出流。
返回值:
- ConsoleWriter - 进程标准输出流。
func getTempDirectory()
public func getTempDirectory(): Path
功能:获取当前进程临时目录的路径。从环境变量中获取 TMPDIR、TMP、TEMP 和 TEMPDIR 环境变量。如果以上值在环境变量中均不存在,则默认返回 /tmp 目录。
返回值:
- Path - 当前进程临时目录的路径。
func getVariable(String)
public func getVariable(key: String): ?String
功能:获取当前进程指定名称的环境变量值。
参数:
- key: String - 指定名称。
返回值:
- ?String - 当前进程指定名称的环境变量值。
异常:
- IllegalArgumentException - 当函数参数 key 包含空字符时,抛出异常。
func getVariables()
public func getVariables(): Array<(String, String)>
功能:获取当前进程环境变量。Windows 平台当前进程可获取,其他场景下无法在非特权 API 下获取到本属性,暂不支持获取。
返回值:
异常:
- EnvException - 当进程不存在或对应进程为僵尸进程,或在 Windows 平台下暂不支持场景,无法获取进程环境变量时,抛出异常。
func getWorkingDirectory()
public func getWorkingDirectory(): Path
功能:获取当前进程工作路径。Windows 平台当前进程可获取,其他场景下无法在非特权 API 下获取到本属性,暂不支持获取。
返回值:
- Path - 当前进程工作路径。
异常:
- EnvException - 当进程不存在或对应进程为僵尸进程,或在 Windows 平台下暂不支持场景,无法获取进程工作路径时,抛出异常。
func removeVariable(String)
public func removeVariable(key: String): Unit
功能:通过指定环境变量名称移除环境变量。
参数:
- key: String - 环境变量名称。
异常:
- IllegalArgumentException - 当函数参数 k 包含空字符时,抛出异常时,抛出异常。
func setVariable(String, String)
public func setVariable(key: String, value: String): Unit
功能:用于设置一对环境变量。如果设置了同名环境变量,原始环境变量值将被覆盖。
说明:
Windows 下如果传入的参数 v 是空字符串,那么会从环境中移除变量 k。
参数:
异常:
- IllegalArgumentException - 当函数参数 key 或 value 中包含空字符时,抛出异常。
类
class ConsoleReader
public class ConsoleReader <: InputStream
功能:提供从控制台读出数据并转换成字符或字符串的功能。
该类型无法构造实例,只能通过 getStdIn() 获取实例。
读操作是同步的,内部设有缓存区来保存控制台输入的内容,当到达控制台输入流的结尾时,控制台读取函数将返回None。
说明:
ConsoleReader 只有一个实例,所有方法共享同一个缓存区,相关
read方法返回None的情形有:
- 将标准输入重定向到文件时,读取到文件结尾EOF。
- Linux 环境,按下
Ctrl+D。- Windows 环境,按下
Ctrl+Z后加回车。
父类型:
func read()
public func read(): ?Rune
功能:从标准输入中读取下一个字符。
返回值:
异常:
- IllegalArgumentException - 当输入不符合
UTF-8编码的字符串时,抛此异常。
示例:
import std.env.*
main() {
getStdOut().write("请输入信息:")
var c = getStdIn().read() // 输入:abc
var r = c.getOrThrow()
getStdOut().write("输入的信息为:")
getStdOut().writeln(r)
return
}
运行结果:
请输入信息:abc
输入的信息为:a
func read(Array<Byte>)
public func read(arr: Array<Byte>): Int64
功能:从标准输入中读取并放入 arr 中。
注意:
该函数存在风险,可能读取出来的结果恰好把
UTF-8 code point从中截断,如果发生截断,将导致该 Array<Byte> 转换成字符串的结果不正确或抛出异常。
参数:
返回值:
- Int64 - 返回读取到的字节长度。
示例:
import std.env.*
main() {
var arr = Array<Byte>(3, repeat: 0)
getStdOut().write("请输入信息:")
getStdIn().read(arr) // 输入:567
getStdOut().write("输入后的数组为:")
getStdOut().writeln(arr)
return
}
运行结果:
请输入信息:567
输入后的数组为:567
func readToEnd()
public func readToEnd(): ?String
功能:从标准输入中读取所有字符。
直到读取到文件结束符EOF,或者在 Linux 上键入 Ctrl+D 或在 Windows 上键入 Ctrl+Z + 回车结束。读取到字符,返回 ?String,否则返回 None。读取失败时会返回 None,该接口不会抛出异常,即使输入不符合 UTF-8 编码的字符串,也会构造出一个 String 并返回,其行为等同于 String.fromUtf8Uncheck(Array<Byte>)。
返回值:
func readUntil((Rune) -> Bool)
public func readUntil(predicate: (Rune) -> Bool): ?String
功能:从标准输入中读取数据直到读取到的字符满足predicate条件结束。
满足 predicate: (Rune) -> Bool 条件的字符包含在结果中,读取失败时会返回None。
参数:
- predicate: (Rune) ->Bool - 终止读取的条件。
返回值:
示例:
import std.env.*
main() {
getStdOut().write("请输入信息:")
var c = getStdIn().readUntil({ch: Rune => ch > r'd' && ch < r'g'}) // 输入:abcdefg
var r = c.getOrThrow()
getStdOut().writeln("输入的信息为:" + r)
return
}
运行结果:
请输入信息:abcdefg
输入的信息为:abcde
func readUntil(Rune)
public func readUntil(ch: Rune): ?String
功能:从标准输入中读取数据直到读取到字符 ch 结束。
ch包含在结果中,如果读取到文件结束符 EOF,将返回读取到的所有信息,读取失败时会返回 None。
参数:
- ch: Rune - 终止字符。
返回值:
示例:
import std.env.*
main() {
getStdOut().write("请输入信息:")
var c = getStdIn().readUntil(r'b') // 输入:abc
var r = c.getOrThrow()
getStdOut().write("输入的信息为:")
getStdOut().writeln(r)
return
}
运行结果:
请输入信息:abc
输入的信息为:ab
func readln()
public func readln(): ?String
功能:从标准输入中读取一行字符串。
读取到字符,返回 ?String,结果不包含末尾换行符。该接口不会抛出异常,即使输入不符合UTF-8编码的字符串,也会构造出一个 String 并返回,其行为等同于 String.fromUtf8Uncheck(Array<Byte>)。
返回值:
- ?String - 读取到的行数据,读取失败返回
None。
示例:
import std.env.*
main() {
getStdOut().write("请输入信息:")
var c = getStdIn().readln() // 输入:abc
var r = c.getOrThrow()
getStdOut().write("输入的信息为:")
getStdOut().writeln(r)
return
}
运行结果:
请输入信息:abc
输入的信息为:abc
class ConsoleWriter
public class ConsoleWriter <: OutputStream
功能:此类提供保证线程安全的标准输出功能。
每次 write 调用写到控制台的结果是完整的,不同的 write 函数调用的结果不会混合到一起。 该类型无法构造实例,只能通过 getStdOut() 获取标准输出实例或者 getStdErr() 获取标准错误的实例。
父类型:
func flush()
public func flush(): Unit
功能:刷新输出流。
func write(Array<Byte>)
public func write(buffer: Array<Byte>): Unit
功能:指定的将字节数组 buffer 写入标准输出或标准错误流中。
参数:
func write(Bool)
public func write(v: Bool): Unit
功能:将指定的布尔值的文本表示形式写入标准输出或标准错误流中。
参数:
- v: Bool - 要写入的值。
func write(Float16)
public func write(v: Float16): Unit
功能:将指定的 16 位浮点数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Float16 - 要写入的值。
func write(Float32)
public func write(v: Float32): Unit
功能:将指定的 32 位浮点数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Float32 - 要写入的值。
func write(Float64)
public func write(v: Float64): Unit
功能:将指定的 64 位浮点数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Float64 - 要写入的值。
func write(Int16)
public func write(v: Int16): Unit
功能:将指定的 16 位有符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Int16 - 要写入的值。
func write(Int32)
public func write(v: Int32): Unit
功能:将指定的 32 位有符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Int32 - 要写入的值。
func write(Int64)
public func write(v: Int64): Unit
功能:将指定的 64 位有符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Int64 - 要写入的值。
func write(Int8)
public func write(v: Int8): Unit
功能:将指定的 8 位有符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: Int8 - 要写入的值。
func write(Rune)
public func write(v: Rune): Unit
功能:将指定的 Rune 的 Unicode 字符值写入标准输出或标准错误流中。
参数:
- v: Rune - 要写入的值。
func write(String)
public func write(v: String): Unit
功能:将指定的字符串值写入标准输出或标准错误流中。
参数:
- v: String - 要写入的值。
func write(UInt16)
public func write(v: UInt16): Unit
功能:将指定的 16 位无符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: UInt16 - 要写入的值。
func write(UInt32)
public func write(v: UInt32): Unit
功能:将指定的 32 位无符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: UInt32 - 要写入的值。
func write(UInt64)
public func write(v: UInt64): Unit
功能:将指定的 64 位无符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: UInt64 - 要写入的值。
func write(UInt8)
public func write(v: UInt8): Unit
功能:将指定的 8 位无符号整数值的文本表示写入标准输出或标准错误流中。
参数:
- v: UInt8 - 要写入的值。
func write<T>(T) where T <: ToString
public func write<T>(v: T): Unit where T <: ToString
功能:将实现了 ToString 接口的数据类型写入标准输出或标准错误流中。
参数:
- v: T - 要被写入的 ToString 类型的实例。
func writeln(Array<Byte>)
public func writeln(buffer: Array<Byte>): Unit
功能:指定的将字节数组 buffer (后跟换行符)写入标准输出或标准错误流中。
参数:
func writeln(Bool)
public func writeln(v: Bool): Unit
功能:将指定的布尔值的文本表示形式(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Bool - 要写入的值。
func writeln(Float16)
public func writeln(v: Float16): Unit
功能:将指定的 16 位浮点数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Float16 - 要写入的值。
func writeln(Float32)
public func writeln(v: Float32): Unit
功能:将指定的 32 位浮点数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Float32 - 要写入的值。
func writeln(Float64)
public func writeln(v: Float64): Unit
功能:将指定的 64 位浮点数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Float64 - 要写入的值。
func writeln(Int16)
public func writeln(v: Int16): Unit
功能:将指定的 16 位有符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Int16 - 要写入的值。
func writeln(Int32)
public func writeln(v: Int32): Unit
功能:将指定的 32 位有符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Int32 - 要写入的值。
func writeln(Int64)
public func writeln(v: Int64): Unit
功能:将指定的 64 位有符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Int64 - 要写入的值。
func writeln(Int8)
public func writeln(v: Int8): Unit
功能:将指定的 8 位有符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Int8 - 要写入的值。
func writeln(Rune)
public func writeln(v: Rune): Unit
功能:将指定的 Unicode 字符值(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: Rune - 要写入的值。
func writeln(String)
public func writeln(v: String): Unit
功能:将指定的字符串值(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: String - 要写入的值。
func writeln(UInt16)
public func writeln(v: UInt16): Unit
功能:将指定的 16 位无符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: UInt16 - 要写入的值。
func writeln(UInt32)
public func writeln(v: UInt32): Unit
功能:将指定的 32 位无符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。 参数:
- v: UInt32 - 要写入的值。
func writeln(UInt64)
public func writeln(v: UInt64): Unit
功能:将指定的 64 位无符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: UInt64 - 要写入的值。
func writeln(UInt8)
public func writeln(v: UInt8): Unit
功能:将指定的 8 位无符号整数值的文本表示(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: UInt8 - 要写入的值。
func writeln<T>(T) where T <: ToString
public func writeln<T>(v: T): Unit where T <: ToString
功能:将实现了 ToString 接口的数据类型转换成的字符串(后跟换行符)写入标准输出或标准错误流中。
参数:
- v: T - 要写入的值。
异常
class EnvException
public class EnvException <: Exception {
public init(message: String)
}
功能:env 包的异常类。
父类型:
init(String)
public init(message: String)
功能:创建 EnvException 实例。
参数:
- message: String - 异常提示信息。
env 相关操作
当前进程相关操作
代码如下:
import std.env.*
main(): Int64 {
println(getProcessId())
println(getCommand())
println(getCommandLine().toString())
println(getWorkingDirectory().toString())
atExit(printText)
exit(0)
return 0
}
func printText(): Unit {
println("hello cangjie!")
}
运行结果可能如下(输出结果中main为当前进程执行命令名,回调执行完成后当前进程会退出):
28481
main
[./main]
/root/code/workpalce/cangjie
hello cangjie!
Console 示例
下面是 Console 示例,示例中接收用户输入的两条信息,并将这些信息通过标准输出原样返回给用户。
import std.env.*
main() {
getStdOut().write("请输入信息1:")
var c = getStdIn().readln() // 输入:你好,请问今天星期几?
var r = c.getOrThrow()
getStdOut().writeln("输入的信息1为:" + r)
getStdOut().write("请输入信息2:")
c = getStdIn().readln() // 输入:你好,请问今天几号?
r = c.getOrThrow()
getStdOut().writeln("输入的信息2为:" + r)
return
}
运行结果:
请输入信息1:你好,请问今天星期几?
输入的信息1为:你好,请问今天星期几?
请输入信息2:你好,请问今天几号?
输入的信息2为:你好,请问今天几号?
std.fs
功能介绍
fs(file system)包提供对文件、文件夹、路径、文件元数据信息的一些操作函数。
目前支持 Linux,macOS 和 Windows 平台下使用。
API 列表
函数
| 函数名 | 功能 |
|---|---|
| canonicalize(Path) | 将 Path 实例规范化,获取绝对路径形式的规范化路径。 |
| canonicalize(String) | 用 path 字符串构造 Path 实例,并进行规范化,获取绝对路径形式的规范化路径。 |
| copy(Path, Path, Bool) | 实现文件系统的拷贝功能,用于于复制文件或目录。 |
| copy(String, String, Bool) | 实现文件系统的拷贝功能,用于于复制文件或目录。 |
| exists(Path) | 判断目标地址是否存在。 |
| exists(String) | 判断目标地址是否存在。 |
| rename(Path, Path, Bool) | 重命名文件。 |
| rename(String, String, Bool) | 重命名文件。 |
| remove(Path, Bool) | 删除文件或目录。 |
| remove(String, Bool) | 删除文件或目录。 |
| removeIfExists(Path, Bool) | 判断目标是否存在,如果存在则删除。 |
| removeIfExists(String, Bool) | 判断目标是否存在,如果存在则删除。 |
类
| 类名 | 功能 |
|---|---|
| Directory | 对应文件系统中的目录,它提供创建、查询属性以及遍历目录等能力。 |
| File | 提供一些对文件进行操作的函数,包括文件的打开、创建、关闭、文件的流式读写操作、查询属性以及一些其他函数。 |
| HardLink | 提供处理文件系统硬链接相关接口。 |
| SymbolicLink | 提供处理文件系统符号链接相关接口。 |
枚举
| 枚举名 | 功能 |
|---|---|
| OpenMode | 表示不同的文件打开模式。 |
结构体
| 结构体名 | 功能 |
|---|---|
| FileDescriptor | 用于获取文件句柄信息。 |
| FileInfo | 对应文件系统中的文件元数据,提供一些文件属性的查询和设置等函数。 |
| Path | 提供路径相关的函数。 |
异常类
| 异常类名 | 功能 |
|---|---|
| FSException | 文件流异常类,继承了 IO 流异常类。 |
函数
func canonicalize(Path)
public func canonicalize(path: Path): Path
功能:将 Path 实例规范化,获取绝对路径形式的规范化路径。
所有的中间引用和软链接都会处理(UNC 路径下的软链接无法被规范化),例如,对于路径 "/foo/test/../test/bar.txt",该函数会返回 "/foo/test/bar.txt"。
参数:
返回值:
异常:
- FSException - 路径不存在或无法规范化时抛出异常。
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func canonicalize(String)
public func canonicalize(path: String): Path
功能:用 path 字符串构造 Path 实例,并进行规范化,获取绝对路径形式的规范化路径。
所有的中间引用和软链接都会处理 (UNC 路径下的软链接无法被规范化),例如,对于路径 "/foo/test/../test/bar.txt",该函数会返回 "/foo/test/bar.txt"。
参数:
- path: String - 待规范化的路径字符串。
返回值:
异常:
- FSException - 路径不存在或无法规范化时抛出异常。
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func copy(Path, Path, Bool)
public func copy(sourcePath: Path, to!: Path, overwrite!: Bool = false): Unit
功能:实现文件系统的拷贝功能,用于复制文件或目录。
当目标位置存在且 overwrite 为 true 时,该函数要求 sourcePath 的类型与 to 的类型一致,比如,sourcePath 的类型是 Directory,to 的类型也应该是 Directory,否则函数会抛出异常 FSException。当前支持的文件类型有文件夹(Directory),常规文件(Regular file),符号链接(SymbolicLink)。
参数:
异常:
- FSException - 如果源文件类型和目标文件类型不一致会抛出异常或者
overwrite为false并且目标地址存在时抛出异常。 - IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func copy(String, String, Bool)
public func copy(sourcePath: String, to!: String, overwrite!: Bool = false): Unit
功能:实现文件系统的拷贝功能,用于复制文件或目录。
当目标位置存在且 overwrite 为 true 时,该函数要求 sourcePath 的类型与 to 的类型一致,比如,sourcePath 的类型是 Directory,to 的类型也应该是 Directory,否则函数会抛出异常 FSException。当前支持的文件类型有文件夹(Directory),常规文件(Regular file),符号链接(SymbolicLink)。
参数:
异常:
- FSException - 如果源文件类型和目标文件类型不一致会抛出异常或者
overwrite为false并且目标地址存在时抛出异常。 - IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func exists(Path)
public func exists(path: Path): Bool
功能:判断目标地址是否存在。
参数:
- path: Path - 待判断的目标地址。
返回值:
- Bool - 目标地址是否存在。
异常:
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func exists(String)
public func exists(path: String): Bool
功能:判断目标地址是否存在。
参数:
- path: String - 待判断的目标地址。
返回值:
- Bool - 目标地址是否存在。
异常:
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func rename(Path, Path, Bool)
public func rename(sourcePath: Path, to!: Path, overwrite!: Bool = false): Unit
功能:将 sourcePath 指定的文件或者目录重命名为由 to 给定的名称,sourcePath 必须是现有文件或者目录的路径,如果 to 是现有文件或者目录的路径时,其具体行为由 overwrite 指定, 如果 overwrite 为 true,将会删除现有的文件或者目录,再执行重命名操作,否则会抛出异常。
注意:
当
overwrite为true时,rename的一个隐含行为是删除目标位置的原有文件或者目录,如果目标位置是目录,将会递归删除目录内的所有内容,需要谨慎使用。
参数:
异常:
- FSException - 操作系统执行rename方法失败时抛出异常。
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func rename(String, String, Bool)
public func rename(sourcePath: String, to!: String, overwrite!: Bool = false): Unit
功能:将 sourcePath 指定的文件或者目录重命名为由 to 给定的名称,sourcePath 必须是现有文件或者目录的路径,如果 to 是现有文件或者目录的路径时,其具体行为由 overwrite 指定, 如果 overwrite 为 true,将会删除现有的文件或者目录,再执行重命名操作,overwrite 为 false 会抛出异常。
注意:
当
overwrite为true时,rename的一个隐含行为是删除目标位置的原有文件或者目录,如果目标位置是目录,将会递归删除目录内的所有内容,需要谨慎使用。
参数:
异常:
- FSException - 操作系统执行rename方法失败时抛出异常。
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func remove(Path, Bool)
public func remove(path: Path, recursive!: Bool = false): Unit
功能:删除文件或目录。
当目标是文件夹时,可选择是否递归删除文件夹。
参数:
异常:
- FSException - 如果指定目录不存在或删除失败,则抛出异常。
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func remove(String, Bool)
public func remove(path: String, recursive!: Bool = false): Unit
功能:删除文件或目录。
当目标是文件夹时,可选择是否递归删除文件夹。
参数:
异常:
- FSException - 如果指定目录不存在或删除失败,则抛出异常。
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func removeIfExists(Path, Bool)
public func removeIfExists(path: Path, recursive!: Bool = false): Bool
功能:判断目标是否存在,如果存在则执行remove方法,并返回 true。
参数:
返回值:
- Bool - 目标地址是否存在。
异常:
- FSException - 如果删除失败,抛出此异常。
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
func removeIfExists(String, Bool)
public func removeIfExists(path: String, recursive!: Bool = false): Bool
功能:判断目标是否存在,如果存在则执行 remove 方法,并返回 true。
参数:
返回值:
- Bool - 目标地址是否存在。
异常:
- FSException - 如果删除失败,抛出此异常。
- IllegalArgumentException - 路径为空或包含字符串结束符时抛出异常。
类
class Directory
public class Directory {}
功能:对应文件系统中的目录,它提供创建、移动、复制、删除、查询属性以及遍历目录等能力。
说明:
非法路径指的是以下情况之一:
- 路径中包含非法字符,例如空格、制表符、换行符等;
- 路径中包含不合法的字符,例如特殊字符、控制字符等;
- 路径中包含不存在的目录或文件;
- 路径中包含无法访问的目录或文件,例如权限不足或被锁定等。
在输入路径时,应该避免使用非法字符,确保路径的合法性,以便正确地访问目标文件或目录。
static func create(Path, Bool)
public static func create(path: Path, recursive!: Bool = false): Unit
功能:创建目录。
可指定是否递归创建,如果需要递归创建,将逐级创建路径中不存在的目录。
参数:
异常:
- FSException - 目录已存在时,抛出异常;非递归时中间有不存在的目录时抛出异常。
- IllegalArgumentException - 目录为空、目录为当前目录、目录为根目录或目录中存在空字符时抛出异常。
static func create(String, Bool)
public static func create(path: String, recursive!: Bool = false): Unit
功能:创建目录。
可指定是否递归创建,如果需要递归创建,将逐级创建路径中不存在的目录。
参数:
异常:
- FSException - 目录已存在时,抛出异常;非递归时中间有不存在的目录时抛出异常。
- IllegalArgumentException - 目录为空、目录为当前目录、目录为根目录或目录中存在空字符时抛出异常。
static func createTemp(Path)
public static func createTemp(directoryPath: Path): Path
功能:在指定目录下创建临时目录。
参数:
返回值:
- Path - 临时目录对应的路径。
异常:
- FSException - 目录不存在或创建失败时抛出异常。
- IllegalArgumentException - 目录为空或包含空字符时抛出异常。
static func createTemp(String)
public static func createTemp(directoryPath: String): Path
功能:在指定目录下创建临时目录。
参数:
- directoryPath: String - 字符串形式的目录路径。
返回值:
- Path - 临时目录对应的路径。
异常:
- FSException - 目录不存在或创建失败时抛出异常。
- IllegalArgumentException - 目录为空或包含空字符时抛出异常。
static func isEmpty(Path)
public static func isEmpty(path: Path): Bool
功能:判断指定目录是否为空。
参数:
- path: Path - 待判断是否为空的目录对应的路径。
返回值:
- Bool - 为 true 时目录为空,为 false 时不为空。
异常:
- FSException - 如果指定路径不存在、指定路径不是目录或判断过程中底层接口发生错误,则抛出异常。
- IllegalArgumentException - 当指定路径为空或包含空字符时,抛出异常。
static func isEmpty(String)
public static func isEmpty(path: String): Bool
功能:判断指定目录是否为空。
参数:
- path: String - 待判断是否为空的目录对应的路径。
返回值:
- Bool - 为 true 时目录为空,为 false 时不为空。
异常:
- FSException - 如果指定路径不存在、指定路径不是目录或判断过程中底层接口发生错误,则抛出异常。
- IllegalArgumentException - 当指定路径为空或包含空字符时,抛出异常。
static func readFrom(Path)
public static func readFrom(path: Path): Array<FileInfo>
功能:获取当前目录的子项目列表。
子项目在数组中的顺序取决于文件在系统中的排序。
参数:
- path: Path - 待读取其子项的目录对应的路径。
返回值:
异常:
- FSException - 当指定路径不存在、指定路径不是目录或获取目录的成员信息失败时,抛出异常。
- IllegalArgumentException - 当指定路径为空或包含空字符时,抛出异常。
static func readFrom(String)
public static func readFrom(path: String): Array<FileInfo>
功能:获取当前目录的子项目列表。
子项目在数组中的顺序取决于文件在系统中的排序。
参数:
- path: String - 待读取其子项目的目录对应的路径。
返回值:
异常:
- FSException - 当指定路径不存在、指定路径不是目录或获取目录的成员信息失败时,抛出异常。
- IllegalArgumentException - 当指定路径为空或包含空字符时,抛出异常。
static func walk(Path, (FileInfo)->Bool)
public static func walk(path: Path, f: (FileInfo)->Bool): Unit
功能:遍历 path 对应的目录下的子项目(非递归,即不包含子目录的子项目),对每一个子项目执行回调函数。
walk 函数退出条件为遍历结束或回调函数 f 返回 false。遍历顺序取决于文件在系统中的排序。
参数:
异常:
- FSException - 当指定路径不存在、指定路径不是目录或获取目录的成员信息失败时,抛出异常。
- IllegalArgumentException - 当指定路径为空或包含空字符时,抛出异常。
static func walk(String, (FileInfo)->Bool)
public static func walk(path: String, f: (FileInfo)->Bool): Unit
功能:遍历 path 对应的目录下的子项目(非递归,即不包含子目录的子项目),对每一个子项目执行回调函数。
walk 函数退出条件为遍历结束或回调函数 f 返回 false。遍历顺序取决于文件在系统中的排序。
参数:
异常:
- FSException - 当指定路径不存在、指定路径不是目录或获取目录的成员信息失败时,抛出异常。
- IllegalArgumentException - 当指定路径为空或包含空字符时,抛出异常。
class File
public class File <: Resource & IOStream & Seekable {
public init(path: String, mode: OpenMode)
public init(path: Path, mode: OpenMode)
}
功能:提供一些对文件进行操作的函数,包括文件的打开、创建、关闭、移动、复制、删除,文件的流式读写操作,查询属性以及一些其他函数。
说明:
非法路径指的是以下情况之一:
- 路径中包含非法字符,例如空格、制表符、换行符等;
- 路径中包含不合法的字符,例如特殊字符、控制字符等;
- 路径中包含不存在的目录或文件;
- 路径中包含无法访问的目录或文件,例如权限不足或被锁定等。
在输入路径时,应该避免使用非法字符,确保路径的合法性,以便正确地访问目标文件或目录。
注意:
父类型:
prop fileDescriptor
public prop fileDescriptor: FileDescriptor
功能:获取文件描述符信息。
prop info
public prop info: FileInfo
功能:获取文件元数据信息。
类型:FileInfo
prop length
public prop length: Int64
功能:获取文件头至文件尾的数据字节数。
类型:Int64
init(Path, OpenMode)
public init(path: Path, mode: OpenMode)
功能:创建一个 File 对象。
需指定文件路径和文件打开方式(读写权限),路径支持相对路径和绝对路径。
参数:
异常:
- FSException - 如果以只读方式打开文件但文件不存在、文件的父目录不存在或其他原因导致无法打开文件,则抛出异常。
- IllegalArgumentException - 如果 path 为空路径或者 path 路径中包含空字符,则抛出异常。
init(String, OpenMode)
public init(path: String, mode: OpenMode)
功能:创建 File 对象。
需指定文件路径和文件打开方式(读写权限),路径支持相对路径和绝对路径。
参数:
异常:
- FSException - 如果以只读方式打开文件但文件不存在、文件的父目录不存在或其他原因导致无法打开文件,则抛出异常。
- IllegalArgumentException - 如果 path 是空字符串或者 path 包含空字符,则抛出异常。
static func appendTo(Path, Array<Byte>)
public static func appendTo(path: Path, buffer: Array<Byte>): Unit
功能:打开指定路径的文件并将 buffer 以追加的方式写入,文件不存在则将创建文件。
参数:
异常:
- FSException - 文件打开失败或写入失败,则抛出异常。
- IllegalArgumentException - 如果文件路径为空或包含空字符,则抛出异常。
static func appendTo(String, Array<Byte>)
public static func appendTo(path: String, buffer: Array<Byte>): Unit
功能:打开指定路径的文件并将 buffer 以追加的方式写入,文件不存在则将创建文件。
参数:
异常:
- FSException - 文件打开失败或写入失败,则抛出异常。
- IllegalArgumentException - 如果文件路径为空或包含空字符,则抛出异常。
static func create(Path)
public static func create(path: Path): File
功能:以只写模式创建指定路径的文件。
参数:
- path: Path - 文件路径。
返回值:
异常:
- FSException - 如果路径指向的文件的上级目录不存在或文件已存在,则抛出异常。
- IllegalArgumentException - 如果文件路径为空或包含空字符,则抛出异常。
static func create(String)
public static func create(path: String): File
功能:以只写模式创建指定路径的文件。
参数:
- path: String - 文件路径字符串。
返回值:
异常:
- FSException - 如果路径指向的文件的上级目录不存在或文件已存在,则抛出异常。
- IllegalArgumentException - 如果文件路径为空字符串或包含空字符,则抛出异常。
static func createTemp(Path)
public static func createTemp(directoryPath: Path): File
功能:在指定目录下创建临时文件。
创建的文件名称是 tmpFileXXXXXX 形式,不使用的临时文件应手动删除。
参数:
- directoryPath: Path - 目录路径。
返回值:
异常:
- FSException - 创建文件失败或路径不存在则抛出异常。
- IllegalArgumentException - 如果文件路径为空或包含空字符,则抛出异常。
static func createTemp(String)
public static func createTemp(directoryPath: String): File
功能:在指定目录下创建临时文件。
创建的文件名称是 tmpFileXXXXXX 形式,不使用的临时文件应手动删除。
参数:
- directoryPath: String - 目录路径字符串。
返回值:
异常:
- FSException - 创建文件失败或路径不存在则抛出异常。
- IllegalArgumentException - 如果文件路径为空字符串或包含空字符,则抛出异常。
static func readFrom(Path)
public static func readFrom(path: Path): Array<Byte>
功能:根据指定路径读取文件全部内容,以字节数组的形式返回其内容。
参数:
- path: Path - 文件路径。
返回值:
异常:
- FSException - 文件路径为空、文件不可读、文件读取失败,则抛出异常。
- IllegalArgumentException - 文件路径包含空字符则抛出异常。
static func readFrom(String)
public static func readFrom(path: String): Array<Byte>
功能:根据指定路径读取文件全部内容,以字节数组的形式返回其内容。
参数:
- path: String - 文件路径字符串。
返回值:
异常:
- FSException - 文件读取失败、文件关闭失败、文件路径为空、文件不可读,则抛出异常。
- IllegalArgumentException - 文件路径包含空字符则抛出异常。
static func writeTo(Path, Array<Byte>)
public static func writeTo(path: Path, buffer: Array<Byte>): Unit
功能:打开指定路径的文件并将 buffer 以覆盖的方式写入,即文件存在时会将该文件截断为零字节大小,文件不存在则将创建文件。
参数:
异常:
- FSException - 文件打开失败或写入失败,则抛出异常。
- IllegalArgumentException - 如果文件路径为空或包含空字符,则抛出异常。
static func writeTo(String, Array<Byte>)
public static func writeTo(path: String, buffer: Array<Byte>): Unit
功能:打开指定路径的文件并将 buffer 以覆盖的方式写入,即文件存在时会将该文件截断为零字节大小,文件不存在则将创建文件。
参数:
异常:
- FSException - 文件打开失败或写入失败,则抛出异常。
- IllegalArgumentException - 如果文件路径为空字符串或包含空字符,则抛出异常。
func canRead()
public func canRead(): Bool
功能:判断当前 File 对象是否可读。
该函数返回值由创建文件对象的 openMode 所决定,文件对象关闭后返回 false。
返回值:
- Bool - 返回 true 表示可读,返回 false 表示不可读或文件对象已关闭。
func canWrite()
public func canWrite(): Bool
功能:判断当前 File 对象是否可写。
该函数返回值由创建文件对象的 openMode 所决定,文件对象关闭后返回 false。
返回值:
- Bool - 返回 true 表示可写,false 表示不可写或文件对象已关闭。
func close()
public func close(): Unit
功能:关闭当前 File 对象。
异常:
- FSException - 如果关闭失败,则抛出异常。
func flush()
public func flush(): Unit
功能:将缓冲区数据写入流。由于 File 不存在缓冲区,所以该函数没有具体作用。
func isClosed()
public func isClosed(): Bool
功能:判断当前 File 对象是否已关闭。
返回值:
- Bool - true 表示已关闭,false 表示未关闭。
func read(Array<Byte>)
public func read(buffer: Array<Byte>): Int64
功能:从文件中读出数据到 buffer 中。
参数:
返回值:
- Int64 - 读取成功,返回读取字节数,如果文件被读完,返回 0。
异常:
- IllegalArgumentException - 如果 buffer 为空,则抛出异常。
- FSException - 读取失败、文件已关闭或文件不可读,则抛出异常。
func seek(SeekPosition)
public func seek(sp: SeekPosition): Int64
功能:将光标跳转到指定位置。
指定的位置不能位于文件头部之前,指定位置可以超过文件末尾,但指定位置到文件头部的最大偏移量不能超过当前文件系统允许的最大值,这个最大值接近当前文件系统的所允许的最大文件大小,一般为最大文件大小减去 4096 个字节。
参数:
- sp: SeekPosition - 指定光标跳转后的位置。
返回值:
- Int64 - 返回文件头部到跳转后位置的偏移量(以字节为单位)。
异常:
- FSException - 指定位置不满足以上情况时或文件不能 seek 时均会抛出异常。
func setLength(Int64)
public func setLength(length: Int64): Unit
功能:将当前文件截断为指定长度。当 length 大于当前文件长度时,则将使用 0 填充文件直到目标长度。此方法不会改变文件光标的位置。
参数:
- length: Int64 - 指定截断的长度。
异常:
- IllegalArgumentException - 指定的长度为负数时抛出异常。
- FSException - 文件截断操作失败时,抛出异常。
func write(Array<Byte>)
public func write(buffer: Array<Byte>): Unit
功能:将 buffer 中的数据写入到文件中。
参数:
异常:
- FSException - 如果写入失败、只写入了部分数据、文件已关闭或文件不可写则抛出异常。
class HardLink
public class HardLink
功能:提供处理文件系统硬链接相关接口。
static func create(Path, Path)
public static func create(link: Path, to!: Path): Unit
功能:创建一个新的硬链接到现有路径。如果新的路径存在,则不会覆盖。
参数:
异常:
- IllegalArgumentException - 参数中路径为空、或者包含空字符时抛出异常。
- FSException - 创建硬链接失败时,抛出异常。
static func create(String, String)
public static func create(link: String, to!: String): Unit
功能:创建一个新的硬链接到现有路径。如果新的路径存在,则不会覆盖。
参数:
异常:
- IllegalArgumentException - 参数中路径为空、或者包含空字符时抛出异常。
- FSException - 创建硬链接失败时,抛出异常。
class SymbolicLink
public class SymbolicLink
功能:提供处理文件系统符号链接相关接口。
static func create(Path, Path)
public static func create(link: Path, to!: Path): Unit
功能:创建一个新的符号链接到现有路径。
说明:
在Windows上,创建一个目标不存在的符号链接时,会创建一个文件符号链接,如果目标路径后来被创建为目录,则符号链接将不起作用。
参数:
异常:
- IllegalArgumentException - 参数中路径为空、或者包含空字符时抛出异常。
- FSException - 创建符号链接失败时,抛出异常。
static func create(String, String)
public static func create(link: String, to!: String): Unit
功能:创建一个新的符号链接到现有路径。
说明:
在Windows上,创建一个目标不存在的符号链接时,会创建一个文件符号链接,如果目标路径后来被创建为目录,则符号链接将不起作用。
参数:
异常:
- IllegalArgumentException - 参数中路径为空、或者包含空字符时抛出异常。
- FSException - 创建符号链接失败时,抛出异常。
static func readFrom(Path, Bool)
public static func readFrom(path: Path, recursive!: Bool = false): Path
功能:获取指定符号链接的目标。当指定 'recursive' 为 'true' 时,表示跟踪指向最终目标的链接,并且返回目标的全路径,当指定 'recursive' 为 'false' 时,读取当前目标链接并且返回。
参数:
返回值:
- Path - 符号链接的目标地址。
异常:
- IllegalArgumentException - 参数中路径为空、或者包含空字符时抛出异常。
- FSException - 读取符号链接失败时,抛出异常。
static func readFrom(String, Bool)
public static func readFrom(path: String, recursive!: Bool = false): Path
功能:获取指定符号链接的目标。当指定 'recursive' 为 'true' 时,表示跟踪指向最终目标的链接,并且返回目标的全路径,当指定 'recursive' 为 'false' 时,读取当前目标链接并且返回。
参数:
返回值:
- Path - 符号链接的目标地址。
异常:
- IllegalArgumentException - 参数中路径为空、或者包含空字符时抛出异常。
- FSException - 读取符号链接失败时,抛出异常。
枚举
enum OpenMode
public enum OpenMode <: ToString & Equatable<OpenMode> {
| Read
| Write
| Append
| ReadWrite
}
功能:表示不同的文件打开模式。
父类型:
Read
Read
功能:构造一个 OpenMode 实例,指定以只读的方式打开文件。如果文件不存在,则将引发 FSException 异常。
Write
Write
功能:构造一个 OpenMode 实例,指定以只写的方式打开文件,即文件存在时会将该文件截断为零字节大小,文件不存在则将创建文件。
Append
Append
功能:构造一个 OpenMode 实例,指定以追加写入的方式打开文件。如果文件不存在,则将创建文件。
ReadWrite
ReadWrite
功能:构造一个 OpenMode 实例,指定以可读可写的方式打开文件。如果文件不存在,则将创建文件。
注意:
ReadWrite 模式不会使文件被截断为零字节大小。
func toString()
public func toString(): String
功能:文件打开模式的字符串表示。
返回值:
- String - 文件打开模式名称。
func operator func ==(OpenMode)
public operator func ==(that: OpenMode): Bool
功能:比较 OpenMode 实例是否相等。
参数:
返回值:
- Bool - 如果相等,则返回 true,否则返回 false。
func operator func !=(OpenMode)
public operator func !=(that: OpenMode): Bool
功能:比较 OpenMode 实例是否不等。
参数:
返回值:
- Bool - 如果不相等,则返回 true,否则返回 false。
结构体
struct FileDescriptor
public struct FileDescriptor
功能:用于获取文件句柄信息。
说明:
文件句柄(File Handle)是操作系统为了跟踪文件而分配的一种数据结构,用于标识一个打开文件的实例。文件句柄包含了文件的元数据信息(如文件名、路径、大小、修改时间等)以及文件数据在磁盘上的物理位置等信息。 在不同的操作系统中,文件句柄的形式可能会有所不同。在 Unix 和 Linux 系统中,文件句柄通常是一个非负整数,由操作系统内核分配,并在打开文件时返回给应用程序。在 Windows 系统中,文件句柄通常是一个指向文件对象的指针,由操作系统内核分配,并在打开文件时返回给应用程序。无论文件句柄的形式是什么,应用程序都可以使用它来执行文件的读取、写入、修改等操作。
prop fileHandle
public prop fileHandle: IntNative
功能:获取文件句柄信息。
类型:IntNative
struct FileInfo
public struct FileInfo <: Equatable<FileInfo> {
public init(path: Path)
public init(path: String)
}
功能:对应文件系统中的文件元数据。
说明:
文件元数据是指文件系统中与文件相关的信息,包括文件名、文件大小、创建时间、修改时间、访问时间、文件权限、文件所有者等。
FileInfo 的底层实现是没有直接缓存文件属性的,每次通过 FileInfo 的 API 都是现场获取的最新的文件属性。
因此这里有需要注意的情况,对于创建的同一 FileInfo 实例,如果在两次获取其文件属性操作期间,对应的文件实体可能会被其他用户或进程做了修改或者替换等不期望的操作,就会导致后一次获取的可能不是期望的文件属性。 如果有特殊文件操作需求需要避免上述情况的产生,可以采用设置文件权限或者给关键文件操作加锁的方式来保证。
父类型:
prop creationTime
public prop creationTime: DateTime
功能:获取创建时间。
类型:DateTime
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
prop lastAccessTime
public prop lastAccessTime: DateTime
功能:获取最后访问时间。
类型:DateTime
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
prop lastModificationTime
public prop lastModificationTime: DateTime
功能:获取最后修改时间。
类型:DateTime
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
prop name
public prop name: String
功能:获取当前实例对应的文件名或目录名。
该属性与 this.path.fileName 等价,路径解析规则详见 Path 结构体的 fileName 属性。
类型:String
prop parentDirectory
public prop parentDirectory: Option<FileInfo>
功能:获得父级目录元数据,以 Option<FileInfo> 形式返回,有父级返回 Option<FileInfo>.Some(v);否则返回 Option<FileInfo>.None。
prop path
public prop path: Path
功能:获得当前文件路径,以 Path 形式返回。
类型:Path
prop size
public prop size: Int64
功能:返回当前文件大小。
- 当前是文件时,表示单个文件占用磁盘空间的大小。
- 当前是目录时,表示当前目录的所有文件占用磁盘空间的大小。
类型:Int64
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
init(Path)
public init(path: Path)
功能:创建 FileInfo 实例。
参数:
异常:
- FSException - 当路径非法时,抛出异常。
- IllegalArgumentException - 当路径为空,或包含字符串结束符则抛出异常。
init(String)
public init(path: String)
功能:创建 FileInfo 实例。
参数:
异常:
- FSException - 当路径非法时,抛出异常。
- IllegalArgumentException - 当路径为空,或包含字符串结束符则抛出异常。
func canExecute()
public func canExecute(): Bool
功能:判断当前用户是否有权限执行该实例对应的文件。
- 对文件而言,判断用户是否有执行文件的权限。
- 对目录而言,判断用户是否有进入目录的权限。
- 在 Windows 环境下,用户对于文件的执行权限由文件扩展名决定;用户始终拥有对于目录的执行权限,该函数不生效,返回 true。
- 在 Linux 和 macOS 环境下,该函数正常使用。
返回值:
- Bool - true 表示有权限;false 表示无权限。
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
func canRead()
public func canRead(): Bool
功能:判断当前用户是否有权限读取该实例对应的文件。
- 对文件而言,判断用户是否有读取文件的权限。
- 对目录而言,判断用户是否有浏览目录的权限。
- 在 Windows 环境下,用户始终拥有对于文件和目录的可读权限,该函数不生效,返回 true。
- 在 Linux 和 macOS 环境下,该函数正常使用。
返回值:
- Bool - true 表示有权限;false 表示无权限。
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
func canWrite()
public func canWrite(): Bool
功能:判断当前用户是否有权限写入该实例对应的文件。
- 对文件而言,判断用户是否有写入文件的权限。
- 对目录而言,判断用户是否有删除、移动、创建目录内文件的权限。
- 在 Windows 环境下,用户对于文件的可写权限正常使用,用户始终拥有对于目录的可写权限,该函数不生效,返回 true。
- 在 Linux 和 macOS 环境下,该函数正常使用。
返回值:
- Bool - true 表示有权限;false 表示无权限。
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
func isDirectory()
public func isDirectory(): Bool
功能:判断当前文件是否是目录。
返回值:
- Bool - true 表示是目录;false 表示不是目录。
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
func isRegular()
public func isRegular(): Bool
功能:判断当前文件是否是普通文件。
返回值:
- Bool - true 表示是文件;false 表示不是文件。
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
func isHidden()
public func isHidden(): Bool
功能:判断当前文件是否隐藏。
返回值:
- Bool - true 表示隐藏;false 表示未隐藏。
func isReadOnly()
public func isReadOnly(): Bool
功能:判断当前文件是否只读。
- 在 Windows 环境下,用户对于文件的只读权限正常使用;用户始终拥有对于目录的删除修改权限,该函数不生效,返回 false。
- 在 Linux 和 macOS 环境下,该函数正常使用。
返回值:
- Bool - true 表示是只读;false 表示不是只读。
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
func isSymbolicLink()
public func isSymbolicLink(): Bool
功能:判断当前文件是否是软链接。
返回值:
- Bool - true 表示是软链接;false 表示不是软链接。
异常:
- FSException - 如果判断过程中底层接口发生错误,则抛出异常。
func setExecutable(Bool)
public func setExecutable(executable: Bool): Bool
功能:对当前实例对应的文件设置当前用户是否可执行的权限,当前用户没有权限修改抛出异常。
- 对文件而言,设置用户是否有执行文件的权限,对目录而言,设置用户是否有进入目录的权限。
- 在 Windows 环境下,用户对于文件的执行权限由文件扩展名决定,用户始终拥有对于目录的执行权限该函数不生效,返回 false。
- 在 Linux 和 macOS 环境下,该函数正常使用如果在此函数调用期间,该 FileInfo 对应的文件实体被其他用户或者进程修改,有可能因为竞争条件(Race Condition)导致其他修改不能生效。
参数:
- executable: Bool - 是否设置可执行。
返回值:
- Bool - true,操作成功;false,操作失败。
func setReadable(Bool)
public func setReadable(readable: Bool): Bool
功能:对当前实例对应的文件设置当前用户是否可读取的权限,当前用户没有权限修改抛出异常。
- 对文件而言,设置用户是否有读取文件的权限。
- 对目录而言,设置用户是否有浏览目录的权限。
- 在 Windows 环境下,用户始终拥有对于文件以及目录的可读权限,不可更改,该函数不生效当 readable 为 true 时,函数返回 true,当 readable 为 false 时,函数返回 false。
- 在 Linux 和 macOS 环境下,该函数正常使用如果在此函数调用期间,该 FileInfo 对应的文件实体被其他用户或者进程修改,有可能因为竞争条件(Race Condition)导致其他修改不能生效。
参数:
- readable: Bool - 是否设置可读。
返回值:
- Bool - true,操作成功;false,操作失败。
func setWritable(Bool)
public func setWritable(writable: Bool): Bool
功能:对当前实例对应的文件设置当前用户是否可写入的权限,当前用户没有权限修改抛出异常。
- 对文件而言,设置用户是否有写入文件的权限。
- 对目录而言,设置用户是否有删除、移动、创建目录内文件的权限。
- 在 Windows 环境下,用户对于文件的可写权限正常使用;用户始终拥有对于目录的可写权限,不可更改,该函数不生效,返回 false。
- 在 Linux 和 macOS 环境下,该函数正常使用如果在此函数调用期间,该 FileInfo 对应的文件实体被其他用户或者进程修改,有可能因为竞争条件(Race Condition)导致其他修改不能生效。
参数:
- writable: Bool - 是否设置可写。
返回值:
- Bool - true,操作成功;false,操作失败。
operator func ==(FileInfo)
public operator func ==(that: FileInfo): Bool
功能:判断当前 FileInfo 和另一个 FileInfo 是否对应同一文件。
参数:
返回值:
- Bool - true,是同一文件;false,不是同一文件。
struct Path
public struct Path <: Equatable<Path> & Hashable & ToString {
public static const Separator: String = PATH_SEPARATOR
public static const ListSeparator: String = PATH_LISTSEPARATOR
public init(rawPath: String)
}
功能:提供路径相关的函数。
Path 用来表示本地路径(Windows 平台已支持 DOS 设备路径和 UNC 路径,长度限制跟随系统)。 路径的字符串最大支持 4096 个字节(包括结束符 \0)。
说明:
非法路径指的是以下情况之一:
- 路径中包含非法字符,例如空格、制表符、换行符等;
- 路径中包含不合法的字符,例如特殊字符、控制字符等;
- 路径中包含不存在的目录或文件;
- 路径中包含无法访问的目录或文件,例如权限不足或被锁定等。
在输入路径时,应该避免使用非法字符,确保路径的合法性,以便正确地访问目标文件或目录。
父类型:
static const ListSeparator
public static const ListSeparator: String = PATH_LISTSEPARATOR
功能:获取路径列表分隔符,用于分隔路径列表中的不同路径。
Windows 系统中路径列表分隔符为 ";",非 Windows 系统中为 ":"。
类型:String
static const Separator
public static const Separator: String = PATH_SEPARATOR
功能:获取路径分隔符,用于分隔多级目录。
Windows 系统中分隔符为 "\",非 Windows 系统中为 "/"。
类型:String
prop extensionName
public prop extensionName: String
功能:获得 Path 的文件扩展名部分。
文件名 fileName 根据最后一个 r'.' 被划分为不带扩展名的文件名 fileNameWithoutExtension 和扩展名 extensionName 两部分。无扩展名时返回空字符串。
- 对于路径 "./NewFile.txt",此属性返回
"txt"。 - 对于路径 "./.gitignore",此属性返回
"gitignore"。 - 对于路径 "./noextension",此属性返回
""。 - 对于路径 "./a.b.c",此属性返回
"c"。 - 对于路径 "./NewFile.txt/",此属性返回
"txt"。
类型:String
异常:
- IllegalArgumentException - 当路径为空或包含字符串结束符则抛出异常。
prop fileName
public prop fileName: String
功能:获得 Path 的文件名(含扩展名)部分。
整个路径字符串被划分为 parent 和 fileName 两部分,详见 parent。无文件名时返回空字符串。
以下示例适用于所有系统:
- 对于路径 "./NewFile.txt",此属性返回 "NewFile.txt";
- 对于路径 "./.gitignore",此属性返回 ".gitignore";
- 对于路径 "./noextension",此属性返回 "noextension";
- 对于路径 "./a.b.c",此属性返回 "a.b.c";
- 对于路径 "./NewDir/",此属性返回 "NewDir";
特别地,在 Windows 文件系统中,fileName 不包括卷名部分。
以下示例仅适用于 Windows 系统:
- 对于路径 "c:\a.txt",此属性返回 "a.txt";
- 对于路径 "c:",此属性返回 "";
- 对于路径 "\\Server\Share\a.txt",此属性返回 "a.txt";
- 对于路径 "\\Server\Share\",此属性返回 "";
- 对于路径 "\\?\C:a\b.txt",此属性返回 "b.txt";
- 对于路径 "\\?\C:",此属性返回 ""。
类型:String
异常:
- IllegalArgumentException - 当路径为空或包含字符串结束符则抛出异常。
prop fileNameWithoutExtension
public prop fileNameWithoutExtension: String
功能:获得 Path 的文件名(不含扩展名)部分。
文件名 fileName 根据最后一个 r'.' 被划分为不带扩展名的文件名 fileNameWithoutExtension 和扩展名 extensionName 两部分。无文件名(不含扩展名)时返回空字符串。
- 对于路径 "./NewFile.txt",此属性返回
"NewFile"。 - 对于路径 "./.gitignore",此属性返回
""。 - 对于路径 "./noextension",此属性返回
"noextension"。 - 对于路径 "./a.b.c",此属性返回
"a.b"。 - 对于路径 "./NewFile/",此属性返回
"NewFile"。
类型:String
异常:
- IllegalArgumentException - 当路径为空或包含字符串结束符则抛出异常。
prop parent
public prop parent: Path
功能:获得该 Path 实例的父路径。
整个路径字符串被划分为 parent 和 fileName,以最后一个有效文件分隔符(末尾的分隔符会被忽略)作为分界。如果 parent 不存在,就返回空字符串构造的 Path 实例。parent 和 fileName 部分都不包含末尾分隔符,parent 保留表示根目录的分隔符。无父目录时返回空的 Path 实例。
该属性不会访问文件系统,也不会消除特殊名称。如果有需要可以跟规范化搭配使用。
该属性在不同操作系统行为有差异,在 Windows 系统中,文件分隔符为 "\" 或 "/"(规范化时会统一转换为 "\"),在 Linux、macOS、ohos 系统中,文件分隔符为 "/"。
以下示例适用于所有系统:
- 对于路径 "/a/b/c",此属性返回 Path("/a/b");
- 对于路径 "/a/b/",此属性返回 Path("/a");
- 对于路径 "/a",此属性返回 Path("/");
- 对于路径 "/",此属性返回 Path("/");
- 对于路径 "./a/b",此属性返回 Path("./a");
- 对于路径 "./",此属性返回 Path("");
- 对于路径 ".gitignore",此属性返回 Path("");
- 对于路径 "/a/./../b",此属性返回 Path("/a/./..")。
此外,在 Windows 系统中,path 被分为卷名、目录名和文件名,详情请参见微软官方文档。属性 parent 包含卷名和目录名。
以下示例仅适用于 Windows 系统:
- 对于路径 "C:",此属性返回 Path("C:");
- 对于路径 "C:\a\b",此属性返回 Path("C:\a");
- 对于路径 "\\Server\Share\xx\yy",此属性返回 Path("\\Server\Share\xx");
- 对于路径 "\\?\UNC\Server\Share\xx\yy",此属性返回 Path("\\?\UNC\Server\Share\xx");
- 对于路径 "\\?\c:\xx\yy",此属性返回 Path("\\?\c:\xx")。
类型:Path
异常:
- IllegalArgumentException - 当路径为空或包含字符串结束符则抛出异常。
init(String)
public init(rawPath: String)
功能:创建 Path 实例时不检查路径字符串是否合法,支持绝对路径和相对路径。
参数:
- rawPath: String - 路径的字符串。
func hashCode()
public func hashCode(): Int64
功能:获得 Path 的哈希值。
返回值:
func isAbsolute()
public func isAbsolute(): Bool
功能:判断 Path 是否是绝对路径。在 Unix 中,以 / 开头的路径为绝对路径。
返回值:
- Bool - true,是绝对路径;false,不是绝对路径。
异常:
- IllegalArgumentException - 当路径为空或包含字符串结束符则抛出异常。
func isEmpty()
public func isEmpty(): Bool
功能:判断当前实例是否为空路径。
返回值:
- Bool - 如果当前实例为空路径,返回 true,否则返回 false。
func isRelative()
public func isRelative(): Bool
功能:判断 Path 是否是相对路径,其结果与函数 isAbsolute 结果相反。
返回值:
- Bool - true,是相对路径;false,不是相对路径。
异常:
- IllegalArgumentException - 当路径为空或包含字符串结束符则抛出异常。
func join(Path)
public func join(path: Path): Path
功能:在当前路径后拼接另一个路径字符串形成新路径。
- 对于路径 "a/b","c",返回 "a/b/c"。
- 对于路径 "a","b/c",返回 "a/b/c"。
返回值:
异常:
- FSException - 如果参数 path 是绝对路径则抛出异常。
- IllegalArgumentException - 当前路径为空或当前路径、入参路径非法时抛出异常。
func join(String)
public func join(path: String): Path
功能:在当前路径后拼接另一个路径字符串形成新路径。
- 对于路径 "a/b","c",返回 "a/b/c"。
- 对于路径 "a","b/c",返回 "a/b/c"。
返回值:
异常:
- FSException - 如果参数 path 是绝对路径则抛出异常。
- IllegalArgumentException - 当前路径为空或当前路径、入参路径非法时抛出异常。
func normalize()
public func normalize(): Path
功能:将路径字符串进行规范化处理,并用规范化后的字符串构造新的 Path 实例。该函数仅做字符串解析,不会进行 io 操作。
规范化规则:
- 将连续的多个路径分隔符替换为单个路径分隔符;
- 删除末尾的路径分隔符(不删除作为根目录的路径分隔符或卷名中的字符);
- 删除每一个 "." 路径名元素(代表当前目录);
- 删除每一个路径内的 ".." 路径名元素(代表父目录)和它前面的非 ".." 路径名元素;
- 删除开始于根路径的 ".." 路径名元素,即将路径开始处的 "/.." 替换为 "/"(Windows 系统中还会将 "\.." 替换为 "\");
- 相对路径保留开头的 "../"(Windows 系统中还将保留 "..\");
- 最后如果得到空路径,返回 Path(".")。
特别地,Windows 文件系统中,卷名部分仅做分隔符转换,即 "/" 转换为 "\"。
返回值:
func toString()
public func toString(): String
功能:获得 Path 的路径字符串。
返回值:
operator func ==(Path)
public operator func ==(that: Path): Bool
功能:判断 Path 是否相等。
判等时将对 Path 进行规范化,如果规范化后的字符串相等,则认为两个 Path 实例相等。规范化规则详见函数 normalize。
参数:
返回值:
- Bool - true,是同一路径;false,不是同一路径。
异常类
class FSException
public class FSException <: IOException {
public init()
public init(message: String)
}
功能:文件流异常类,继承了 IO 流异常类。
父类型:
init()
public init()
功能:构造一个文件异常实例,无异常提示信息。
init(String)
public init(message: String)
功能:构造一个文件异常实例,有异常提示信息。
参数:
- message: String - 错误信息。
Directory 示例
Directory 一些基础操作演示
代码如下:
import std.fs.*
main() {
let testDirPath: Path = Path("./testDir")
let subDirPath: Path = Path("./testDir/subDir")
if (exists(testDirPath)) {
remove(testDirPath, recursive: true)
}
/* 递归创建目录 和 "./testDir/subDir" */
Directory.create(subDirPath, recursive: true)
if (exists(subDirPath)) {
println("The directory './testDir/subDir' is successfully created recursively in current directory.")
}
/* 在 "./testDir" 下创建临时目录 */
let tempDirPath: Path = Directory.createTemp(testDirPath)
if (exists(tempDirPath)) {
println("The temporary directory is created successfully in directory './testDir'.")
}
/* 将 "subDir" 移动到临时目录下并重命名为 "subDir_new" */
let newSubDirPath: Path = tempDirPath.join("subDir_new")
rename(subDirPath, to: newSubDirPath)
if (exists(newSubDirPath) && !exists(subDirPath)) {
println("The directory './testDir/subDir' is moved successfully to the temporary directory and renamed 'subDir_new'.")
}
/* 将 "subDir_new" 拷贝到 "./testDir" 下并重命名为 "subDir" */
copy(newSubDirPath, to: subDirPath, overwrite: false)
if (exists(subDirPath) && exists(newSubDirPath)) {
println("The directory 'subDir_new' is copied successfully to directory './testDir' and renamed 'subDir'.")
}
remove(testDirPath, recursive: true)
return 0
}
运行结果:
The directory './testDir/subDir' is successfully created recursively in current directory.
The temporary directory is created successfully in directory './testDir'.
The directory './testDir/subDir' is moved successfully to the temporary directory and renamed 'subDir_new'.
The directory 'subDir_new' is copied successfully to directory './testDir' and renamed 'subDir'.
File 示例
File 常规操作:创建、删除、读写、关闭
代码如下:
import std.fs.*
import std.io.*
main() {
let filePath: Path = Path("./tempFile.txt")
if (exists(filePath)) {
remove(filePath)
}
/* 在当前目录以 只写模式 创建新文件 'tempFile.txt',写入三遍 "123456789\n" 并关闭文件 */
var file: File = File(filePath, Write)
if (exists(filePath)) {
println("The file 'tempFile.txt' is created successfully in current directory.\n")
}
let bytes: Array<Byte> = "123456789\n".toArray()
for (_ in 0..3) {
file.write(bytes)
}
file.close()
/* 以 追加模式 打开文件 './tempFile.txt',写入 "abcdefghi\n" 并关闭文件 */
file = File(filePath, Append)
file.write("abcdefghi\n".toArray())
file.close()
/* 以 只读模式 打开文件 './tempFile.txt',按要求读出数据并关闭文件 */
file = File(filePath, Read)
let bytesBuf: Array<Byte> = Array<Byte>(10, repeat: 0)
// 从文件头开始的第 10 个字节后开始读出 10 个字节的数据
file.seek(SeekPosition.Begin(10))
file.read(bytesBuf)
println("Data of the 10th byte after the 10th byte: ${String.fromUtf8(bytesBuf)}")
// 读出文件尾的 10 个字节的数据
file.seek(SeekPosition.End(-10))
file.read(bytesBuf)
println("Data of the last 10 bytes: ${String.fromUtf8(bytesBuf)}")
file.close()
/* 以 读+写模式 打开文件 './tempFile.txt',按要求进行操作后关闭文件 */
file = File(filePath, ReadWrite)
// 截断文件大小为 0
file.setLength(0)
// 向文件中写入新内容
file.write("The file was truncated to an empty file!".toArray())
// 重置游标到文件头
file.seek(SeekPosition.Begin(0))
// 读取文件内容
let allBytes: Array<Byte> = readToEnd(file)
// 关闭文件
file.close()
println("Data written newly: ${String.fromUtf8(allBytes)}")
remove(filePath)
return 0
}
运行结果:
The file 'tempFile.txt' is created successfully in current directory.
Data of the 10th byte after the 10th byte: 123456789
Data of the last 10 bytes: abcdefghi
Data written newly: The file was truncated to an empty file!
File 的一些 static 函数演示
代码如下:
import std.fs.*
main() {
let filePath: Path = Path("./tempFile.txt")
if (exists(filePath)) {
remove(filePath)
}
/* 以 只写模式 创建文件,并写入 "123456789\n" 并关闭文件 */
var file: File = File.create(filePath)
file.write("123456789\n".toArray())
file.close()
/* 以 追加模式 写入 "abcdefghi\n" 到文件 */
File.appendTo(filePath, "abcdefghi".toArray())
/* 直接读取文件中所有数据 */
let allBytes: Array<Byte> = File.readFrom(filePath)
println(String.fromUtf8(allBytes))
remove(filePath)
return 0
}
运行结果:
123456789
abcdefghi
FileInfo 示例
FileInfo 一些基础操作演示
代码如下:
import std.fs.*
import std.time.DateTime
main() {
// 在当前目录下创建一个临时文件,以便下面 FileInfo 的演示
let curDirPath: Path = canonicalize(Path("./"))
let file: File = File.createTemp(curDirPath)
file.write("123456789\n".toArray())
let fileInfo: FileInfo = file.info
file.close()
/* 获得这个文件父级目录的 FileInfo,这个文件的父目录是当前目录 */
let parentDirectory: Option<FileInfo> = fileInfo.parentDirectory
checkResult(parentDirectory == Some(FileInfo(curDirPath)), "The 'parentFileInfo' is obtained successfully.")
/* 获得这个文件的路径 */
/*
let filePath: Path = fileInfo.path
*/
/* 获取这个文件的创建时间、最后访问时间、最后修改时间 */
/*
let creationTime: DateTime = fileInfo.creationTime
let lastAccessTime: DateTime = fileInfo.lastAccessTime
let lastModificationTime: DateTime = fileInfo.lastModificationTime
*/
/*
* 获取这个文件的 length
* 如果是文件代表这个文件占用磁盘空间的大小
* 如果是目录代表这个目录的所有文件占用磁盘空间的大小(不包含子目录)
*/
/*
let length: Int64 = fileInfo.size
*/
/* 判断这个文件是否是软链接、普通文件、目录 */
checkResult(fileInfo.isSymbolicLink(), "The file is a symbolic link.")
checkResult(fileInfo.isRegular(), "The file is a regular file.")
checkResult(fileInfo.isDirectory(), "The file is a directory.")
/* 判断这个文件对于当前用户是否是只读、隐藏、可执行、可读、可写 */
checkResult(fileInfo.isReadOnly(), "This file is read-only.")
checkResult(fileInfo.isHidden(), "The file is hidden.")
checkResult(fileInfo.canExecute(), "The file is executable.")
checkResult(fileInfo.canRead(), "The file is readable.")
checkResult(fileInfo.canWrite(), "The file is writable.")
/* 修改当前用户对这个文件的权限,这里设置为对当前用户只读 */
checkResult(fileInfo.setExecutable(false), "The file was successfully set to executable.")
checkResult(fileInfo.setReadable(true), "The file was successfully set to readable.")
checkResult(fileInfo.setWritable(false), "The file was successfully set to writable.")
checkResult(fileInfo.isReadOnly(), "This file is now read-only.")
return 0
}
func checkResult(result: Bool, message: String): Unit {
if (result) {
println(message)
}
}
运行结果:
The 'parentFileInfo' is obtained successfully.
The file is a regular file.
The file is readable.
The file is writable.
The file was successfully set to executable.
The file was successfully set to readable.
The file was successfully set to writable.
This file is now read-only.
Path 示例
不同 Path 实例的属性信息展示
打印 Path 实例的目录部分、文件全名(有扩展名)、扩展名、文件名(无扩展名),并判断 Path 实例是绝对路径还是相对路径
代码如下:
import std.fs.Path
main() {
let pathStrArr: Array<String> = [
// 绝对路径
"/a/b/c",
"/a/b/",
"/a/b/c.cj",
"/a",
"/",
// 相对路径
"./a/b/c",
"./a/b/",
"./a/b/c.cj",
"./",
".",
"123."
]
for (i in 0..pathStrArr.size) {
let path: Path = Path(pathStrArr[i])
// 打印 path 的整个路径字符串
println("Path${i}: ${path.toString()}")
// 打印 path 的目录路径
println("Path.parent: ${path.parent}")
// 打印 path 的文件全名(有扩展名)
println("Path.fileName: ${path.fileName}")
// 打印 path 的扩展名
println("Path.extensionName: ${path.extensionName}")
// 打印 path 的文件名(无扩展名)
println("Path.fileNameWithoutExtension: ${path.fileNameWithoutExtension}")
// 打印 path 是否是绝对路径、相对路径
println("Path.isAbsolute: ${path.isAbsolute()}; Path.isRelative: ${path.isRelative()}")
println()
}
return 0
}
运行结果:
Path0: /a/b/c
Path.parent: /a/b
Path.fileName: c
Path.extensionName:
Path.fileNameWithoutExtension: c
Path.isAbsolute: true; Path.isRelative: false
Path1: /a/b/
Path.parent: /a
Path.fileName: b
Path.extensionName:
Path.fileNameWithoutExtension: b
Path.isAbsolute: true; Path.isRelative: false
Path2: /a/b/c.cj
Path.parent: /a/b
Path.fileName: c.cj
Path.extensionName: cj
Path.fileNameWithoutExtension: c
Path.isAbsolute: true; Path.isRelative: false
Path3: /a
Path.parent: /
Path.fileName: a
Path.extensionName:
Path.fileNameWithoutExtension: a
Path.isAbsolute: true; Path.isRelative: false
Path4: /
Path.parent: /
Path.fileName:
Path.extensionName:
Path.fileNameWithoutExtension:
Path.isAbsolute: true; Path.isRelative: false
Path5: ./a/b/c
Path.parent: ./a/b
Path.fileName: c
Path.extensionName:
Path.fileNameWithoutExtension: c
Path.isAbsolute: false; Path.isRelative: true
Path6: ./a/b/
Path.parent: ./a
Path.fileName: b
Path.extensionName:
Path.fileNameWithoutExtension: b
Path.isAbsolute: false; Path.isRelative: true
Path7: ./a/b/c.cj
Path.parent: ./a/b
Path.fileName: c.cj
Path.extensionName: cj
Path.fileNameWithoutExtension: c
Path.isAbsolute: false; Path.isRelative: true
Path8: ./
Path.parent:
Path.fileName: .
Path.extensionName:
Path.fileNameWithoutExtension:
Path.isAbsolute: false; Path.isRelative: true
Path9: .
Path.parent:
Path.fileName: .
Path.extensionName:
Path.fileNameWithoutExtension:
Path.isAbsolute: false; Path.isRelative: true
Path10: 123.
Path.parent:
Path.fileName: 123.
Path.extensionName:
Path.fileNameWithoutExtension: 123
Path.isAbsolute: false; Path.isRelative: true
Path 的拼接、判等、转规范化路径等操作
代码如下:
import std.fs.*
main() {
let dirPath: Path = Path("./a/b/c")
if (!exists(dirPath)) {
Directory.create(dirPath, recursive: true)
}
let filePath: Path = dirPath.join("d.cj") // ./a/b/c/d.cj
if (filePath == Path("./a/b/c/d.cj")) {
println("filePath.join: success")
}
if (!exists(filePath)) {
File.create(filePath).close()
}
let curCanonicalizedPath: Path = canonicalize(Path("."))
let fileCanonicalizedPath: Path = canonicalize(Path("././././a/./../a/b/../../a/b/c/.././../../a/b/c/d.cj"))
if (fileCanonicalizedPath == canonicalize(filePath) &&
fileCanonicalizedPath.toString() == curCanonicalizedPath.toString() + "/a/b/c/d.cj") {
println("canonicalize filePath: success")
}
remove(dirPath, recursive: true)
return 0
}
运行结果:
filePath.join: success
canonicalize filePath: success
通过 Path 创建文件和目录
代码如下:
import std.fs.*
main() {
let curPath: Path = Path("./")
let dirPath: Path = curPath.join("tempDir")
let filePath: Path = dirPath.join("tempFile.txt")
if (exists(dirPath)) {
remove(dirPath, recursive: true)
}
Directory.create(dirPath)
if (exists(dirPath)) {
println("Directory 'tempDir' is created successfully.")
}
File.create(filePath).close()
if (exists(filePath)) {
println("File 'tempFile.txt' is created successfully in directory 'tempDir'.")
}
remove(dirPath, recursive: true)
return 0
}
运行结果:
Directory 'tempDir' is created successfully.
File 'tempFile.txt' is created successfully in directory 'tempDir'.
std.io
功能介绍
io 包提供程序与外部设备进行数据交换的能力。
I/O 操作是指程序与外部设备进行数据交换的操作。仓颉提供了流式 I/O 操作的通用接口和一些特殊实现。输入输出流类似一个数据通道,承载一段有序数据,程序从输入流读取数据(来自文件、网络等),往输出流(通往文件、网络等)写入数据。
API 列表
函数
| 函数名 | 功能 |
|---|---|
| copy(InputStream, OutputStream) | 将一个输入流中未被读取的数据拷贝到另一个输出流中。 |
| readString<T>(T) where T <: InputStream & Seekable | 读取入参中的所有剩余内容,并返回一个字符串。 |
| readStringUnchecked<T>(T) where T <: InputStream & Seekable | 读取入参中的所有剩余内容,并返回一个字符串。该函数不会检查字符串的合法性。 |
| func readToEnd<T>(T) where T <: InputStream & Seekable | 获取入参中未被读取的数据。 |
接口
| 接口名 | 功能 |
|---|---|
| InputStream | 输入流接口。 |
| IOStream | 输入输出流接口。 |
| OutputStream | 输出流接口。 |
| Seekable | 移动光标接口。 |
类
| 类名 | 功能 |
|---|---|
| BufferedInputStream<T> where T <: InputStream | 提供带缓冲区的输入流。 |
| BufferedOutputStream<T> where T <: OutputStream | 提供带缓冲区的输出流。 |
| ByteBuffer | 输入流接口。 |
| ChainedInputStream<T> where T <: InputStream | 提供顺序从 InputStream 数组中读取数据的能力。 |
| MultiOutputStream<T> where T <: OutputStream | 提供将数据同时写入到 OutputStream 数组中每个输出流中的能力。 |
| StringReader<T> where T <: InputStream | 提供从 InputStream 输入流中读出数据并转换成字符或字符串的能力。 |
| StringWriter<T> where T <: OutputStream | 提供将 String 以及一些 ToString 类型转换成指定编码格式和字节序配置的字符串并写入到输出流的能力。 |
枚举
| 枚举名 | 功能 |
|---|---|
| SeekPosition | 输入流接口。 |
异常类
| 异常类名 | 功能 |
|---|---|
| ContentFormatException | 提供字符格式相关的异常处理。 |
| IOException | 提供 IO 流相关的异常处理。 |
函数
func copy(InputStream, OutputStream)
public func copy(from: InputStream, to!: OutputStream): Int64
功能:将一个输入流中未被读取的数据拷贝到另一个输出流中。
参数:
- from: InputStream - 待读取数据的输入流。
- to!: OutputStream - 数据将要拷贝到的输出流。
返回值:
- Int64 - 拷贝数据的字节数。
示例:
import std.io.ByteBuffer
import std.io.copy
main(): Unit {
let sourceStream = ByteBuffer()
let targetStream = ByteBuffer()
/* 向源输入流写入数据 */
let sourceData = "Hello, World!".toArray()
sourceStream.write(sourceData)
/* 使用 copy 函数将源输入流的数据拷贝到目标输出流 */
let copiedBytes = copy(sourceStream, to: targetStream)
println("Copied ${copiedBytes} bytes.")
/* 读取目标输出流中的数据 */
let targetData: Array<Byte> = Array<Byte>(sourceData.size, repeat: 0)
targetStream.read(targetData)
println("Data copied to target stream: ${String.fromUtf8(targetData)}")
}
运行结果:
Copied 13 bytes.
Data copied to target stream: Hello, World!
func readString<T>(T) where T <: InputStream & Seekable
public func readString<T>(from: T): String where T <: InputStream & Seekable
功能:读取入参中的所有剩余内容,并返回一个字符串。
参数:
- from: T - 要读取数据的对象。
返回值:
- String - 读取到的结果字符串。
异常:
- ContentFormatException - 当剩余字节不符合 UTF-8 编码规则时,抛出异常。 示例:
import std.io.ByteBuffer
import std.io.readString
import std.io.ContentFormatException
main(): Unit {
let inputStream = ByteBuffer()
/* 向输入流写入数据 */
let sourceData = "Hello, World!".toArray()
inputStream.write(sourceData)
/* 使用 readString 函数读取输入流中的所有剩余内容 */
try {
let result = readString(inputStream)
println("Read string: ${result}")
} catch (e: ContentFormatException) {
println("Error: ${e.message}")
}
/* 向输入流写入一个不合法的 UTF-8 字符串 */
let sourceDataError: Array<UInt8> = [0xC3, 0x28, 0x48, 0x65, 0x6C, 0x6C, 0x6F]
inputStream.write(sourceDataError)
/* 使用 readString 函数读取输入流中的所有剩余内容 */
try {
let result = readString(inputStream)
println("Read string: ${result}")
} catch (e: ContentFormatException) {
println("Error: ${e.message}")
}
}
运行结果:
Read string: Hello, World!
Error: Invalid unicode scalar value.
func readStringUnchecked<T>(T) where T <: InputStream & Seekable
public unsafe func readStringUnchecked<T>(from: T): String where T <: InputStream & Seekable
功能:读取入参中的所有剩余内容,并返回一个字符串。该函数不会检查字符串的合法性。
参数:
- from: T - 要读取数据的对象。
返回值:
- String - 读取到的结果字符串。
示例:
import std.io.ByteBuffer
import std.io.readStringUnchecked
import std.io.ContentFormatException
main(): Unit {
let inputStream = ByteBuffer()
/* 向输入流写入数据 */
let sourceData = "Hello, World!".toArray()
inputStream.write(sourceData)
/* 使用 readString 函数读取输入流中的所有剩余内容,可以正常输出:Read string: Hello, World! */
unsafe {
let result = readStringUnchecked(inputStream)
println("Read string: ${result}")
}
/* 向输入流写入一个不合法的 UTF-8 字符串 */
let sourceDataError: Array<UInt8> = [0xC3, 0x28, 0x48, 0x65, 0x6C, 0x6C, 0x6F]
inputStream.write(sourceDataError)
/* 使用 readString 函数读取输入流中的所有剩余内容,由于 inputStream 的第一位是不合法的UTF-8字符,所以将产生不可期的输出字符 */
unsafe {
let result = readStringUnchecked(inputStream)
println("Read string: ${result}")
}
}
func readToEnd<T>(T) where T <: InputStream & Seekable
public func readToEnd<T>(from: T): Array<Byte> where T <: InputStream & Seekable
功能:获取入参中未被读取的数据。
参数:
- from: T - 要读取数据的对象。
返回值:
示例:
import std.io.ByteBuffer
import std.io.readToEnd
main(): Unit {
let inputStream = ByteBuffer()
/* 向输入流写入数据 */
let sourceData = "Hello, World!".toArray()
inputStream.write(sourceData)
/* 使用 readToEnd 函数读取输入流中的所有剩余内容 */
let data = readToEnd(inputStream)
println("${String.fromUtf8(data)}")
}
运行结果:
Hello, World!
接口
interface IOStream
public interface IOStream <: InputStream & OutputStream {}
功能:输入输出流接口。
父类型:
interface InputStream
public interface InputStream {
func read(buffer: Array<Byte>): Int64
}
功能:输入流接口。
func read(Array<Byte>)
func read(buffer: Array<Byte>): Int64
功能:从输入流中读取数据放到 buffer 中。
参数:
返回值:
- Int64 - 读取的数据的字节数。
interface OutputStream
public interface OutputStream {
func write(buffer: Array<Byte>): Unit
func flush(): Unit
}
功能:输出流接口。
func flush()
func flush(): Unit
功能:清空缓存区。该函数提供默认实现,默认实现为空。
func write(Array<Byte>)
func write(buffer: Array<Byte>): Unit
功能:将 buffer 中的数据写入到输出流中。
参数:
interface Seekable
public interface Seekable {
prop length: Int64
prop position: Int64
prop remainLength: Int64
func seek(sp: SeekPosition): Int64
}
功能:移动光标接口。
prop length
prop length: Int64
功能:返回当前流中的总数据量。
类型:Int64
prop position
prop position: Int64
功能:返回当前光标位置。
类型:Int64
prop remainLength
prop remainLength: Int64
功能:返回当前流中未读的数据量。
类型:Int64
func seek(SeekPosition)
func seek(sp: SeekPosition): Int64
功能:移动光标到指定的位置。
参数:
- sp: SeekPosition - 指定光标移动后的位置。
返回值:
- Int64 - 返回流中数据的起点到移动后位置的偏移量(以字节为单位)。
类
class BufferedInputStream<T> where T <: InputStream
public class BufferedInputStream<T> <: InputStream where T <: InputStream {
public init(input: T)
public init(input: T, buffer: Array<Byte>)
public init(input: T, capacity: Int64)
}
功能:提供带缓冲区的输入流。
可将其他 InputStream 类型的输入流(如 ByteBuffer)绑定到 BufferedInputStream 实例,从该实例读取数据时,先把数据从被绑定的流读入缓冲区暂存,再从缓冲区读取用户需要的数据。
父类型:
init(T)
public init(input: T)
功能:创建 BufferedInputStream 实例,缓冲区容量取默认值 4096。
参数:
- input: T - 绑定指定输入流。
示例:
import std.io.ByteBuffer
import std.io.BufferedInputStream
main(): Unit {
let inputData = "Hello World".toArray()
let inputStream = ByteBuffer(inputData)
/* 绑定指定输入流 */
let bufferedStream = BufferedInputStream(inputStream)
/* 从输入流中读取数据 */
let data = Array<Byte>(inputData.size, repeat: 0)
bufferedStream.read(data)
println(String.fromUtf8(data))
}
运行结果:
Hello World
init(T, Array<Byte>)
public init(input: T, buffer: Array<Byte>)
功能:创建 BufferedInputStream 实例。
其内部使用的缓存区由入参决定,在注重性能的场景下,通过复用传入的 buffer,可以减少内存分配次数,提高性能。
参数:
- input: T - 绑定一个输入流。
- buffer: Array<Byte> - BufferedInputStream 使用的内部缓存区。
异常:
- IllegalArgumentException - 当 buffer 大小等于 0 时,抛出异常。
示例:
import std.io.ByteBuffer
import std.io.BufferedInputStream
main(): Unit {
let inputStream = ByteBuffer()
/* 使用合法的内部缓冲区创建 BufferedInputStream 实例,不会抛出异常 */
try {
let buffer = Array<Byte>(1024, repeat: 0)
let bufferedStream = BufferedInputStream(inputStream, buffer)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
/* 内部缓冲区大小被定义为0的情况 */
try {
let invalidBuffer = Array<Byte>()
let bufferedStream = BufferedInputStream(inputStream, invalidBuffer)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
}
运行结果:
Error: The buffer cannot be empty.
init(T, Int64)
public init(input: T, capacity: Int64)
功能:创建 BufferedInputStream 实例。
参数:
- input: T - 绑定指定输入流。
- capacity: Int64 - 内部缓冲区容量。
异常:
- IllegalArgumentException - 当 capacity 小于等于 0 时,抛出异常。
func read(Array<Byte>)
public func read(buffer: Array<Byte>): Int64
功能:从绑定的输入流读出数据到 buffer 中。
参数:
返回值:
- Int64 - 读取数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 为空时,抛出异常。
示例:
import std.io.ByteBuffer
import std.io.BufferedInputStream
main(): Unit {
let inputStream = ByteBuffer()
/* 使用合法的内部缓冲区容量创建 BufferedInputStream 实例,不会抛出异常 */
try {
let capacity = 2048
let bufferedStream = BufferedInputStream(inputStream, capacity)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
/* 当内部缓冲区被设置成 0 时,抛出异常 */
try {
let zeroCapacity = 0
let bufferedStream = BufferedInputStream(inputStream, zeroCapacity)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
/* 当内部缓冲区被设置成负数时,抛出异常 */
try {
let negativeCapacity = -1024
let bufferedStream = BufferedInputStream(inputStream, negativeCapacity)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
}
运行结果:
Error: Invalid capacity size: capacity = 0.
Error: Invalid capacity size: capacity = -1024.
func readByte()
public func readByte(): ?Byte
功能:从输入流中读取一个字节。
返回值:
- ?Byte - 读取到的数据。读取失败时会返回
None。
示例:
import std.io.ByteBuffer
import std.io.BufferedInputStream
main(): Unit {
/* 创建输入流并写入数据 */
let inputStream = ByteBuffer()
let sourceData = "abc".toArray()
inputStream.write(sourceData)
let bufferedStream = BufferedInputStream(inputStream)
/* 依次读取所有字节 */
while (true) {
let byte = bufferedStream.readByte()
if (byte == None) {
break
}
println(String.fromUtf8(byte.getOrThrow()))
}
}
运行结果:
a
b
c
func reset(T)
public func reset(input: T): Unit
功能:绑定新的输入流,重置状态,但不重置 capacity。
参数:
- input: T - 待绑定的输入流。
示例:
import std.io.ByteBuffer
import std.io.BufferedInputStream
import std.io.IOException
main(): Unit {
/* 创建第一个输入流并写入数据 */
let inputStream1 = ByteBuffer()
let sourceData1 = "First message: Hello".toArray()
inputStream1.write(sourceData1)
/* 创建第二个输入流并写入数据 */
let inputStream2 = ByteBuffer()
let sourceData2 = "Second message: World".toArray()
inputStream2.write(sourceData2)
/* 使用 BufferedInputStream 包装第一个输入流 */
let bufferedStream = BufferedInputStream(inputStream1)
/* 读取第一个输入流的部分数据 */
var result1 = ""
for (_ in 0..sourceData1.size) {
let byte = bufferedStream.readByte()
if (byte == None) {
break
}
result1 += String.fromUtf8(byte.getOrThrow())
}
println(result1)
/* 重置输入流为第二个输入流 */
bufferedStream.reset(inputStream2)
var result2 = ""
for (_ in 0..sourceData2.size) {
let byte = bufferedStream.readByte()
if (byte == None) {
break
}
result2 += String.fromUtf8(byte.getOrThrow())
}
println(result2)
}
运行结果:
First message: Hello
Second message: World
extend<T> BufferedInputStream<T> <: Resource where T <: Resource
extend<T> BufferedInputStream<T> <: Resource where T <: Resource
功能:为 BufferedInputStream 实现 Resource 接口,该类型对象可在 try-with-resource 语法上下文中实现自动资源释放。
父类型:
func close()
public func close(): Unit
功能:关闭当前流。
注意:
- 调用此方法后不可再调用 BufferedInputStream 的其他接口,否则会造成不可期现象。
func isClosed()
public func isClosed(): Bool
功能:判断当前流是否关闭。
返回值:
- Bool - 如果当前流已经被关闭,返回 true,否则返回 false。
示例:
import std.io.BufferedInputStream
import std.io.InputStream
import std.io.ByteBuffer
/**
* 自定义实现 InputStream 和 Resource 接口的类A
*/
public class A <: InputStream & Resource {
private var closed: Bool = false
public func read(buffer: Array<Byte>): Int64 {
let inputData = "Hello World".toArray()
let inputStream = ByteBuffer(inputData)
let num = inputStream.read(buffer)
return num
}
public func isClosed(): Bool {
return closed
}
public func close(): Unit {
println("Resource is closed")
closed = true
}
}
main(): Unit {
let bufferedStream = BufferedInputStream(A())
/* 使用try-with-resource语法获取资源 */
try (r = bufferedStream) {
println("Get the resource")
let data = Array<Byte>(11, repeat: 0)
r.read(data)
println(r.isClosed())
println(String.fromUtf8(data))
}
/* 自动调用 close() 函数释放资源 */
println(bufferedStream.isClosed())
}
运行结果:
Get the resource
false
Hello World
Resource is closed
true
extend<T> BufferedInputStream<T> <: Seekable where T <: Seekable
extend<T> BufferedInputStream<T> <: Seekable where T <: Seekable
功能:为 BufferedInputStream 实现 Seekable 接口,支持查询数据长度,移动光标等操作。
父类型:
prop length
public prop length: Int64
功能:返回当前流中的总数据量。
类型:Int64
prop position
public prop position: Int64
功能:返回当前光标位置。
类型:Int64
prop remainLength
public prop remainLength: Int64
功能:返回当前流中未读的数据量。
类型:Int64
func seek(SeekPosition)
public func seek(sp: SeekPosition): Int64
功能:移动光标到指定的位置。
说明:
- 指定的位置不能位于流中数据头部之前。
- 指定位置可以超过流中数据末尾。
- 调用该函数会先清空缓存区,再移动光标的位置。
参数:
- sp: SeekPosition - 指定光标移动后的位置。
返回值:
- Int64 - 返回流中数据的起点到移动后位置的偏移量(以字节为单位)。
异常:
- IOException - 当指定的位置位于流中数据头部之前时,抛出异常。
示例:
import std.io.BufferedInputStream
import std.io.InputStream
import std.io.ByteBuffer
import std.io.Seekable
import std.io.SeekPosition
import std.io.IOException
import std.io.readToEnd
/**
* 自定义实现 InputStream 和 Seekable 接口的类A
*/
public class A <: InputStream & Seekable {
public var inputStream: ByteBuffer = ByteBuffer()
public func read(buffer: Array<Byte>): Int64 {
let inputData = "Hello World".toArray()
inputStream = ByteBuffer(inputData)
let num = inputStream.read(buffer)
return num
}
public func seek(sp: SeekPosition): Int64 {
return inputStream.seek(sp)
}
}
main(): Unit {
let seekableStream = A()
let bufferedStream = BufferedInputStream(seekableStream)
let buffer = Array<Byte>(11, repeat: 0)
bufferedStream.read(buffer)
/* 输出当前流中总数据量,当前光标位置,当前流中未读的数据量 */
println("Length : " + bufferedStream.length.toString())
println("Position : " + bufferedStream.position.toString())
println("Remain Length : " + bufferedStream.remainLength.toString())
/* 移动光标到指定位置,虽然超过了流中数据末尾但是合法的 */
println("Position after seek() : " + bufferedStream.seek(SeekPosition.Current(11)).toString())
/* 尝试移动到数据头部之前,抛出异常 */
try {
bufferedStream.seek(SeekPosition.Begin(-1))
} catch (e: IOException) {
println("Error: " + e.message)
}
/* 将光标移动到第一个单词之后,读取后续的数据 */
bufferedStream.seek(SeekPosition.Begin(6))
println(String.fromUtf8(readToEnd(seekableStream.inputStream)))
}
运行结果:
Length : 11
Position : 11
Remain Length : 0
Position after seek() : 22
Error: Can't move the position before the beginning of the stream.
World
class BufferedOutputStream<T> where T <: OutputStream
public class BufferedOutputStream<T> <: OutputStream where T <: OutputStream {
public init(output: T)
public init(output: T, buffer: Array<Byte>)
public init(output: T, capacity: Int64)
}
功能:提供带缓冲区的输出流。
可将其他 OutputStream 类型的输入流(如 ByteBuffer)绑定到 BufferedOutputStream 实例,从该实例写入数据时,先把数据写入缓冲区暂存,再从缓冲区写入数据到流中。
父类型:
init(T)
public init(output: T)
功能:创建 BufferedOutputStream 实例,缓冲区容量取默认值 4096。
参数:
- output: T - 绑定指定输出流。
示例:
import std.io.ByteBuffer
import std.io.BufferedOutputStream
import std.io.readToEnd
main(): Unit {
let outputStream = ByteBuffer()
/* 绑定指定输出流 */
let bufferedStream = BufferedOutputStream(outputStream)
/* 将输出数据写入缓冲流 bufferedStream 并刷新内部绑定的输出流 outputStream */
let outputData = "Hello World".toArray()
bufferedStream.write(outputData)
bufferedStream.flush()
println(String.fromUtf8(readToEnd(outputStream)))
}
运行结果:
Hello World
init(T, Array<Byte>)
public init(output: T, buffer: Array<Byte>)
功能:创建 BufferedOutputStream 实例。
其内部使用的缓存区由入参决定,在注重性能的场景下,通过复用传入的 buffer,可以减少内存分配次数,提高性能。
参数:
- output: T - 绑定一个输出流。
- buffer: Array<Byte> - BufferedOutputStream 使用的内部缓存区。
异常:
- IllegalArgumentException - 当 buffer 大小等于 0 时,抛出异常。
示例:
import std.io.ByteBuffer
import std.io.BufferedOutputStream
main(): Unit {
let outputStream = ByteBuffer()
/* 使用合法的内部缓冲区创建 BufferedOutputStream 实例,不会抛出异常 */
try {
let buffer = Array<Byte>(1024, repeat: 0)
let bufferedStream = BufferedOutputStream(outputStream, buffer)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
/* 内部缓冲区大小被定义为0的情况 */
try {
let invalidBuffer = Array<Byte>()
let bufferedStream = BufferedOutputStream(outputStream, invalidBuffer)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
}
运行结果:
Error: The buffer cannot be empty.
init(T, Int64)
public init(output: T, capacity: Int64)
功能:创建 BufferedOutputStream 实例。
参数:
- output: T - 绑定指定输出流。
- capacity: Int64 - 内部缓冲区容量。
异常:
- IllegalArgumentException - 当 capacity 小于等于 0 时,抛出异常。
示例:
import std.io.ByteBuffer
import std.io.BufferedOutputStream
main(): Unit {
let outputStream = ByteBuffer()
/* 使用合法的内部缓冲区容量创建 BufferedoutputStream 实例,不会抛出异常 */
try {
let capacity = 2048
let bufferedStream = BufferedOutputStream(outputStream, capacity)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
/* 当内部缓冲区被设置成 0 时,抛出异常 */
try {
let zeroCapacity = 0
let bufferedStream = BufferedOutputStream(outputStream, zeroCapacity)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
/* 当内部缓冲区被设置成负数时,抛出异常 */
try {
let negativeCapacity = -1024
let bufferedStream = BufferedOutputStream(outputStream, negativeCapacity)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
}
运行结果:
Error: Invalid capacity size: capacity = 0.
Error: Invalid capacity size: capacity = -1024.
func flush()
public func flush(): Unit
功能:刷新 BufferedOutputStream:将内部缓冲区的剩余数据写入绑定的输出流,并刷新 BufferedOutputStream。
示例:
import std.io.ByteBuffer
import std.io.BufferedOutputStream
import std.io.readToEnd
main(): Unit {
let outputStream = ByteBuffer()
/* 绑定指定输出流 */
let bufferedStream = BufferedOutputStream(outputStream)
/* 将输出数据写入缓冲流 bufferedStream 并刷新内部绑定的输出流 outputStream */
let outputData = "Hello World".toArray()
bufferedStream.write(outputData)
bufferedStream.flush()
println(String.fromUtf8(readToEnd(outputStream)))
}
运行结果:
Hello World
func reset(T)
public func reset(output: T): Unit
功能:绑定新的输出流,重置状态,但不重置 capacity。
参数:
- output: T - 待绑定的输出流。
示例:
import std.io.ByteBuffer
import std.io.BufferedOutputStream
import std.io.IOException
import std.io.readToEnd
main(): Unit {
/* 创建第一个输出流 */
let outputStream1 = ByteBuffer()
let sourceData1 = "First message: Hello".toArray()
/* 创建第二个输出流 */
let outputStream2 = ByteBuffer()
let sourceData2 = "Second message: World".toArray()
/* 使用 BufferedOutputStream 包装第一个输出流 */
let bufferedStream = BufferedOutputStream(outputStream1)
/* 将第一个源数据写入到绑定的第一个输出流中并刷新 */
bufferedStream.write(sourceData1)
bufferedStream.flush()
println(String.fromUtf8(readToEnd(outputStream1)))
/* 重置输出流为第二个输出流,将第二个源数据写入到绑定的第二个输出流中并刷新 */
bufferedStream.reset(outputStream2)
bufferedStream.write(sourceData2)
bufferedStream.flush()
println(String.fromUtf8(readToEnd(outputStream2)))
}
运行结果:
First message: Hello
Second message: World
func write(Array<Byte>)
public func write(buffer: Array<Byte>): Unit
功能:将 buffer 中的数据写入到绑定的输出流中。
参数:
示例:
import std.io.ByteBuffer
import std.io.BufferedOutputStream
import std.io.readToEnd
main(): Unit {
let outputStream = ByteBuffer()
/* 绑定指定输出流 */
let bufferedStream = BufferedOutputStream(outputStream)
/* 将输出数据写入缓冲流 bufferedStream 并刷新内部绑定的输出流 outputStream */
let outputData = "Hello World".toArray()
bufferedStream.write(outputData)
bufferedStream.flush()
println(String.fromUtf8(readToEnd(outputStream)))
}
运行结果:
Hello World
func writeByte(Byte)
public func writeByte(v: Byte): Unit
功能:写入一个字节到绑定的输出流中。
参数:
- v: Byte - 待写入的字节。
示例:
import std.io.ByteBuffer
import std.io.BufferedOutputStream
import std.io.readToEnd
main(): Unit {
let outputStream = ByteBuffer()
/* 绑定指定输出流 */
let bufferedStream = BufferedOutputStream(outputStream)
/* 将输出数据逐个写入缓冲流 bufferedStream 并刷新内部绑定的输出流 outputStream */
let outputData = "Hello World".toArray()
for (byte in outputData){
bufferedStream.writeByte(byte)
}
bufferedStream.flush()
println(String.fromUtf8(readToEnd(outputStream)))
}
运行结果:
Hello World
extend<T> BufferedOutputStream<T> <: Resource where T <: Resource
extend<T> BufferedOutputStream<T> <: Resource where T <: Resource
功能:为 BufferedOutputStream 实现 Resource 接口,该类型对象可在 try-with-resource 语法上下文中实现自动资源释放。
父类型:
func close()
public func close(): Unit
功能:关闭当前流。
注意:
- 调用此方法后不可再调用 BufferedOutputStream 的其他接口,否则会造成不可期现象。
func isClosed()
public func isClosed(): Bool
功能:判断当前流是否关闭。
返回值:
- Bool - 如果当前流已经被关闭,返回 true,否则返回 false。
示例:
import std.io.BufferedOutputStream
import std.io.OutputStream
import std.io.ByteBuffer
import std.io.readToEnd
/**
* 自定义实现 OutputStream 和 Resource 接口的类A
*/
public class A <: OutputStream & Resource {
private var closed: Bool = false
public var outputStream = ByteBuffer()
public func write(buffer: Array<Byte>): Unit {
this.outputStream = ByteBuffer(buffer)
}
public func isClosed(): Bool {
return closed
}
public func close(): Unit {
println("Resource is closed")
closed = true
}
}
main(): Unit {
let resourceStream = A()
let bufferedStream = BufferedOutputStream(resourceStream)
/* 使用try-with-resource语法获取资源 */
try (r = bufferedStream) {
println("Get the resource")
let data = "Hello World".toArray()
r.write(data)
r.flush()
println(r.isClosed())
println(String.fromUtf8(readToEnd(resourceStream.outputStream)))
}
/* 自动调用 close() 函数释放资源 */
println(bufferedStream.isClosed())
}
运行结果:
Get the resource
false
Hello World
Resource is closed
true
extend<T> BufferedOutputStream<T> <: Seekable where T <: Seekable
extend<T> BufferedOutputStream<T> <: Seekable where T <: Seekable
功能:为 BufferedOutputStream 实现 Seekable 接口,支持查询数据长度,移动光标等操作。
父类型:
prop length
public prop length: Int64
功能:返回当前流中的总数据量。
类型:Int64
prop position
public prop position: Int64
功能:返回当前光标位置。
类型:Int64
prop remainLength
public prop remainLength: Int64
功能:返回当前流中未读的数据量。
类型:Int64
func seek(SeekPosition)
public func seek(sp: SeekPosition): Int64
功能:移动光标到指定的位置。
说明:
- 指定的位置不能位于流中数据头部之前。
- 指定位置可以超过流中数据末尾。
- 调用该函数会先将缓存区内的数据写到绑定的输出流里,再移动光标的位置。
参数:
- sp: SeekPosition - 指定光标移动后的位置。
返回值:
- Int64 - 返回流中数据的起点到移动后位置的偏移量(以字节为单位)。
异常:
- IOException - 当指定的位置位于流中数据头部之前时,抛出异常。
示例:
import std.io.BufferedOutputStream
import std.io.OutputStream
import std.io.ByteBuffer
import std.io.Seekable
import std.io.SeekPosition
import std.io.IOException
import std.io.readToEnd
/**
* 自定义实现 OutputStream 和 Seekable 接口的类A
*/
public class A <: OutputStream & Seekable {
public var outputStream: ByteBuffer = ByteBuffer()
public func write(buffer: Array<Byte>): Unit {
this.outputStream = ByteBuffer(buffer)
}
public func seek(sp: SeekPosition): Int64 {
return outputStream.seek(sp)
}
}
main(): Unit {
let seekableStream = A()
let bufferedStream = BufferedOutputStream(seekableStream)
let data = "Hello World".toArray()
bufferedStream.write(data)
bufferedStream.flush()
/* 输出当前流中总数据量,当前光标位置,当前流中未读的数据量 */
println("Length : " + bufferedStream.length.toString())
println("Position : " + bufferedStream.position.toString())
println("Remain Length : " + bufferedStream.remainLength.toString())
/* 移动光标到指定位置,虽然超过了流中数据末尾但是合法的 */
println("Position after seek() : " + bufferedStream.seek(SeekPosition.Current(11)).toString())
/* 尝试移动到数据头部之前,抛出异常 */
try {
bufferedStream.seek(SeekPosition.Begin(-1))
} catch (e: IOException) {
println("Error: " + e.message)
}
/* 将光标移动到第一个单词之后,读取后续的数据 */
bufferedStream.seek(SeekPosition.Begin(6))
println(String.fromUtf8(readToEnd(seekableStream.outputStream)))
}
运行结果:
Length : 11
Position : 0
Remain Length : 11
Position after seek() : 11
Error: Can't move the position before the beginning of the stream.
World
class ByteBuffer
public class ByteBuffer <: IOStream & Seekable {
public init()
public init(capacity: Int64)
public init(source: Array<Byte>)
}
功能:基于 Array<Byte> 数据类型,提供对字节流的写入、读取等操作。
父类型:
prop capacity
public prop capacity: Int64
功能:获取当前缓冲区容量。
返回值:
- Int64 - 当前缓冲区容量。
init()
public init()
功能:创建 ByteBuffer 实例,默认的初始容量是 32。
示例:
import std.io.ByteBuffer
main(): Unit {
let buffer = ByteBuffer()
println(buffer.capacity)
}
运行结果:
32
init(Array<Byte>)
public init(source: Array<Byte>)
功能:根据传入的数组构造 ByteBuffer 实例。
参数:
示例:
import std.io.ByteBuffer
main(): Unit {
let inputData = "Hello World".toArray()
let buffer = ByteBuffer(inputData)
println(buffer.capacity)
/* 从缓冲区中读取数据 */
println(String.fromUtf8(buffer.bytes()))
}
运行结果:
11
Hello World
init(Int64)
public init(capacity: Int64)
功能:创建 ByteBuffer 实例。
参数:
- capacity: Int64 - 指定的初始容量。
异常:
- IllegalArgumentException - 当 capacity 小于 0 时,抛出异常。
示例:
import std.io.ByteBuffer
main(): Unit {
let buffer = ByteBuffer(1024)
println(buffer.capacity)
try{
let errorBuffer = ByteBuffer(-1024)
println(errorBuffer.capacity)
}catch(e: Exception){
println("Error: ${e.message}")
}
}
运行结果:
1024
Error: The capacity must be greater than or equal to 0: -1024.
func bytes()
public func bytes(): Array<Byte>
功能:获取当前 ByteBuffer 中未被读取的数据的切片。
注意:
- 缓冲区进行读取,写入或重置等修改操作会导致这个切片失效。
- 对切片的修改会影响缓冲区的内容。
返回值:
示例:
import std.io.ByteBuffer
main(): Unit {
let inputData = "Hello World".toArray()
let buffer = ByteBuffer(inputData)
/* 从缓冲区中读取数据 */
println(String.fromUtf8(buffer.bytes()))
}
运行结果:
Hello World
func clear()
public func clear(): Unit
功能:清除当前 ByteBuffer 中所有数据。
示例:
import std.io.ByteBuffer
main(): Unit {
let inputData = "Hello World".toArray()
let buffer = ByteBuffer(inputData)
println(buffer.capacity)
/* 读取原始数据 */
println(String.fromUtf8(buffer.bytes()))
/* 清除缓冲区 */
buffer.clear()
/* 读取清除后的缓冲区 */
println("buffer after clear: " + String.fromUtf8(buffer.bytes()))
println("capacity after clear: ${buffer.capacity}")
}
运行结果:
11
Hello World
buffer after clear:
capacity after clear: 11
func clone()
public func clone(): ByteBuffer
功能:用当前 ByteBuffer 中的数据来构造一个新的 ByteBuffer。
返回值:
- ByteBuffer - 新构造的 ByteBuffer 对象。
示例:
import std.io.ByteBuffer
main(): Unit {
let inputData = "Hello World".toArray()
let originalBuffer = ByteBuffer(inputData)
/* 克隆原始缓冲区 */
let clonedBuffer = originalBuffer.clone()
println("originalBuffer: " + String.fromUtf8(originalBuffer.bytes()))
println("clonedBuffer: " + String.fromUtf8(clonedBuffer.bytes()))
/* 修改原始缓冲区的数据 */
originalBuffer.write(" New Data".toArray())
println("originalBuffer: " + String.fromUtf8(originalBuffer.bytes()))
println("clonedBuffer: " + String.fromUtf8(clonedBuffer.bytes()))
}
运行结果:
originalBuffer: Hello World
clonedBuffer: Hello World
originalBuffer: Hello World New Data
clonedBuffer: Hello World
func read(Array<Byte>)
public func read(buffer: Array<Byte>): Int64
功能:从输入流中读取数据放到 buffer 中。
参数:
返回值:
- Int64 - 读取数据的字节数。
异常:
- IllegalArgumentException - 当 buffer 为空时,抛出异常。
示例:
import std.io.ByteBuffer
main(): Unit {
let inputData = "Hello World".toArray()
let buffer = ByteBuffer(inputData)
/* 创建一个目标缓冲区,读取数据到目标缓冲区 */
let targetBuffer = Array<Byte>(5,repeat:0)
buffer.read(targetBuffer)
println(String.fromUtf8(targetBuffer))
/* 尝试读取空缓冲区 */
try {
let emptyBuffer = Array<Byte>()
buffer.read(emptyBuffer)
} catch (e: IllegalArgumentException) {
println("Error: " + e.message)
}
}
运行结果:
Hello
Error: The buffer is empty.
func readByte()
public func readByte(): ?Byte
功能:从输入流中读取一个字节。
返回值:
- ?Byte - 读取到的数据。读取失败时会返回
None。
示例:
import std.io.ByteBuffer
main(): Unit {
let inputData = "Hello World".toArray()
let buffer = ByteBuffer(inputData)
for (_ in 0..inputData.size) {
print(String.fromUtf8(buffer.readByte().getOrThrow()))
}
println()
/* 尝试读取下一个不存在的字节 */
let nextByte = buffer.readByte()
match (nextByte) {
case None => println("nextByte: None")
case _ => println("nextByte: ${nextByte.getOrThrow()}")
}
}
运行结果:
Hello World
nextByte: None
func reserve(Int64)
public func reserve(additional: Int64): Unit
功能:将缓冲区扩容指定大小。
说明:
- 当缓冲区剩余字节数大于等于
additional时不发生扩容。- 当缓冲区剩余字节数量小于
additional时,取(additional+capacity)与(capacity的1.5倍向下取整)两个值中的最大值进行扩容。
参数:
- additional: Int64 - 将要扩容的大小。
异常:
- IllegalArgumentException - 当 additional 小于 0 时,抛出异常。
- OverflowException - 当扩容后的缓冲区大小超过 Int64 的最大值时,抛出异常。
示例:
import std.io.ByteBuffer
main(): Unit {
let buffer = ByteBuffer(11)
println("initial capacity: " + buffer.capacity.toString())
buffer.write("Hello World".toArray())
/* 尝试扩容,需要增加的容量大于剩余空间,发生扩容 */
buffer.reserve(5)
println("reserve 5: " + buffer.capacity.toString())
/* 尝试扩容,需要增加的容量小于剩余空间,不发生扩容 */
buffer.reserve(2)
println("reserve 2: " + buffer.capacity.toString())
/* 尝试扩容,additional为负数 */
try {
buffer.reserve(-1)
} catch (e: IllegalArgumentException) {
println("Error: " + e.message)
}
/* 尝试扩容,导致容量超过Int64最大值 */
try {
buffer.reserve(Int64.Max - buffer.capacity + 1)
} catch (e: OverflowException) {
println("Error: " + e.message)
}
}
运行结果:
initial capacity: 11
reserve 5: 16
reserve 2: 16
Error: The additional must be greater than or equal to 0.
Error:The maximum value for capacity expansion cannot exceed the maximum value of Int64.
func seek(SeekPosition)
public func seek(sp: SeekPosition): Int64
功能:将光标跳转到指定位置。
说明:
- 指定的位置不能位于流中数据头部之前。
- 指定位置可以超过流中数据末尾。
参数:
- sp: SeekPosition - 指定光标跳转后的位置。
返回值:
- Int64 - 流中数据的头部到跳转后位置的偏移量(以字节为单位)。
异常:
- IOException - 当指定的位置位于流中数据头部之前时,抛出异常。
示例:
import std.io.ByteBuffer
import std.io.SeekPosition
import std.io.IOException
main(): Unit {
let buffer = ByteBuffer("Hello World".toArray())
println("initial position: ${buffer.position}")
/* 移动到当前位置之后6个字节 */
buffer.seek(SeekPosition.Current(6))
println(String.fromUtf8(buffer.bytes()))
/* 移动位置超过流中数据末尾,为合法操作 */
println(buffer.seek(SeekPosition.End(1)))
/* 尝试移动到数据头部之前,抛出异常 */
try {
buffer.seek(SeekPosition.Begin(-1))
} catch (e: IOException) {
println("Error: " + e.message)
}
}
运行结果:
initial position: 0
World
12
Error: Can't move the position before the beginning of the stream.
func setLength(Int64)
public func setLength(length: Int64): Unit
功能:将当前数据修改为指定长度。该操作不会改变seek的偏移。
参数:
- length: Int64 - 要修改的长度。
异常:
- IllegalArgumentException - 当
length小于 0 时,抛此异常。 - OverflowException - 当 length 过大导致扩容后的缓冲区大小超过 Int64 的最大值时,抛出异常。
示例:
import std.io.ByteBuffer
main(): Unit {
let buffer = ByteBuffer("Hello World".toArray())
println("initial length: " + buffer.length.toString())
/* 设置长度为5,并读取缓冲区中所有的内容 */
buffer.setLength(5)
println("set length to 5: " + String.fromUtf8(buffer.bytes()))
/* 尝试设置扩容后的缓冲区大小超过 Int64 的最大值时,抛出异常 */
try {
buffer.setLength(Int64.Max + 1)
} catch (e: OverflowException) {
println("Error: " + e.message)
}
/* 尝试设置长度为-1,抛出异常 */
try {
buffer.setLength(-1)
} catch (e: IllegalArgumentException) {
println("Error: " + e.message)
}
}
运行结果:
initial length: 11
set length to 5: Hello
Error: add
Error: The length must be greater than or equal to 0.
func write(Array<Byte>)
public func write(buffer: Array<Byte>): Unit
功能:将 buffer 中的数据写入到输出流中。
参数:
示例:
import std.io.ByteBuffer
main(): Unit {
let buffer = ByteBuffer()
let dataToWrite = "Hello World".toArray()
/* 写入数据 */
buffer.write(dataToWrite)
println(String.fromUtf8(buffer.bytes()))
}
运行结果:
Hello World
func writeByte(Byte)
public func writeByte(v: Byte): Unit
功能:将一个字节写入到输出流中。
参数:
- v: Byte - 待写入的字节。
示例:
import std.io.ByteBuffer
main(): Unit {
let buffer = ByteBuffer()
let dataToWrite : Array<Byte> = "Hello World".toArray()
/* 每次写入单个字节 */
for( i in 0 .. dataToWrite.size){
buffer.writeByte(dataToWrite[i])
}
println(String.fromUtf8(buffer.bytes()))
}
运行结果:
Hello World
class ChainedInputStream<T> where T <: InputStream
public class ChainedInputStream<T> <: InputStream where T <: InputStream {
public init(input: Array<T>)
}
功能:提供顺序从 InputStream 数组中读取数据的能力。
父类型:
init(Array<T>)
public init(input: Array<T>)
功能:创建 ChainedInputStream 实例。
参数:
- input: Array<T> - 绑定指定输入流数组。
异常:
- IllegalArgumentException - 当 input 为空时,抛出异常。
func read(Array<Byte>)
public func read(buffer: Array<Byte>): Int64
功能:依次从绑定 InputStream 数组中读出数据到 buffer 中。
参数:
返回值:
- Int64 - 读取字节数。
异常:
- IllegalArgumentException - 当 buffer 为空时,抛出异常。
示例:
import std.io.*
main(): Unit {
let inputData = "Hello World".toArray()
let bufferInput = ByteBuffer(inputData)
let cis = ChainedInputStream(bufferInput)
// 缓冲区容量是 7
let bufferOutput = Array<Byte>(7, repeat: 0)
cis.read(bufferOutput)
let result = String.fromUtf8(bufferOutput)
println(result)
}
运行结果:
Hello W
class MultiOutputStream<T> where T <: OutputStream
public class MultiOutputStream<T> <: OutputStream where T <: OutputStream {
public init(output: Array<T>)
}
功能:提供将数据同时写入到 OutputStream 数组中每个输出流中的能力。
父类型:
init(Array<T>)
public init(output: Array<T>)
功能:创建 MultiOutputStream 实例。
参数:
- output: Array<T> - 绑定指定输出流数组。
异常:
- IllegalArgumentException - 当 output 为空时,抛出异常。
func flush()
public func flush(): Unit
功能:刷新绑定的输出流数组里的每个输出流。
func write(Array<Byte>)
public func write(buffer: Array<Byte>): Unit
功能:将 buffer 同时写入到绑定的 OutputStream 数组里的每个输出流中。
参数:
class StringReader<T> where T <: InputStream
public class StringReader<T> where T <: InputStream {
public init(input: T)
}
功能:提供从 InputStream 输入流中读出数据并转换成字符或字符串的能力。
说明:
- StringReader 内部默认有缓冲区,缓冲区容量 4096 个字节。
- StringReader 目前仅支持 UTF-8 编码,暂不支持 UTF-16、UTF-32。
init(T)
public init(input: T)
功能:创建 StringReader 实例。
参数:
- input: T - 待读取数据的输入流。
func lines()
public func lines(): Iterator<String>
功能:获得 StringReader 的行迭代器。
相当于循环调用 func readln(),内部遇到非法字符时也会抛出异常。
说明:
- 每行都由换行符进行分隔。
- 换行符是
\n\r\r\n之一。- 每行不包括换行符。
返回值:
异常:
- ContentFormatException - 当
for-in或者调用next()方法时读取到非法字符,抛出异常。
func read()
public func read(): ?Rune
功能:按字符读取流中的数据。
返回值:
异常:
- ContentFormatException - 当读取到非法字符时,抛出异常。
func readToEnd()
public func readToEnd(): String
功能:读取流中所有剩余数据。
返回值:
- String - 流中所有剩余数据。
异常:
- ContentFormatException - 当读取到非法字符时,抛出异常。
func readUntil((Rune)->Bool)
public func readUntil(predicate: (Rune)->Bool): Option<String>
功能:从流内读取到使 predicate 返回 true 的字符位置(包含这个字符)或者流结束位置的数据。
参数:
- predicate: (Rune)->Bool - 满足一定条件返回
true的表达式。
返回值:
异常:
- ContentFormatException - 当读取到非法字符时,抛出异常。
func readUntil(Rune)
public func readUntil(v: Rune): Option<String>
功能:从流内读取到指定字符(包含指定字符)或者流结束位置的数据。
参数:
- v: Rune - 指定字符。
返回值:
异常:
- ContentFormatException - 当读取到非法字符时,抛出异常。
func readln()
public func readln(): Option<String>
功能:按行读取流中的数据。
说明:
- 读取的数据会去掉原换行符。
返回值:
异常:
- ContentFormatException - 当读取到非法字符时,抛出异常。
func runes()
public func runes(): Iterator<Rune>
功能:获得 StringReader 的 Rune 迭代器。
返回值:
异常:
- ContentFormatException - 当
for-in或者调用next()方法时读取到非法字符,抛出异常。
extend<T> StringReader<T> <: Resource where T <: Resource
extend<T> StringReader<T> <: Resource where T <: Resource
功能:为 StringReader 实现 Resource 接口,该类型对象可在 try-with-resource 语法上下文中实现自动资源释放。
父类型:
func close()
public func close(): Unit
功能:关闭当前流。
注意:
- 调用此方法后不可再调用 StringReader 的其他接口,否则会造成不可期现象。
func isClosed()
public func isClosed(): Bool
功能:判断当前流是否关闭。
返回值:
- Bool - 如果当前流已经被关闭,返回 true,否则返回 false。
extend<T> StringReader<T> <: Seekable where T <: Seekable
extend<T> StringReader<T> <: Seekable where T <: Seekable
功能:为 StringReader 实现 Seekable 接口,支持查询数据长度,移动光标等操作。
父类型:
prop position
public prop position: Int64
功能:返回当前光标位置。
类型:Int64
func seek(SeekPosition)
public func seek(sp: SeekPosition): Int64
功能:移动光标到指定的位置。
说明:
- 指定的位置不能位于流中数据头部之前。
- 指定位置可以超过流中数据末尾。
参数:
- sp: SeekPosition - 指定光标移动后的位置。
返回值:
- Int64 - 返回流中数据的起点到移动后位置的偏移量(以字节为单位)。
异常:
- IOException - 当指定的位置位于流中数据头部之前时,抛出异常。
class StringWriter<T> where T <: OutputStream
public class StringWriter<T> where T <: OutputStream {
public init(output: T)
}
功能:提供将 String 以及一些 ToString 类型转换成指定编码格式和字节序配置的字符串并写入到输出流的能力。
说明:
- StringWriter 内部默认有缓冲区,缓冲区容量 4096 个字节。
- StringWriter 目前仅支持 UTF-8 编码,暂不支持 UTF-16、UTF-32。
init(T)
public init(output: T)
功能:创建 StringWriter 实例。
参数:
- output: T - 待写入数据的输出流。
func flush()
public func flush(): Unit
功能:刷新内部缓冲区,将缓冲区数据写入 output 中,并刷新 output。
func write(Bool)
public func write(v: Bool): Unit
功能:写入 Bool 类型。
参数:
func write(Float16)
public func write(v: Float16): Unit
功能:写入 Float16 类型。
参数:
func write(Float32)
public func write(v: Float32): Unit
功能:写入 Float32 类型。
参数:
func write(Float64)
public func write(v: Float64): Unit
功能:写入 Float64 类型。
参数:
func write(Int16)
public func write(v: Int16): Unit
功能:写入 Int16 类型。
参数:
func write(Int32)
public func write(v: Int32): Unit
功能:写入 Int32 类型。
参数:
func write(Int64)
public func write(v: Int64): Unit
功能:写入 Int64 类型。
参数:
func write(Int8)
public func write(v: Int8): Unit
功能:写入 Int8 类型。
参数:
func write(Rune)
public func write(v: Rune): Unit
功能:写入 Rune 类型。
参数:
func write(String)
public func write(v: String): Unit
功能:写入字符串。
参数:
- v: String - 待写入的字符串。
func write(UInt16)
public func write(v: UInt16): Unit
功能:写入 UInt16 类型。
参数:
func write(UInt32)
public func write(v: UInt32): Unit
功能:写入 UInt32 类型。
参数:
func write(UInt64)
public func write(v: UInt64): Unit
功能:写入 UInt64 类型。
参数:
func write(UInt8)
public func write(v: UInt8): Unit
功能:写入 UInt8 类型。
参数:
func write<T>(T) where T <: ToString
public func write<T>(v: T): Unit where T <: ToString
功能:写入 ToString 类型。
参数:
- v: T - ToString 类型的实例。
func writeln()
public func writeln(): Unit
功能:写入换行符。
func writeln(Bool)
public func writeln(v: Bool): Unit
功能:写入 Bool 类型 + 换行符。
参数:
func writeln(Float16)
public func writeln(v: Float16): Unit
功能:写入 Float16 类型 + 换行符。
参数:
func writeln(Float32)
public func writeln(v: Float32): Unit
功能:写入 Float32 类型 + 换行符。
参数:
func writeln(Float64)
public func writeln(v: Float64): Unit
功能:写入 Float64 类型 + 换行符。
参数:
func writeln(Int16)
public func writeln(v: Int16): Unit
功能:写入 Int16 类型 + 换行符。
参数:
func writeln(Int32)
public func writeln(v: Int32): Unit
功能:写入 Int32 类型 + 换行符。
参数:
func writeln(Int64)
public func writeln(v: Int64): Unit
功能:写入 Int64 类型 + 换行符。
参数:
func writeln(Int8)
public func writeln(v: Int8): Unit
功能:写入 Int8 类型 + 换行符。
参数:
func writeln(Rune)
public func writeln(v: Rune): Unit
功能:写入 Rune 类型 + 换行符。
参数:
func writeln(String)
public func writeln(v: String): Unit
功能:写入字符串 + 换行符。
参数:
- v: String - 待写入的字符串。
func writeln(UInt16)
public func writeln(v: UInt16): Unit
功能:写入 UInt16 类型 + 换行符。
参数:
func writeln(UInt32)
public func writeln(v: UInt32): Unit
功能:写入 UInt32 类型 + 换行符。
参数:
func writeln(UInt64)
public func writeln(v: UInt64): Unit
功能:写入 UInt64 类型 + 换行符。
参数:
func writeln(UInt8)
public func writeln(v: UInt8): Unit
功能:写入 UInt8 类型 + 换行符。
参数:
func writeln<T>(T) where T <: ToString
public func writeln<T>(v: T): Unit where T <: ToString
功能:写入 ToString 类型 + 换行符。
参数:
- v: T - ToString 类型的实例。
extend<T> StringWriter<T> <: Resource where T <: Resource
extend<T> StringWriter<T> <: Resource where T <: Resource
功能:为 StringWriter 实现 Resource 接口,该类型对象可在 try-with-resource 语法上下文中实现自动资源释放。
父类型:
func close()
public func close(): Unit
功能:关闭当前流。
注意:
- 调用此方法后不可再调用 StringWriter 的其他接口,否则会造成不可期现象。
func isClosed()
public func isClosed(): Bool
功能:判断当前流是否关闭。
返回值:
- Bool - 如果当前流已经被关闭,返回 true,否则返回 false。
extend<T> StringWriter<T> <: Seekable where T <: Seekable
extend<T> StringWriter<T> <: Seekable where T <: Seekable
功能:为 StringWriter 实现 Seekable 接口,支持查询数据长度,移动光标等操作。
父类型:
func seek(SeekPosition)
public func seek(sp: SeekPosition): Int64
功能:移动光标到指定的位置。
说明:
- 指定的位置不能位于流中数据头部之前。
- 指定位置可以超过流中数据末尾。
参数:
- sp: SeekPosition - 指定光标移动后的位置。
返回值:
- Int64 - 返回流中数据的起点到移动后位置的偏移量(以字节为单位)。
异常:
- IOException - 当指定的位置位于流中数据头部之前时,抛出异常。
枚举
enum SeekPosition
public enum SeekPosition {
| Begin(Int64)
| Current(Int64)
| End(Int64)
}
功能:该枚举类型表示光标在文件中的位置。
Begin(Int64)
Begin(Int64)
功能:表示从起点开始移动。
Current(Int64)
Current(Int64)
功能:表示从当前位置开始移动。
End(Int64)
End(Int64)
功能:表示从末尾开始移动。
异常
class ContentFormatException
public class ContentFormatException <: Exception {
public init()
public init(message: String)
}
功能:提供字符格式相关的异常处理。
父类型:
init()
public init()
功能:创建 ContentFormatException 实例。
init(String)
public init(message: String)
功能:根据异常信息创建 ContentFormatException 实例。
参数:
- message: String - 异常提示信息。
class IOException
public open class IOException <: Exception {
public init()
public init(message: String)
}
功能:提供 IO 流相关的异常处理。
父类型:
init()
public init()
功能:创建 IOException 实例。
init(String)
public init(message: String)
功能:根据异常信息创建 IOException 实例。
参数:
- message: String - 异常提示信息。
func getClassName()
protected open func getClassName(): String
功能:获得类名。
返回值:
- String - 类名。
BufferedInputStream 示例
下面是 BufferedInputStream 从流中读取数据示例。
import std.io.*
main(): Unit {
let arr1 = "0123456789".toArray()
let byteBuffer = ByteBuffer()
byteBuffer.write(arr1)
let bufferedInputStream = BufferedInputStream(byteBuffer)
let arr2 = Array<Byte>(20, repeat: 0)
/* 读取流中数据,返回读取到的数据的长度 */
let readLen = bufferedInputStream.read(arr2)
println(String.fromUtf8(arr2[..readLen]))
}
运行结果:
0123456789
BufferedOutputStream 示例
下面是 BufferedOutputStream 向流中写入数据示例。
import std.io.*
main(): Unit {
let arr1 = "01234".toArray()
let byteBuffer = ByteBuffer()
byteBuffer.write(arr1)
let bufferedOutputStream = BufferedOutputStream(byteBuffer)
let arr2 = "56789".toArray()
/* 向流中写入数据,此时数据在外部流的缓冲区中 */
bufferedOutputStream.write(arr2)
/* 调用 flush 函数,真正将数据写入内部流中 */
bufferedOutputStream.flush()
println(String.fromUtf8(readToEnd(byteBuffer)))
}
运行结果:
0123456789
ByteBuffer 示例
下面是 ByteBuffer 对流进行写入数据,读取数据等操作的示例。
import std.io.*
main(): Unit {
let arr1 = "test case".toArray()
let byteBuffer = ByteBuffer()
/* 将 arr1 中的数据写入到流中 */
byteBuffer.write(arr1)
/* 读取前 4 个字节的数据到 arr2 中 */
let arr2 = Array<Byte>(4, repeat: 0)
byteBuffer.read(arr2)
println(String.fromUtf8(arr2))
/* 将流的索引指向起点 */
byteBuffer.seek(Begin(0))
/* 读取流中全部数据 */
let arr3 = readToEnd(byteBuffer)
println(String.fromUtf8(arr3))
/* 将流的索引指向字母 'c' 的位置 */
byteBuffer.seek(End(-4))
/* 读取流中剩余数据 */
let str = readString(byteBuffer)
println(str)
}
运行结果:
test
test case
case
ChainedInputStream 示例
下面是 ChainedInputStream 从绑定的流中循环读取数据示例。
import std.io.*
import std.collection.ArrayList
main(): Unit {
const size = 2
/* 创建两个 ByteBuffer 并写入数据 */
let streamArr = Array<InputStream>(size, {_ => ByteBuffer()})
for (i in 0..size) {
match (streamArr[i]) {
case v: OutputStream =>
let str = "now ${i}"
v.write(str.toArray())
case _ => throw Exception()
}
}
/* 将两个 ByteBuffer 绑定到 ChainedInputStream */
let chainedInputStream = ChainedInputStream(streamArr)
let res = ArrayList<Byte>()
let buffer = Array<Byte>(20, repeat: 0)
var readLen = chainedInputStream.read(buffer)
/* 循环读取 chainedInputStream 中数据 */
while (readLen != 0) {
res.add(all: buffer[..readLen])
readLen = chainedInputStream.read(buffer)
}
println(String.fromUtf8(res.toArray()))
}
运行结果:
now 0now 1
MultiOutputStream 示例
下面是 MultiOutputStream 向绑定的所有流中写入数据示例。
import std.io.*
main(): Unit {
const size = 2
/* 将两个 ByteBuffer 绑定到 MultiOutputStream */
let streamArr = Array<OutputStream>(size, {_ => ByteBuffer()})
let multiOutputStream = MultiOutputStream(streamArr)
/* 往 MultiOutputStream 写入数据,会同时写入绑定的两个 ByteBuffer */
multiOutputStream.write("test".toArray())
/* 读取 ByteBuffer 中数据,验证结果 */
for (i in 0..size) {
match (streamArr[i]) {
case v: ByteBuffer =>
println(String.fromUtf8(readToEnd(v)))
case _ => throw Exception()
}
}
}
运行结果:
test
test
StringReader 示例
下面是 StringReader 从流中读取数据示例。
import std.io.*
main(): Unit {
let arr1 = "012\n346789".toArray()
let byteBuffer = ByteBuffer()
byteBuffer.write(arr1)
let stringReader = StringReader(byteBuffer)
/* 读取一个字节 */
let ch = stringReader.read()
println(ch ?? 'a')
/* 读取一行数据 */
let line = stringReader.readln()
println(line ?? "error")
/* 读取数据直到遇到字符6 */
let until = stringReader.readUntil(r'6')
println(until ?? "error")
/* 读取全部数据 */
let all = stringReader.readToEnd()
println(all)
}
运行结果:
0
12
346
789
StringWriter 示例
下面是 StringWriter 向流中写入数据示例。
import std.io.*
main(): Unit {
let byteBuffer = ByteBuffer()
let stringWriter = StringWriter(byteBuffer)
/* 写入字符串 */
stringWriter.write("number")
/* 写入字符串并自动转行 */
stringWriter.writeln(" is:")
/* 写入数字 */
stringWriter.write(100.0f32)
stringWriter.flush()
println(String.fromUtf8(readToEnd(byteBuffer)))
}
运行结果:
number is:
100.000000
std.math
功能介绍
math 包提供常见的数学运算,常数定义,浮点数处理等功能。
包括了以下能力:
- 科学常数与类型常数定义;
- 浮点数的判断,规整;
- 常用的位运算;
- 通用的数学函数,如绝对值,三角函数,指数,对数计算;
- 最大公约数与最小公倍数。
API 列表
函数
| 函数名 | 功能 |
|---|---|
| abs(Float16) | 求一个半精度浮点数的绝对值。 |
| abs(Float32) | 求一个单精度浮点数的绝对值。 |
| abs(Float64) | 求一个双精度浮点数的绝对值。 |
| abs(Int16) | 求一个 16 位有符号整数的绝对值。 |
| abs(Int32) | 求一个 32 位有符号整数的绝对值。 |
| abs(Int64) | 求一个 64 位有符号整数的绝对值。 |
| abs(Int8) | 求一个 8 位有符号整数的绝对值。 |
| acos(Float16) | 计算半精度浮点数的反余弦函数值,单位为弧度。 |
| acos(Float32) | 计算单精度浮点数的反余弦函数值,单位为弧度。 |
| acos(Float64) | 计算双精度浮点数的反余弦函数值,单位为弧度。 |
| acosh(Float16) | 计算半精度浮点数的反双曲余弦函数值。 |
| acosh(Float32) | 计算单精度浮点数的反双曲余弦函数值。 |
| acosh(Float64) | 计算双精度浮点数的反双曲余弦函数值。 |
| asin(Float16) | 计算半精度浮点数的反正弦函数值,单位为弧度。 |
| asin(Float32) | 计算单精度浮点数的反正弦函数值,单位为弧度。 |
| asin(Float64) | 计算双精度浮点数的反正弦函数值,单位为弧度。 |
| asinh(Float16) | 计算半精度浮点数的反双曲正弦函数值。 |
| asinh(Float32) | 计算单精度浮点数的反双曲正弦函数值。 |
| asinh(Float64) | 计算双精度浮点数的反双曲正弦函数值。 |
| atan(Float16) | 计算半精度浮点数的反正切函数值,单位为弧度。 |
| atan(Float32) | 计算单精度浮点数的反正切函数值,单位为弧度。 |
| atan(Float64) | 计算双精度浮点数的反正切函数值,单位为弧度。 |
| atan2(Float16, Float16) | 计算两个半精度浮点数的反正切函数值,单位为弧度。 |
| atan2(Float32, Float32) | 计算两个单精度浮点数的反正切函数值,单位为弧度。 |
| atan2(Float64, Float64) | 计算两个双精度浮点数的反正切函数值,单位为弧度。 |
| atanh(Float16) | 计算半精度浮点数的反双曲正切函数值。 |
| atanh(Float32) | 计算单精度浮点数的反双曲正切函数值。 |
| atanh(Float64) | 计算双精度浮点数的反双曲正切函数值。 |
| cbrt(Float16) | 求半精度浮点数的立方根。 |
| cbrt(Float32) | 求单精度浮点数的立方根。 |
| cbrt(Float64) | 求双精度浮点数的立方根。 |
| ceil(Float16) | 求半精度浮点数的向上取整值。 |
| ceil(Float32) | 求单精度浮点数的向上取整值。 |
| ceil(Float64) | 求双精度浮点数的向上取整值。 |
| checkedAbs(Int16) | 检查并求一个 16 位有符号整数的绝对值。如果入参是 16 位有符号整数的最小值,函数返回 None;否则,返回 Some(abs(x))。 |
| checkedAbs(Int32) | 检查并求一个 32 位有符号整数的绝对值。如果入参是 32 位有符号整数的最小值,函数返回 None;否则,返回 Some(abs(x))。 |
| checkedAbs(Int64) | 检查并求一个 64 位有符号整数的绝对值。如果入参是 64 位有符号整数的最小值,函数返回 None;否则,返回 Some(abs(x))。 |
| checkedAbs(Int8) | 检查并求一个 8 位有符号整数的绝对值。如果入参是 8 位有符号整数的最小值,函数返回 None;否则,返回 Some(abs(x))。 |
| clamp(Float16, Float16, Float16) | 求浮点数的范围区间数。如果此浮点数在该范围区间则返回此浮点数;如果此浮点数小于这个范围区间,则返回该范围区间的最小值;如果此浮点数大于这个范围区间,则返回该范围区间的最大值;如果是 NaN 则返回 NaN。 |
| clamp(Float32, Float32, Float32) | 求浮点数的范围区间数。如果此浮点数在该范围区间则返回此浮点数;如果此浮点数小于这个范围区间,则返回该范围区间的最小值;如果此浮点数大于这个范围区间,则返回该范围区间的最大值;如果是 NaN 则返回 NaN。 |
| clamp(Float64, Float64, Float64) | 求浮点数的范围区间数。如果此浮点数在该范围区间则返回此浮点数;如果此浮点数小于这个范围区间,则返回该范围区间的最小值;如果此浮点数大于这个范围区间,则返回该范围区间的最大值;如果是 NaN 则返回 NaN。 |
| cos(Float16) | 计算半精度浮点数的余弦函数值,入参单位为弧度。 |
| cos(Float32) | 计算单精度浮点数的余弦函数值,入参单位为弧度。 |
| cos(Float64) | 计算双精度浮点数的余弦函数值,入参单位为弧度。 |
| cosh(Float16) | 计算半精度浮点数的双曲余弦函数值。 |
| cosh(Float32) | 计算单精度浮点数的双曲余弦函数值。 |
| cosh(Float64) | 计算双精度浮点数的双曲余弦函数值。 |
| countOne(Int16) (deprecated) | 求 16 位整型的二进制表达中的 1 的位的个数。 |
| countOne(Int32) (deprecated) | 求 32 位整型的二进制表达中的 1 的位的个数。 |
| countOne(Int64) (deprecated) | 求 64 位整型的二进制表达中的 1 的位的个数。 |
| countOne(Int8) (deprecated) | 求 8 位整型的二进制表达中的 1 的位的个数。 |
| countOne(UInt16) (deprecated) | 求 16 位无符号整型的二进制表达中的 1 的位的个数。 |
| countOne(UInt32) (deprecated) | 求 32 位无符号整型的二进制表达中的 1 的位的个数。 |
| countOne(UInt64) (deprecated) | 求 64 位无符号整型的二进制表达中的 1 的位的个数。 |
| countOne(UInt8) (deprecated) | 求 8 位无符号整型的二进制表达中的 1 的位的个数。 |
| countOnes(Int16) | 求 16 位整型的二进制表达中的 1 的位的个数。 |
| countOnes(Int32) | 求 32 位整型的二进制表达中的 1 的位的个数。 |
| countOnes(Int64) | 求 64 位整型的二进制表达中的 1 的位的个数。 |
| countOnes(Int8) | 求 8 位整型的二进制表达中的 1 的位的个数。 |
| countOnes(UInt16) | 求 16 位无符号整型的二进制表达中的 1 的位的个数。 |
| countOnes(UInt32) | 求 32 位无符号整型的二进制表达中的 1 的位的个数。 |
| countOnes(UInt64) | 求 64 位无符号整型的二进制表达中的 1 的位的个数。 |
| countOnes(UInt8) | 求 8 位无符号整型的二进制表达中的 1 的位的个数。 |
| erf(Float16) | 求半精度浮点数的误差值。 |
| erf(Float32) | 求单精度浮点数的误差值。 |
| erf(Float64) | 求双精度浮点数的误差值。 |
| exp(Float16) | 求自然常数 e 的 x 次幂。 |
| exp(Float32) | 求自然常数 e 的 x 次幂。 |
| exp(Float64) | 求自然常数 e 的 x 次幂。 |
| exp2(Float16) | 求 2 的 x 次幂。 |
| exp2(Float32) | 求 2 的 x 次幂。 |
| exp2(Float64) | 求 2 的 x 次幂。 |
| floor(Float16) | 求浮点数的向下取整值。 |
| floor(Float32) | 求浮点数的向下取整值。 |
| floor(Float64) | 求浮点数的向下取整值。 |
| fmod(Float16, Float16) | 求两个半精度浮点数相除的余数。 |
| fmod(Float32, Float32) | 求两个单精度浮点数相除的余数。 |
| fmod(Float64, Float64) | 求两个双精度浮点数相除的余数。 |
| gamma(Float16) | 求浮点数的 Gamma 值。 |
| gamma(Float32) | 求浮点数的 Gamma 值。 |
| gamma(Float64) | 求浮点数的 Gamma 值。 |
| gcd(Int16, Int16) | 求两个 16 位有符号整数的最大公约数。 |
| gcd(Int32, Int32) | 求两个 32 位有符号整数的最大公约数。 |
| gcd(Int64, Int64) | 求两个 64 位有符号整数的最大公约数。 |
| gcd(Int8, Int8) | 求两个 8 位有符号整数的最大公约数。 |
| gcd(UInt16, UInt16) | 求两个 16 位无符号整数的最大公约数。 |
| gcd(UInt32, UInt32) | 求两个 32 位无符号整数的最大公约数。 |
| gcd(UInt64, UInt64) | 求两个 64 位无符号整数的最大公约数。 |
| gcd(UInt8, UInt8) | 求两个 8 位无符号整数的最大公约数。 |
| lcm(Int16, Int16) | 求两个 16 位有符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。 |
| lcm(Int32, Int32) | 求两个 32 位有符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。 |
| lcm(Int64, Int64) | 求两个 64 位有符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。 |
| lcm(Int8, Int8) | 求两个 8 位有符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。 |
| lcm(UInt16, UInt16) | 求两个 16 位无符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。 |
| lcm(UInt32, UInt32) | 求两个 32 位无符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。 |
| lcm(UInt64, UInt64) | 求两个 64 位无符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。 |
| lcm(UInt8, UInt8) | 求两个 8 位无符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。 |
| leadingZeros(Int16) | 求 16 位有符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。 |
| leadingZeros(Int32) | 求 32 位有符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。 |
| leadingZeros(Int64) | 求 64 位有符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。 |
| leadingZeros(Int8) | 求 8 位有符号整数的二进制表达中的从最高位算起,包含符号位,连续位为 0 的个数。如果最高位不是 0,则返回 0。 |
| leadingZeros(UInt16) | 求 16 位无符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。 |
| leadingZeros(UInt32) | 求 32 位无符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。 |
| leadingZeros(UInt64) | 求 64 位无符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。 |
| leadingZeros(UInt8) | 求 8 位无符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。 |
| log(Float16) | 求以 e 为底 x 的对数。 |
| log(Float32) | 求以 e 为底 x 的对数。 |
| log(Float64) | 求以 e 为底 x 的对数。 |
| log10(Float16) | 求以 10 为底 x 的对数。 |
| log10(Float32) | 求以 10 为底 x 的对数。 |
| log10(Float64) | 求以 10 为底 x 的对数。 |
| log2(Float16) | 求以 2 为底 x 的对数。 |
| log2(Float32) | 求以 2 为底 x 的对数。 |
| log2(Float64) | 求以 2 为底 x 的对数。 |
| logBase(Float16, Float16) | 求以 base 为底 x 的对数。 |
| logBase(Float32, Float32) | 求以 base 为底 x 的对数。 |
| logBase(Float64, Float64) | 求以 base 为底 x 的对数。 |
| pow(Float32, Float32) | 求浮点数 base 的 exponent 次幂。 |
| pow(Float32, Int32) | 求浮点数 base 的 exponent 次幂。 |
| pow(Float64, Float64) | 求浮点数 base 的 exponent 次幂。 |
| pow(Float64, Int64) | 求浮点数 base 的 exponent 次幂。 |
| reverse(UInt16) | 求无符号整数按位反转后的数。 |
| reverse(UInt32) | 求无符号整数按位反转后的数。 |
| reverse(UInt64) | 求无符号整数按位反转后的数。 |
| reverse(UInt8) | 求无符号整数按位反转后的数。 |
| rotate(Int16, Int8) | 求整数的按位旋转后的结果。 |
| rotate(Int32, Int8) | 求整数的按位旋转后的结果。 |
| rotate(Int64, Int8) | 求整数的按位旋转后的结果。 |
| rotate(Int8, Int8) | 求整数的按位旋转后的结果。 |
| rotate(UInt16, Int8) | 求整数的按位旋转后的结果。 |
| rotate(UInt32, Int8) | 求整数的按位旋转后的结果。 |
| rotate(UInt64, Int8) | 求整数的按位旋转后的结果。 |
| rotate(UInt8, Int8) | 求整数的按位旋转后的结果。 |
| round(Float16) | 此函数采用 IEEE-754 的向最近舍入规则,计算浮点数的舍入值。 |
| round(Float32) | 此函数采用 IEEE-754 的向最近舍入规则,计算浮点数的舍入值。 |
| round(Float64) | 此函数采用 IEEE-754 的向最近舍入规则,计算浮点数的舍入值。 |
| sin(Float16) | 计算半精度浮点数的正弦函数值,入参单位为弧度。 |
| sin(Float32) | 计算单精度浮点数的正弦函数值,入参单位为弧度。 |
| sin(Float64) | 计算双精度浮点数的正弦函数值,入参单位为弧度。 |
| sinh(Float16) | 计算半精度浮点数的双曲正弦函数值。 |
| sinh(Float32) | 计算单精度浮点数的双曲正弦函数值。 |
| sinh(Float64) | 计算双精度浮点数的双曲正弦函数值。 |
| sqrt(Float16) | 求浮点数的算术平方根。 |
| sqrt(Float32) | 求浮点数的算术平方根。 |
| sqrt(Float64) | 求浮点数的算术平方根。 |
| tan(Float16) | 计算半精度浮点数的正切函数值,入参单位为弧度。 |
| tan(Float32) | 计算单精度浮点数的正切函数值,入参单位为弧度。 |
| tan(Float64) | 计算双精度浮点数的正切函数值,入参单位为弧度。 |
| tanh(Float16) | 计算半精度浮点数的双曲正切函数值。 |
| tanh(Float32) | 计算单精度浮点数的双曲正切函数值。 |
| tanh(Float64) | 计算双精度浮点数的双曲正切函数值。 |
| trailingZeros(Int16) | 求 16 位有符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
| trailingZeros(Int32) | 求 32 位有符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
| trailingZeros(Int64) | 求 64 位有符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
| trailingZeros(Int8) | 求 16 位有符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
| trailingZeros(UInt16) | 求 16 位无符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
| trailingZeros(UInt32) | 求 32 位无符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
| trailingZeros(UInt64) | 求 64 位无符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
| trailingZeros(UInt8) | 求 8 位无符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
| trunc(Float16) | 求浮点数的截断取整值。 |
| trunc(Float32) | 求浮点数的截断取整值。 |
| trunc(Float64) | 求浮点数的截断取整值。 |
接口
| 接口名 | 功能 |
|---|---|
| FloatingPoint<T> | 本接口提供了浮点数相关的方法。 |
| Integer<T> | 本接口提供了整数类型相关的方法。 |
| MathExtension (deprecated) | 为了导出 prop 而作辅助接口,浮点数导出 PI,E 属性。 |
| MaxMinValue<T> | 提供获取最大值和最小值的方法。 |
| Number<T> | 提供数值类型相关的方法。 |
枚举
| 枚举 | 功能 |
|---|---|
| RoundingMode | 舍入规则枚举类,共包含 6 种舍入规则。除包含 IEEE 754 浮点数规定约定的 5 种舍入规则外,提供使用较多的 “四舍五入” 舍入规则。 |
接口
interface FloatingPoint<T>
public interface FloatingPoint<T> <: Number<T> {
static func getE(): T
static func getInf(): T
static func getPI(): T
static func getMinDenormal(): T
static func getMinNormal(): T
static func getNaN(): T
func isInf(): Bool
func isNaN(): Bool
func isNormal(): Bool
}
功能:本接口提供了浮点数相关的方法。
父类型:
- Number<T>
static func getE()
static func getE(): T
功能:获取 T 类型的自然常数。
返回值:
- T - 类型 T 的自然常数。
static func getInf()
static func getInf(): T
功能:获取浮点数的无穷数。
返回值:
- T - 类型 T 的无穷数。
static func getPI()
static func getPI(): T
功能:获取 T 类型的圆周率常数。
返回值:
- T - 类型 T 的圆周率常数。
static func getMinDenormal()
static func getMinDenormal(): T
功能:获取单精度浮点数的最小次正规数。
返回值:
- T - 类型 T 的最小次正规数。
static func getMinNormal()
static func getMinNormal(): T
功能:获取单精度浮点数的最小正规数。
返回值:
- T - 类型 T 的最小正规数。
static func getNaN()
static func getNaN(): T
功能:获取浮点数的非数。
返回值:
- T - 类型 T 的非数。
func isInf()
func isInf(): Bool
功能:判断浮点数是否为无穷数值。
返回值:
- Bool - 如果浮点数的值正无穷大或负无穷大,则返回
true;否则,返回false。
func isNaN()
func isNaN(): Bool
功能:判断浮点数是否为非数值。
返回值:
- Bool - 如果浮点数的值为非数值,则返回
true;否则,返回false。
func isNormal()
func isNormal(): Bool
功能:判断浮点数是否为常规数值。
返回值:
- Bool - 如果是正常的浮点数,返回
true;否则,返回false。
extend Float16 <: FloatingPoint<Float16>
extend Float16 <: FloatingPoint<Float16>
功能:为 Float16 类型扩展 FloatingPoint<Float16> 接口。
父类型:
static func getE()
public static func getE(): Float16
功能:获取半精度浮点数类型的自然常数。
返回值:
- Float16 - 半精度浮点数类型的自然常数。
static func getInf()
public static func getInf(): Float16
功能:获取半精度浮点数类型的无穷数值。
返回值:
- Float16 - 半精度浮点数类型的无穷数值。
static func getPI()
public static func getPI(): Float16
功能:获取半精度浮点数类型的圆周率常数。
返回值:
- Float16 - 半精度浮点数类型的圆周率常数。
static func getMinDenormal()
public static func getMinDenormal(): Float16
功能:获取半精度浮点数类型的最小次正规数。
返回值:
- Float16 - 半精度浮点数类型的最小次正规数。
static func getMinNormal()
public static func getMinNormal(): Float16
功能:获取半精度浮点数类型的最小正规数。
返回值:
- Float16 - 半精度浮点数类型的最小正规数。
static func getNaN()
public static func getNaN(): Float16
功能:获取半精度浮点数类型的非数。
返回值:
- Float16 - 半精度浮点数类型的非数。
extend Float32 <: FloatingPoint<Float32>
extend Float32 <: FloatingPoint<Float32>
功能:为 Float32 类型扩展 FloatingPoint<Float32> 接口。
父类型:
static func getE()
public static func getE(): Float32
功能:获取单精度浮点数类型的自然常数。
返回值:
- Float32 - 单精度浮点数类型的自然常数。
static func getInf()
public static func getInf(): Float32
功能:获取单精度浮点数类型的无穷数值。
返回值:
- Float32 - 单精度浮点数类型的无穷数值。
static func getPI()
public static func getPI(): Float32
功能:获取单精度浮点数类型的圆周率常数。
返回值:
- Float32 - 单精度浮点数类型的圆周率常数。
static func getMinDenormal()
public static func getMinDenormal(): Float32
功能:获取单精度浮点数类型的最小次正规数。
返回值:
- Float32 - 单精度浮点数类型的最小次正规数。
static func getMinNormal()
public static func getMinNormal(): Float32
功能:获取单精度浮点数类型的最小正规数。
返回值:
- Float32 - 单精度浮点数类型的最小正规数。
static func getNaN()
public static func getNaN(): Float32
功能:获取单精度浮点数类型的非数。
返回值:
- Float32 - 单精度浮点数类型的非数。
extend Float64 <: FloatingPoint<Float64>
extend Float64 <: FloatingPoint<Float64>
功能:为 Float64 类型扩展 FloatingPoint<Float64> 接口。
父类型:
static func getE()
public static func getE(): Float64
功能:获取双精度浮点数类型的自然常数。
返回值:
- Float64 - 双精度浮点数类型的自然常数。
static func getInf()
public static func getInf(): Float64
功能:获取双精度浮点数类型的无穷数值。
返回值:
- Float64 - 双精度浮点数类型的无穷数值。
static func getPI()
public static func getPI(): Float64
功能:获取双精度浮点数类型的圆周率常数。
返回值:
- Float64 - 双精度浮点数类型的圆周率常数。
static func getMinDenormal()
public static func getMinDenormal(): Float64
功能:获取双精度浮点数类型的最小次正规数。
返回值:
- Float64 - 双精度浮点数类型的最小次正规数。
static func getMinNormal()
public static func getMinNormal(): Float64
功能:获取双精度浮点数类型的最小正规数。
返回值:
- Float64 - 双精度浮点数类型的最小正规数。
static func getNaN()
public static func getNaN(): Float64
功能:获取双精度浮点数类型的非数。
返回值:
- Float64 - 双精度浮点数类型的非数。
interface Integer<T>
public interface Integer<T> <: Number<T> {
static func isSigned(): Bool
operator func %(rhs: T): T
operator func &(rhs: T): T
operator func |(rhs: T): T
operator func ^(rhs: T): T
operator func !(): T
operator func >>(n: Int64): T
operator func <<(n: Int64): T
}
功能:本接口提供了整数类型相关的方法。
父类型:
static func isSigned()
static func isSigned(): Bool
功能:判断类型是否是有符号的。
返回值:
- Bool - 如果类型是有符号的,返回
true;否则返回false。
operator func %(T)
operator func %(rhs: T): T
功能:算术运算符,计算余数。
参数:
- rhs: T - 运算符右边的数,表示除数。
返回值:
- T - 计算所得余数。
operator func &(T)
operator func &(rhs: T): T
功能:位运算符,按位与。
参数:
- rhs: T - 运算符右边的数。
返回值:
- T - 计算所得结果。
operator func |(T)
operator func |(rhs: T): T
功能:位运算符,按位或。
参数:
- rhs: T - 运算符右边的数。
返回值:
- T - 计算所得结果。
operator func ^(T)
operator func ^(rhs: T): T
功能:位运算符,按位异或。
参数:
- rhs: T - 运算符右边的数。
返回值:
- T - 计算所得结果。
operator func !()
operator func !(): T
功能:位运算符,按位取反。
返回值:
- T - 计算所得结果。
operator func >>(Int64)
operator func >>(n: Int64): T
功能:位运算符,按位右移。
参数:
- n: Int64 - 运算符右边的数,表示右移的位数。
返回值:
- T - 计算所得结果。
operator func <<(Int64)
operator func <<(n: Int64): T
功能:位运算符,按位左移。
参数:
- n: Int64 - 运算符右边的数,表示左移的位数。
返回值:
- T - 计算所得结果。
extend Int16 <: Integer<Int16>
extend Int16 <: Integer<Int16>
功能:为 Int16 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 Int16 类型是否是有符号类型。
返回值:
- Bool - 总是返回
true。
extend Int32 <: Integer<Int32>
extend Int32 <: Integer<Int32>
功能:为 Int32 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 Int32 类型是否是有符号类型。
返回值:
- Bool - 总是返回
true。
extend Int64 <: Integer<Int64>
extend Int64 <: Integer<Int64>
功能:为 Int64 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 Int64 类型是否是有符号类型。
返回值:
- Bool - 总是返回
true。
extend Int8 <: Integer<Int8>
extend Int8 <: Integer<Int8>
功能:为 Int8 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 Int8 类型是否是有符号类型。
返回值:
- Bool - 总是返回
true。
extend IntNative <: Integer<IntNative>
extend IntNative <: Integer<IntNative>
功能:为 IntNative 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 IntNative 类型是否是有符号类型。
返回值:
- Bool - 总是返回
true。
extend UInt16 <: Integer<UInt16>
extend UInt16 <: Integer<UInt16>
功能:为 UInt16 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 UInt16 类型是否是有符号类型。
返回值:
- Bool - 总是返回
false。
extend UInt32 <: Integer<UInt32>
extend UInt32 <: Integer<UInt32>
功能:为 UInt32 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 UInt32 类型是否是有符号类型。
返回值:
- Bool - 总是返回
false。
extend UInt64 <: Integer<UInt64>
extend UInt64 <: Integer<UInt64>
功能:为 UInt64 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 UInt64 类型是否是有符号类型。
返回值:
- Bool - 总是返回
false。
extend UInt8 <: Integer<UInt8>
extend UInt8 <: Integer<UInt8>
功能:为 UInt8 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 UInt8 类型是否是有符号类型。
返回值:
- Bool - 总是返回
false。
extend UIntNative <: Integer<UIntNative>
extend UIntNative <: Integer<UIntNative>
功能:为 UIntNative 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 UIntNative 类型是否是有符号类型。
返回值:
- Bool - 总是返回
false。
interface MathExtension<T> (deprecated)
public interface MathExtension<T> {
static func GetPI(): T
static func GetE(): T
}
功能:本接口提供了统一的方法获取一些数学常数。
注意:
未来版本即将废弃,使用 FloatingPoint<T> 替代。
static func GetPI()
static func GetPI(): T
功能:获取 T 类型的圆周率常数。
返回值:
- T - 类型 T 的圆周率常数。
static func GetE()
static func GetE(): T
功能:获取 T 类型的自然常数。
返回值:
- T - 类型 T 的自然常数。
extend Float16 <: MathExtension<Float16>
extend Float16 <: MathExtension<Float16>
功能:拓展半精度浮点数以支持一些数学常数。
父类型:
static func GetPI()
public static func GetPI(): Float16
功能:获取半精度浮点数的圆周率常数。
返回值:
- Float16 - 类型的圆周率常数
static func GetE()
public static func GetE(): Float16
功能:获取半精度浮点数的自然常数。
返回值:
- Float16 - 类型的自然常数
extend Float32 <: MathExtension<Float32>
extend Float32 <: MathExtension<Float32>
功能:拓展单精度浮点数以支持一些数学常数。
父类型:
static func GetPI()
public static func GetPI(): Float32
功能:获取单精度浮点数的圆周率常数。
返回值:
- Float32 - 类型的圆周率常数
static func GetE()
public static func GetE(): Float32
功能:获取单精度浮点数的自然常数。
返回值:
- Float32 - 类型的自然常数
extend Float64 <: MathExtension<Float64>
extend Float64 <: MathExtension<Float64>
功能:拓展双精度浮点数以支持一些数学常数。
父类型:
static func GetPI()
public static func GetPI(): Float64
功能:获取双精度浮点数的圆周率常数。
返回值:
- Float64 - 类型的圆周率常数
static func GetE()
public static func GetE(): Float64
功能:获取双精度浮点数的自然常数。
返回值:
- Float64 - 类型的自然常数
interface MaxMinValue<T>
public interface MaxMinValue<T> {
static func getMax(): T
static func getMin(): T
}
功能:提供获取最大值和最小值的方法。
static func getMax()
static func getMax(): T
功能:获取最大值。
返回值:
- T - 最大值。
static func getMax()
static func getMin(): T
功能:获取最小值。
返回值:
- T - 最小值。
extend Float16 <: MaxMinValue<Float16>
extend Float16 <: MaxMinValue<Float16>
功能:为 Float16 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): Float16
功能:获取 Float16 类型的最大值。
返回值:
- Float16 - 半精度浮点数类型的最大值。
static func getMin()
public static func getMin(): Float16
功能:获取 Float16 类型的最小值。
返回值:
- Float16 - 半精度浮点数类型的最小值。
extend Float32 <: MaxMinValue<Float32>
extend Float32 <: MaxMinValue<Float32>
功能:为 Float32 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): Float32
功能:获取 Float32 类型的最大值。
返回值:
- Float32 - 单精度浮点数类型的最大值。
static func getMin()
public static func getMin(): Float32
功能:获取 Float32 类型的最小值。
返回值:
- Float32 - 单精度浮点数类型的最小值。
extend Float64 <: MaxMinValue<Float64>
extend Float64 <: MaxMinValue<Float64>
功能:为 Float64 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): Float64
功能:获取 Float64 类型的最大值。
返回值:
- Float64 - 双精度浮点数类型的最大值。
static func getMin()
public static func getMin(): Float64
功能:获取 Float64 类型的最小值。
返回值:
- Float64 - 双精度浮点数类型的最小值。
extend Int16 <: MaxMinValue<Int16>
extend Int16 <: MaxMinValue<Int16>
功能:为 Int16 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): Int16
功能:获取 Int16 类型的最大值。
返回值:
static func getMin()
public static func getMin(): Int16
功能:获取 Int16 类型的最小值。
返回值:
extend Int32 <: MaxMinValue<Int32>
extend Int32 <: MaxMinValue<Int32>
功能:为 Int32 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): Int32
功能:获取 Int32 类型的最大值。
返回值:
static func getMin()
public static func getMin(): Int32
功能:获取 Int32 类型的最小值。
返回值:
extend Int64 <: MaxMinValue<Int64>
extend Int64 <: MaxMinValue<Int64>
功能:为 Int64 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): Int64
功能:获取 Int64 类型的最大值。
返回值:
static func getMin()
public static func getMin(): Int64
功能:获取 Int64 类型的最小值。
返回值:
extend Int8 <: MaxMinValue<Int8>
extend Int8 <: MaxMinValue<Int8>
功能:为 Int8 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): Int8
功能:获取 Int8 类型的最大值。
返回值:
static func getMin()
public static func getMin(): Int8
功能:获取 Int8 类型的最小值。
返回值:
extend IntNative <: MaxMinValue<IntNative>
extend IntNative <: MaxMinValue<IntNative>
功能:为 IntNative 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): IntNative
功能:获取 IntNative 类型的最大值。
返回值:
static func getMin()
public static func getMin(): IntNative
功能:获取 IntNative 类型的最小值。
返回值:
extend UInt16 <: MaxMinValue<UInt16>
extend UInt16 <: MaxMinValue<UInt16>
功能:为 UInt16 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): UInt16
功能:获取 UInt16 类型的最大值。
返回值:
static func getMin()
public static func getMin(): UInt16
功能:获取 UInt16 类型的最小值。
返回值:
extend UInt32 <: MaxMinValue<UInt32>
extend UInt32 <: MaxMinValue<UInt32>
功能:为 UInt32 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): UInt32
功能:获取 UInt32 类型的最大值。
返回值:
static func getMin()
public static func getMin(): UInt32
功能:获取 UInt32 类型的最小值。
返回值:
extend UInt64 <: MaxMinValue<UInt64>
extend UInt64 <: MaxMinValue<UInt64>
功能:为 UInt64 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): UInt64
功能:获取 UInt64 类型的最大值。
返回值:
static func getMin()
public static func getMin(): UInt64
功能:获取 UInt64 类型的最小值。
返回值:
extend UInt8 <: MaxMinValue<UInt8>
extend UInt8 <: MaxMinValue<UInt8>
功能:为 UInt8 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): UInt8
功能:获取 UInt8 类型的最大值。
返回值:
static func getMin()
public static func getMin(): UInt8
功能:获取 UInt8 类型的最小值。
返回值:
extend UIntNative <: MaxMinValue<UIntNative>
extend UIntNative <: MaxMinValue<UIntNative>
功能:为 UIntNative 类型扩展 MaxMinValue 接口。
父类型:
static func getMax()
public static func getMax(): UIntNative
功能:获取 UIntNative 类型的最大值。
返回值:
- UIntNative - UIntNative 类型的最大值。
static func getMin()
public static func getMin(): UIntNative
功能:获取 UIntNative 类型的最小值。
返回值:
- UIntNative - UIntNative 类型的最小值。
interface Number<T>
public interface Number<T> {
operator func +(rhs: T): T
operator func -(rhs: T): T
operator func *(rhs: T): T
operator func /(rhs: T): T
operator func -(): T
}
功能:提供数值类型相关的方法。
operator func +(T)
operator func +(rhs: T): T
功能:算术运算符,计算加法。
参数:
- rhs: T - 运算符右边的数,表示另一个加数。
返回值:
- T - 计算所得和。
operator func -(T)
operator func -(rhs: T): T
功能:算术运算符,计算减法。
参数:
- rhs: T - 运算符右边的数,表示减数。
返回值:
- T - 计算所得差。
operator func *(T)
operator func *(rhs: T): T
功能:算术运算符,计算乘法。
参数:
- rhs: T - 运算符右边的数,表示另一个乘数。
返回值:
- T - 计算所得积。
operator func /(T)
operator func /(rhs: T): T
功能:算术运算符,计算除法。
参数:
- rhs: T - 运算符右边的数,表示除数。
返回值:
- T - 计算所得商。
operator func -()
operator func -(): T
功能:算术运算符,计算取负的值。
返回值:
- T - 取负的值。
extend Float16 <: Number<Float16>
extend Float16 <: Number<Float16> {}
功能:为 Float16 类型扩展 Number<T> 接口。
父类型:
extend Float32 <: Number<Float32>
extend Float32 <: Number<Float32> {}
功能:为 Float32 类型扩展 Number<T> 接口。
父类型:
extend Float64 <: Number<Float64>
extend Float64 <: Number<Float64> {}
功能:为 Float64 类型扩展 Number<T> 接口。
父类型:
extend Int16 <: Number<Int16>
extend Int16 <: Number<Int16> {}
父类型:
extend Int32 <: Number<Int32>
extend Int32 <: Number<Int32> {}
父类型:
extend Int64 <: Number<Int64>
extend Int64 <: Number<Int64> {}
父类型:
extend Int8 <: Number<Int8>
extend Int8 <: Number<Int8> {}
父类型:
extend IntNative <: Number<IntNative>
extend IntNative <: Number<IntNative> {}
功能:为 IntNative 类型扩展 Number<T> 接口。
父类型:
extend UInt16 <: Number<UInt16>
extend UInt16 <: Number<UInt16> {}
功能:为 UInt16 类型扩展 Number<T> 接口。
父类型:
extend UInt32 <: Number<UInt32>
extend UInt32 <: Number<UInt32> {}
功能:为 UInt32 类型扩展 Number<T> 接口。
父类型:
extend UInt64 <: Number<UInt64>
extend UInt64 <: Number<UInt64> {}
功能:为 UInt64 类型扩展 Number<T> 接口。
父类型:
extend UInt8 <: Number<UInt8>
extend UInt8 <: Number<UInt8> {}
父类型:
extend UIntNative <: Number<UIntNative>
extend UIntNative <: Number<UIntNative> {}
功能:为 UIntNative 类型扩展 Number<T> 接口。
父类型:
函数
func abs(Float16)
public func abs(x: Float16): Float16
功能:求一个半精度浮点数的绝对值。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的绝对值。
示例:
import std.math.abs
main() {
let n: Float16 = -23.0
let abs = abs(n)
println(abs)
}
运行结果:
23.000000
func abs(Float32)
public func abs(x: Float32): Float32
功能:求一个单精度浮点数的绝对值。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的绝对值。
示例:
import std.math.abs
main() {
let n: Float32 = -23.0
let abs = abs(n)
println(abs)
}
运行结果:
23.000000
func abs(Float64)
public func abs(x: Float64): Float64
功能:求一个双精度浮点数的绝对值。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的绝对值。
示例:
import std.math.abs
main() {
let n: Float64 = -23.0
let abs = abs(n)
println(abs)
}
运行结果:
23.000000
func abs(Int16)
public func abs(x: Int16): Int16
功能:求一个 16 位有符号整数的绝对值。
参数:
- x: Int16 - 传入的 16 位有符号整数。
返回值:
- Int16 - 返回传入参数的绝对值。
异常:
- OverflowException - 当输入参数是有符号整数的最小值,抛出异常。
示例:
import std.math.abs
main() {
let n: Int16 = -23
let abs = abs(n)
println(abs)
}
运行结果:
23
以下示例抛出异常:
import std.math.abs
main(): Unit {
try {
let n = Int16(-2 ** 15)
let abs: Int16 = abs(n)
println(abs)
} catch (e: OverflowException) {
println("异常:输入参数是有符号整数的最小值")
}
}
运行结果:
异常:输入参数是有符号整数的最小值
func abs(Int32)
public func abs(x: Int32): Int32
功能:求一个 32 位有符号整数的绝对值。
参数:
- x: Int32 - 传入的 32 位有符号整数。
返回值:
- Int32 - 返回传入参数的绝对值。
异常:
- OverflowException - 当输入参数是有符号整数的最小值,抛出异常。
示例:
import std.math.abs
main() {
let n: Int32 = -23
let abs = abs(n)
println(abs)
}
运行结果:
23
func abs(Int64)
public func abs(x: Int64): Int64
功能:求一个 64 位有符号整数的绝对值。
参数:
- x: Int64 - 传入的 64 位有符号整数。
返回值:
- Int64 - 返回传入参数的绝对值。
异常:
- OverflowException - 当输入参数是有符号整数的最小值,抛出异常。
示例:
import std.math.abs
main() {
let n: Int64 = -23
let abs = abs(n)
println(abs)
}
运行结果:
23
func abs(Int8)
public func abs(x: Int8): Int8
功能:求一个 8 位有符号整数的绝对值。
参数:
- x: Int8 - 传入的 8 位有符号整数。
返回值:
- Int8 - 返回传入参数的绝对值。
异常:
- OverflowException - 当输入参数是有符号整数的最小值,抛出异常。
示例:
import std.math.abs
main() {
let n: Int8 = -23
let abs = abs(n)
println(abs)
}
运行结果:
23
func acos(Float16)
public func acos(x: Float16): Float16
功能:计算半精度浮点数的反余弦函数值。
参数:
- x: Float16 - 传入的半精度浮点数。-1.0 <=
x<= 1.0。
返回值:
- Float16 - 返回传入参数的反余弦函数值,单位为弧度。
异常:
- IllegalArgumentException - 当参数
x大于 1.0 或小于 -1.0 时,抛出异常。
示例:
import std.math.acos
main() {
let n: Float16 = 1.0
let acos = acos(n)
println(acos)
}
运行结果:
0.000000
以下示例将抛出异常:
import std.math.acos
main(): Unit {
let n = -1.5
let acos = acos(n)
println(acos)
}
func acos(Float32)
public func acos(x: Float32): Float32
功能:计算单精度浮点数的反余弦函数值。
参数:
- x: Float32 - 传入的单精度浮点数。-1.0 <=
x<= 1.0。
返回值:
- Float32 - 返回传入参数的反余弦函数值,单位为弧度。
异常:
- IllegalArgumentException - 当参数
x大于 1.0 或小于 -1.0 时,抛出异常。
示例:
import std.math.acos
main() {
let n: Float32 = 1.0
let acos = acos(n)
println(acos)
}
运行结果:
0.000000
func acos(Float64)
public func acos(x: Float64): Float64
功能:计算双精度浮点数的反余弦函数值。
参数:
- x: Float64 - 传入的双精度浮点数。-1.0 <=
x<= 1.0。
返回值:
- Float64 - 返回传入参数的反余弦函数值,单位为弧度。
异常:
- IllegalArgumentException - 当参数
x大于 1.0 或小于 -1.0 时,抛出异常。
示例:
import std.math.acos
main() {
let n: Float64 = 1.0
let acos = acos(n)
println(acos)
}
运行结果:
0.000000
func acosh(Float16)
public func acosh(x: Float16): Float16
功能:计算半精度浮点数的反双曲余弦函数值。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的反双曲余弦函数值。
x>= 1.0。
异常:
- IllegalArgumentException - 当参数
x小于 1.0 时,抛出异常。
示例:
import std.math.acosh
main() {
let n: Float16 = 1.0
let acosh = acosh(n)
println(acosh)
}
运行结果:
0.000000
以下示例将抛出异常:
import std.math.acosh
main(): Unit {
let n = 0.4
let acosh = acosh(n)
println(acosh)
}
func acosh(Float32)
public func acosh(x: Float32): Float32
功能:计算单精度浮点数的反双曲余弦函数值。
参数:
- x: Float32 - 传入的单精度浮点数。
x>= 1.0。
返回值:
- Float32 - 返回传入参数的反双曲余弦函数值。
异常:
- IllegalArgumentException - 当参数
x小于 1.0 时,抛出异常。
示例:
import std.math.acosh
main() {
let n: Float32 = 1.0
let acosh = acosh(n)
println(acosh)
}
运行结果:
0.000000
func acosh(Float64)
public func acosh(x: Float64): Float64
功能:计算双精度浮点数的反双曲余弦函数值。
参数:
- x: Float64 - 传入的双精度浮点数。
x>= 1.0。
返回值:
- Float64 - 返回传入参数的反双曲余弦函数值。
异常:
- IllegalArgumentException - 当参数
x小于 1.0 时,抛出异常。
示例:
import std.math.acosh
main() {
let n: Float64 = 1.0
let acosh = acosh(n)
println(acosh)
}
运行结果:
0.000000
func asin(Float16)
public func asin(x: Float16): Float16
功能:计算半精度浮点数的反正弦函数值。
参数:
- x: Float16 - 传入的半精度浮点数。-1.0 <=
x<= 1.0。
返回值:
- Float16 - 返回传入参数的反正弦函数值,单位为弧度。
异常:
- IllegalArgumentException - 当参数
x大于 1.0 或小于 -1.0 时,抛出异常。
示例:
import std.math.asin
main() {
let n: Float16 = 0.0
let asin = asin(n)
println(asin)
}
运行结果:
0.000000
以下示例将抛出异常:
import std.math.asin
main(): Unit {
let n = 1.4
let asin = asin(n)
println(asin)
}
func asin(Float32)
public func asin(x: Float32): Float32
功能:计算单精度浮点数的反正弦函数值。
参数:
- x: Float32 - 传入的单精度浮点数。-1.0 <=
x<= 1.0。
返回值:
- Float32 - 返回传入参数的反正弦函数值,单位为弧度。
异常:
- IllegalArgumentException - 当参数
x大于 1.0 或小于 -1.0 时,抛出异常。
示例:
import std.math.asin
main() {
let n: Float32 = 0.0
let asin = asin(n)
println(asin)
}
运行结果:
0.000000
func asin(Float64)
public func asin(x: Float64): Float64
功能:计算双精度浮点数的反正弦函数值。
参数:
- x: Float64 - 传入的双精度浮点数。-1.0 <=
x<= 1.0。
返回值:
- Float64 - 返回传入参数的反正弦函数值,单位为弧度。
异常:
- IllegalArgumentException - 当参数
x大于 1.0 或小于 -1.0 时,抛出异常。
示例:
import std.math.asin
main() {
let n: Float64 = 0.0
let asin = asin(n)
println(asin)
}
运行结果:
0.000000
func asinh(Float16)
public func asinh(x: Float16): Float16
功能:计算半精度浮点数的反双曲正弦函数值。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的反双曲正弦函数值。
示例:
import std.math.asinh
main() {
let n: Float16 = 0.0
let asinh = asinh(n)
println(asinh)
}
运行结果:
0.000000
func asinh(Float32)
public func asinh(x: Float32): Float32
功能:计算单精度浮点数的反双曲正弦函数值。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的反双曲正弦函数值。
示例:
import std.math.asinh
main() {
let n: Float32 = 0.0
let asinh = asinh(n)
println(asinh)
}
运行结果:
0.000000
func asinh(Float64)
public func asinh(x: Float64): Float64
功能:计算双精度浮点数的反双曲正弦函数值。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的反双曲正弦函数值。
示例:
import std.math.asinh
main() {
let n: Float64 = 0.0
let asinh = asinh(n)
println(asinh)
}
运行结果:
0.000000
func atan(Float16)
public func atan(x: Float16): Float16
功能:计算半精度浮点数的反正切函数值。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的反正切函数值,单位为弧度。
示例:
import std.math.atan
main() {
let n: Float16 = 0.0
let atan = atan(n)
println(atan)
}
运行结果:
0.000000
func atan(Float32)
public func atan(x: Float32): Float32
功能:计算单精度浮点数的反正切函数值。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的反正切函数值,单位为弧度。
示例:
import std.math.atan
main() {
let n: Float32 = 0.0
let atan = atan(n)
println(atan)
}
运行结果:
0.000000
func atan(Float64)
public func atan(x: Float64): Float64
功能:计算双精度浮点数的反正切函数值。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的反正切函数值,单位为弧度。
示例:
import std.math.atan
main() {
let n: Float64 = 0.0
let atan = atan(n)
println(atan)
}
运行结果:
0.000000
func atan2(Float16, Float16)
public func atan2(y: Float16, x: Float16): Float16
功能:计算两个半精度浮点数 y/x 的反正切函数值,单位为弧度。
参数:
返回值:
- Float16 - 返回 y/x 的反正切函数值,单位为弧度。
示例:
import std.math.*
import std.convert.Formattable
main() {
let y: Float16 = 1.0
let x: Float16 = 1.0
let atan2 = atan2(y, x) / Float16.getPI() * 180.0 // 将弧度值转为角度值打印
println("${atan2.format(".1")}°")
}
运行结果:
45.0°
func atan2(Float32, Float32)
public func atan2(y: Float32, x: Float32): Float32
功能:计算两个单精度浮点数 y/x 的反正切函数值,单位为弧度。
参数:
返回值:
- Float32 - 返回 y/x 的反正切函数值,单位为弧度。
示例:
import std.math.*
import std.convert.Formattable
main() {
let y: Float32 = 1.0
let x: Float32 = 1.0
let atan2 = atan2(y, x) / Float32.getPI() * 180.0 // 将弧度值转为角度值打印
println("${atan2.format(".1")}°")
}
运行结果:
45.0°
func atan2(Float64, Float64)
public func atan2(y: Float64, x: Float64): Float64
功能:计算两个双精度浮点数 y/x 的反正切函数值,单位为弧度。
参数:
返回值:
- Float64 - 返回 y/x 的反正切函数值,单位为弧度。
示例:
import std.math.*
import std.convert.Formattable
main() {
let y: Float64 = 1.0
let x: Float64 = 1.0
let atan2 = atan2(y, x) / Float64.getPI() * 180.0 // 将弧度值转为角度值打印
println("${atan2.format(".1")}°")
}
运行结果:
45.0°
func atanh(Float16)
public func atanh(x: Float16): Float16
功能:计算半精度浮点数的反双曲正切函数值。
参数:
- x: Float16 - 传入的半精度浮点数。-1.0 <
x< 1.0。
返回值:
- Float16 - 返回传入参数的反双曲正切函数值。
异常:
- IllegalArgumentException - 当参数
x大于等于 1.0 或小于等于 -1.0 时,抛出异常。
示例:
import std.math.atanh
main() {
let n: Float16 = 0.0
let atanh = atanh(n)
println(atanh)
}
运行结果:
0.000000
以下示例将抛出异常:
import std.math.atanh
main(): Unit {
let n = -1.4
let atanh = atanh(n)
println(atanh)
}
func atanh(Float32)
public func atanh(x: Float32): Float32
功能:计算单精度浮点数的反双曲正切函数值。
参数:
- x: Float32 - 传入的单精度浮点数。-1.0 <
x< 1.0。
返回值:
- Float32 - 返回传入参数的反双曲正切函数值。
异常:
- IllegalArgumentException - 当参数
x大于等于 1.0 或小于等于 -1.0 时,抛出异常。
示例:
import std.math.atanh
main() {
let n: Float32 = 0.0
let atanh = atanh(n)
println(atanh)
}
运行结果:
0.000000
func atanh(Float64)
public func atanh(x: Float64): Float64
功能:计算双精度浮点数的反双曲正切函数值。
参数:
- x: Float64 - 传入的双精度浮点数。-1.0 <
x< 1.0。
返回值:
- Float64 - 返回传入参数的反双曲正切函数值。
异常:
- IllegalArgumentException - 当参数
x大于等于 1.0 或小于等于 -1.0 时,抛出异常。
示例:
import std.math.atanh
main() {
let n: Float64 = 0.0
let atanh = atanh(n)
println(atanh)
}
运行结果:
0.000000
func cbrt(Float16)
public func cbrt(x: Float16): Float16
功能:求半精度浮点数的立方根。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的立方根。
示例:
import std.math.cbrt
main() {
let n: Float16 = -1000.0
let cbrt = cbrt(n)
println(cbrt)
}
运行结果:
-10.000000
func cbrt(Float32)
public func cbrt(x: Float32): Float32
功能:求单精度浮点数的立方根。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的立方根。
示例:
import std.math.cbrt
main() {
let n: Float32 = -1000.0
let cbrt = cbrt(n)
println(cbrt)
}
运行结果:
-10.000000
func cbrt(Float64)
public func cbrt(x: Float64): Float64
功能:求双精度浮点数的立方根。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的立方根。
示例:
import std.math.cbrt
main() {
let n: Float64 = -1000.0
let cbrt = cbrt(n)
println(cbrt)
}
运行结果:
-10.000000
func ceil(Float16)
public func ceil(x: Float16): Float16
功能:求半精度浮点数的向上取整值。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的向上取整值。
示例:
import std.math.ceil
main() {
let n: Float16 = 0.7
let ceil = ceil(n)
println(ceil)
}
运行结果:
1.000000
func ceil(Float32)
public func ceil(x: Float32): Float32
功能:求单精度浮点数的向上取整值。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的向上取整值。
示例:
import std.math.ceil
main() {
let n: Float32 = 0.7
let ceil = ceil(n)
println(ceil)
}
运行结果:
1.000000
func ceil(Float64)
public func ceil(x: Float64): Float64
功能:求双精度浮点数的向上取整值。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的向上取整值。
示例:
import std.math.ceil
main() {
let n: Float64 = 0.7
let ceil = ceil(n)
println(ceil)
}
运行结果:
1.000000
func checkedAbs(Int16)
public func checkedAbs(x: Int16): Option<Int16>
功能:求一个 16 位有符号整数的绝对值。如果入参是 16 位有符号整数的最小值,函数返回 None;否则,返回 Some(abs(x))。
参数:
- x: Int16 - 传入的 16 位有符号整数。
返回值:
示例:
import std.math.checkedAbs
main() {
let n: Int16 = -23
let checkedAbs = checkedAbs(n)
println(checkedAbs)
}
运行结果:
Some(23)
func checkedAbs(Int32)
public func checkedAbs(x: Int32): Option<Int32>
功能:求一个 32 位有符号整数的绝对值。如果入参是 32 位有符号整数的最小值,函数返回 None;否则,返回 Some(abs(x))。
参数:
- x: Int32 - 传入的 32 位有符号整数。
返回值:
示例:
import std.math.checkedAbs
main() {
let n: Int32 = -23
let checkedAbs = checkedAbs(n)
println(checkedAbs)
}
运行结果:
Some(23)
func checkedAbs(Int64)
public func checkedAbs(x: Int64): Option<Int64>
功能:求一个 64 位有符号整数的绝对值。如果入参是 64 位有符号整数的最小值,函数返回 None;否则,返回 Some(abs(x))。
参数:
- x: Int64 - 传入的 64 位有符号整数。
返回值:
示例:
import std.math.checkedAbs
main() {
let n: Int64 = -23
let checkedAbs = checkedAbs(n)
println(checkedAbs)
}
运行结果:
Some(23)
func checkedAbs(Int8)
public func checkedAbs(x: Int8): Option<Int8>
功能:求一个 8 位有符号整数的绝对值。如果入参是 8 位有符号整数的最小值,函数返回 None;否则,返回 Some(abs(x))。
参数:
- x: Int8 - 传入的 8 位有符号整数。
返回值:
示例:
import std.math.checkedAbs
main() {
let n: Int8 = -23
let checkedAbs = checkedAbs(n)
println(checkedAbs)
}
运行结果:
Some(23)
func clamp(Float16, Float16, Float16)
public func clamp(v: Float16, min: Float16, max: Float16): Float16
功能:求浮点数的范围区间数。如果此浮点数在该范围区间则返回此浮点数;如果此浮点数小于这个范围区间,则返回该范围区间的最小值;如果此浮点数大于这个范围区间,则返回该范围区间的最大值;如果是 NaN 则返回 NaN。
参数:
返回值:
- Float16 - 如果
v在min与max之间则返回v;如果v小于等于min则返回min;如果v大于等于max,则返回max;如果是NaN则返回NaN。
异常:
- IllegalArgumentException - 当参数
min大于参数max或者min和max是NaN时,抛出异常。
示例:
import std.math.clamp
main() {
let n: Float16 = -23.0
let clamp = clamp(n, -100.0, 100.0)
println(clamp)
}
运行结果:
-23.000000
func clamp(Float32, Float32, Float32)
public func clamp(v: Float32, min: Float32, max: Float32): Float32
功能:求浮点数的范围区间数。如果此浮点数在该范围区间则返回此浮点数;如果此浮点数小于这个范围区间,则返回该范围区间的最小值;如果此浮点数大于这个范围区间,则返回该范围区间的最大值;如果是 NaN 则返回 NaN。
参数:
返回值:
- Float32 - 如果
v在min与max之间则返回v;如果v小于等于min则返回min;如果v大于等于max,则返回max;如果是NaN则返回NaN。
异常:
- IllegalArgumentException - 当参数
min大于参数max或者min和max是NaN时,抛出异常。
示例:
import std.math.clamp
main() {
var m: Float32 = -23.0
var clamp1 = clamp(m, -100.0, 100.0)
println(clamp1)
var n: Float32 = -123.0
var clamp2 = clamp(n, -100.0, 100.0)
println(clamp2)
var p: Float32 = 123.0
var clamp3 = clamp(p, -100.0, 100.0)
println(clamp3)
}
运行结果:
-23.000000
-100.000000
100.000000
func clamp(Float64, Float64, Float64)
public func clamp(v: Float64, min: Float64, max: Float64): Float64
功能:求浮点数的范围区间数。如果此浮点数在该范围区间则返回此浮点数;如果此浮点数小于这个范围区间,则返回该范围区间的最小值;如果此浮点数大于这个范围区间,则返回该范围区间的最大值;如果是 NaN 则返回 NaN。
参数:
返回值:
- Float64 - 如果
v在min与max之间则返回v;如果v小于等于min则返回min;如果v大于等于max,则返回max;如果是NaN则返回NaN。
异常:
- IllegalArgumentException - 当参数
min大于参数max或者min和max是NaN时,抛出异常。
示例:
import std.math.clamp
main() {
let n: Float64 = -23.0
let clamp = clamp(n, -100.0, 100.0)
println(clamp)
}
运行结果:
-23.000000
func cos(Float16)
public func cos(x: Float16): Float16
功能:计算半精度浮点数的余弦函数值。
参数:
- x: Float16 - 传入的半精度浮点数,入参单位为弧度。
返回值:
- Float16 - 返回传入参数的余弦函数值。
示例:
import std.math.cos
main() {
let n: Float16 = 3.14159265
let cos = cos(n)
println(cos)
}
运行结果:
-1.000000
func cos(Float32)
public func cos(x: Float32): Float32
功能:计算单精度浮点数的余弦函数值。
参数:
- x: Float32 - 传入的单精度浮点数,入参单位为弧度。
返回值:
- Float32 - 返回传入参数的余弦函数值。
示例:
import std.math.cos
main() {
let n: Float32 = 3.14159265
let cos = cos(n)
println(cos)
}
运行结果:
-1.000000
func cos(Float64)
public func cos(x: Float64): Float64
功能:计算双精度浮点数的余弦函数值。
参数:
- x: Float64 - 传入的双精度浮点数,入参单位为弧度。
返回值:
- Float64 - 返回传入参数的余弦函数值。
示例:
import std.math.cos
main() {
let n: Float64 = 3.14159265
let cos = cos(n)
println(cos)
}
运行结果:
-1.000000
func cosh(Float16)
public func cosh(x: Float16): Float16
功能:计算半精度浮点数的双曲余弦函数值。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的双曲余弦函数值。
示例:
import std.math.cosh
main() {
let n: Float16 = 0.0
let cosh = cosh(n)
println(cosh)
}
运行结果:
1.000000
func cosh(Float32)
public func cosh(x: Float32): Float32
功能:计算单精度浮点数的双曲余弦函数值。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的双曲余弦函数值。
示例:
import std.math.cosh
main() {
let n: Float32 = 0.0
let cosh = cosh(n)
println(cosh)
}
运行结果:
1.000000
func cosh(Float64)
public func cosh(x: Float64): Float64
功能:计算双精度浮点数的双曲余弦函数值。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的双曲余弦函数值。
示例:
import std.math.cosh
main() {
let n: Float64 = 0.0
let cosh = cosh(n)
println(cosh)
}
运行结果:
1.000000
func countOne(Int16) (deprecated)
public func countOne(x: Int16): Int8
功能:求 16 位整型的二进制表达中 1 的个数。
注意:
未来版本即将废弃,使用 countOnes(Int16) 替代。
参数:
- x: Int16 - 传入的 16 位有符号整数。
返回值:
- Int8 - 返回传入参数的二进制表达中的 1 的位的个数。
func countOnes(Int16)
public func countOnes(x: Int16): Int64
功能:求 16 位整型的二进制表达中 1 的个数。
参数:
- x: Int16 - 传入的 16 位有符号整数。
返回值:
- Int64 - 返回传入参数的二进制表达中的 1 的位的个数。
示例:
import std.math.countOnes
main() {
let n: Int16 = 15
let countOnes = countOnes(n)
println(countOnes)
}
运行结果:
4
func countOne(Int32) (deprecated)
public func countOne(x: Int32): Int8
功能:求 32 位整型的二进制表达中 1 的个数。
注意:
未来版本即将废弃,使用 countOnes(Int32) 替代。
参数:
- x: Int32 - 传入的 32 位有符号整数。
返回值:
- Int8 - 返回传入参数的二进制表达中的 1 的位的个数。
func countOnes(Int32)
public func countOnes(x: Int32): Int64
功能:求 32 位整型的二进制表达中 1 的个数。
参数:
- x: Int32 - 传入的 32 位有符号整数。
返回值:
- Int64 - 返回传入参数的二进制表达中的 1 的位的个数。
示例:
import std.math.countOnes
main() {
let n: Int32 = 15
let countOnes = countOnes(n)
println(countOnes)
}
运行结果:
4
func countOne(Int64) (deprecated)
public func countOne(x: Int64): Int8
功能:求 64 位整型的二进制表达中 1 的个数。
注意:
未来版本即将废弃,使用 countOnes(Int64) 替代。
参数:
- x: Int64 - 传入的 64 位有符号整数。
返回值:
- Int8 - 返回传入参数的二进制表达中的 1 的位的个数。
func countOnes(Int64)
public func countOnes(x: Int64): Int64
功能:求 64 位整型的二进制表达中 1 的个数。
参数:
- x: Int64 - 传入的 64 位有符号整数。
返回值:
- Int64 - 返回传入参数的二进制表达中的 1 的位的个数。
示例:
import std.math.countOnes
main() {
let n: Int64 = 15
let countOnes = countOnes(n)
println(countOnes)
}
运行结果:
4
func countOne(Int8) (deprecated)
public func countOne(x: Int8): Int8
功能:求 8 位整型的二进制表达中 1 的个数。
注意:
未来版本即将废弃,使用 countOnes(Int8) 替代。
参数:
- x: Int8 - 传入的 8 位有符号整数。
返回值:
- Int8 - 返回传入参数的二进制表达中的 1 的位的个数。
func countOnes(Int8)
public func countOnes(x: Int8): Int64
功能:求 8 位整型的二进制表达中 1 的个数。
参数:
- x: Int8 - 传入的 8 位有符号整数。
返回值:
- Int64 - 返回传入参数的二进制表达中的 1 的位的个数。
示例:
import std.math.countOnes
main() {
let n: Int8 = 15
let countOnes = countOnes(n)
println(countOnes)
}
运行结果:
4
func countOne(UInt16) (deprecated)
public func countOne(x: UInt16): Int8
功能:求 16 位无符号整型的二进制表达中的 1 的位的个数。
注意:
未来版本即将废弃,使用 countOnes(UInt16) 替代。
参数:
- x: UInt16 - 传入的 16 位无符号整数。
返回值:
- Int8 - 返回传入参数的二进制表达中的 1 的位的个数。
func countOnes(UInt16)
public func countOnes(x: UInt16): Int64
功能:求 16 位无符号整型的二进制表达中的 1 的位的个数。
参数:
- x: UInt16 - 传入的 16 位无符号整数。
返回值:
- Int64 - 返回传入参数的二进制表达中的 1 的位的个数。
示例:
import std.math.countOnes
main() {
let n: UInt16 = 15
let countOnes = countOnes(n)
println(countOnes)
}
运行结果:
4
func countOne(UInt32) (deprecated)
public func countOne(x: UInt32): Int8
功能:求 32 位无符号整型的二进制表达中的 1 的位的个数。
注意:
未来版本即将废弃,使用 countOnes(UInt32) 替代。
参数:
- x: UInt32 - 传入的 32 位无符号整数。
返回值:
- Int8 - 返回传入参数的二进制表达中的 1 的位的个数。
func countOnes(UInt32)
public func countOnes(x: UInt32): Int64
功能:求 32 位无符号整型的二进制表达中的 1 的位的个数。
参数:
- x: UInt32 - 传入的 32 位无符号整数。
返回值:
- Int64 - 返回传入参数的二进制表达中的 1 的位的个数。
示例:
import std.math.countOnes
main() {
let n: UInt32 = 15
let countOnes = countOnes(n)
println(countOnes)
}
运行结果:
4
func countOne(UInt64) (deprecated)
public func countOne(x: UInt64): Int8
功能:求 64 位无符号整型的二进制表达中的 1 的位的个数。
注意:
未来版本即将废弃,使用 countOnes(UInt64) 替代。
参数:
- x: UInt64 - 传入的 64 位无符号整数。
返回值:
- Int8 - 返回传入参数的二进制表达中的 1 的位的个数。
func countOnes(UInt64)
public func countOnes(x: UInt64): Int64
功能:求 64 位无符号整型的二进制表达中的 1 的位的个数。
参数:
- x: UInt64 - 传入的 64 位无符号整数。
返回值:
- Int64 - 返回传入参数的二进制表达中的 1 的位的个数。
示例:
import std.math.countOnes
main() {
let n: UInt64 = 15
let countOnes = countOnes(n)
println(countOnes)
}
运行结果:
4
func countOne(UInt8) (deprecated)
public func countOne(x: UInt8): Int8
功能:求 8 位无符号整型的二进制表达中的 1 的位的个数。
注意:
未来版本即将废弃,使用 countOnes(UInt8) 替代。
参数:
- x: UInt8 - 传入的 8 位无符号整数。
返回值:
- Int8 - 返回传入参数的二进制表达中的 1 的位的个数。
func countOnes(UInt8)
public func countOnes(x: UInt8): Int64
功能:求 8 位无符号整型的二进制表达中的 1 的位的个数。
参数:
- x: UInt8 - 传入的 8 位无符号整数。
返回值:
- Int64 - 返回传入参数的二进制表达中的 1 的位的个数。
示例:
import std.math.countOnes
main() {
let n: UInt8 = 15
let countOnes = countOnes(n)
println(countOnes)
}
运行结果:
4
func erf(Float16)
public func erf(x: Float16): Float16
功能:求半精度浮点数的误差值。相关定义是:$$erf(x) = \frac{2}{\sqrt{\pi}}\int_0^xe^{-t^2}dt$$。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的半精度浮点数的误差值。
示例:
import std.math.erf
main() {
let n: Float16 = 5.0
let erf = erf(n)
println(erf)
}
运行结果:
1.000000
func erf(Float32)
public func erf(x: Float32): Float32
功能:求单精度浮点数的误差值。相关定义是:$$erf(x) = \frac{2}{\sqrt{\pi}}\int_0^xe^{-t^2}dt$$。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的单精度浮点数的误差值。
示例:
import std.math.erf
main() {
let n: Float32 = 5.0
let erf = erf(n)
println(erf)
}
运行结果:
1.000000
func erf(Float64)
public func erf(x: Float64): Float64
功能:求双精度浮点数的误差值。相关定义是:$$erf(x) = \frac{2}{\sqrt{\pi}}\int_0^xe^{-t^2}dt$$。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的双精度浮点数的误差值。
示例:
import std.math.erf
main() {
let n: Float64 = 5.0
let erf = erf(n)
println(erf)
}
运行结果:
1.000000
func exp(Float16)
public func exp(x: Float16): Float16
功能:求自然常数 e 的 x 次幂。
参数:
- x: Float16 - 传入的半精度浮点数指数。
返回值:
- Float16 - 返回自然常数 e 的
x次幂。
示例:
import std.math.exp
main() {
let n: Float16 = 1.0
let exp = exp(n)
println(exp)
}
运行结果:
2.718750
func exp(Float32)
public func exp(x: Float32): Float32
功能:求自然常数 e 的 x 次幂。
参数:
- x: Float32 - 传入的单精度浮点数指数。
返回值:
- Float32 - 返回自然常数 e 的
x次幂。
示例:
import std.math.exp
main() {
let n: Float32 = 1.0
let exp = exp(n)
println(exp)
}
运行结果:
2.718282
func exp(Float64)
public func exp(x: Float64): Float64
功能:求自然常数 e 的 x 次幂。
参数:
- x: Float64 - 传入的双精度浮点数指数。
返回值:
- Float64 - 返回自然常数 e 的
x次幂。
示例:
import std.math.exp
main() {
let n: Float64 = 1.0
let exp = exp(n)
println(exp)
}
运行结果:
2.718282
func exp2(Float16)
public func exp2(x: Float16): Float16
功能:求 2 的 x 次幂。
参数:
- x: Float16 - 传入的半精度浮点数指数。
返回值:
- Float16 - 返回 2 的
x次幂。
示例:
import std.math.exp2
main() {
let n: Float16 = 10.0
let exp2 = exp2(n)
println(exp2)
}
运行结果:
1024.000000
func exp2(Float32)
public func exp2(x: Float32): Float32
功能:求 2 的 x 次幂。
参数:
- x: Float32 - 传入的单精度浮点数指数。
返回值:
- Float32 - 返回 2 的
x次幂。
示例:
import std.math.exp2
main() {
let n: Float32 = 10.0
let exp2 = exp2(n)
println(exp2)
}
运行结果:
1024.000000
func exp2(Float64)
public func exp2(x: Float64): Float64
功能:求 2 的 x 次幂。
参数:
- x: Float64 - 传入的双精度浮点数指数。
返回值:
- Float64 - 返回 2 的
x次幂。
示例:
import std.math.exp2
main() {
let n: Float64 = 10.0
let exp = exp2(n)
println(exp)
}
运行结果:
1024.000000
func floor(Float16)
public func floor(x: Float16): Float16
功能:求浮点数的向下取整值。
参数:
- x: Float16 - 传入的需要向下取整的半精度浮点数。
返回值:
- Float16 - 返回传入浮点数的向下取整值。
示例:
import std.math.floor
main() {
let n: Float16 = 10.5
let floor = floor(n)
println(floor)
}
运行结果:
10.000000
func floor(Float32)
public func floor(x: Float32): Float32
功能:求浮点数的向下取整值。
参数:
- x: Float32 - 传入的需要向下取整的单精度浮点数。
返回值:
- Float32 - 返回传入浮点数的向下取整值。
示例:
import std.math.floor
main() {
let n: Float32 = 10.5
let floor = floor(n)
println(floor)
}
运行结果:
10.000000
func floor(Float64)
public func floor(x: Float64): Float64
功能:求浮点数的向下取整值。
参数:
- x: Float64 - 传入的需要向下取整的双精度浮点数。
返回值:
- Float64 - 返回传入浮点数的向下取整值。
示例:
import std.math.floor
main() {
let n: Float64 = 10.5
let floor = floor(n)
println(floor)
}
运行结果:
10.000000
func fmod(Float16, Float16)
public func fmod(x: Float16, y: Float16): Float16
功能:求两个半精度浮点数 x/y 的余数。
参数:
返回值:
- Float16 - 返回 x/y 的余数, 当 x 或 y 为
NaN时 返回NaN。
异常:
- IllegalArgumentException - 当 x 为
Inf或 y 为 0 时,抛出异常。
示例:
import std.math.fmod
import std.convert.Formattable
main() {
let x: Float16 = 3.3
let y: Float16 = 2.2
let fmod = fmod(x, y)
println(fmod.format(".1"))
}
运行结果:
1.1
func fmod(Float32, Float32)
public func fmod(x: Float32, y: Float32): Float32
功能:求两个单精度浮点数 x/y 的余数。
参数:
返回值:
- Float32 - 返回 x/y 的余数, 当 x 或 y 为
NaN时 返回NaN。
异常:
- IllegalArgumentException - 当 x 为
Inf或 y 为 0 时,抛出异常。
示例:
import std.math.fmod
import std.convert.Formattable
main() {
let x: Float32 = 3.3
let y: Float32 = 2.2
let fmod = fmod(x, y)
println(fmod.format(".1"))
}
运行结果:
1.1
func fmod(Float64, Float64)
public func fmod(x: Float64, y: Float64): Float64
功能:求两个双精度浮点数 x/y 的余数。
参数:
返回值:
- Float64 - 返回 x/y 的余数, 当 x 或 y 为
NaN时 返回NaN。
异常:
- IllegalArgumentException - 当 x 为
Inf或 y 为 0 时,抛出异常。
示例:
import std.math.fmod
import std.convert.Formattable
main() {
let x: Float64 = 3.3
let y: Float64 = 2.2
let fmod = fmod(x, y)
println(fmod.format(".1"))
}
运行结果:
1.1
func gamma(Float16)
public func gamma(x: Float16): Float16
功能:求浮点数的伽马函数值,该函数是阶乘概念在实数上的推广,其求值公式为:
$${\displaystyle \Gamma (x)=\int _{0}^{\infty }t^{x-1}\mathrm {e} ^{-t}{\rm {{d}t,}}}$$
参数:
- x: Float16 - 传入的需要求伽马函数值的半精度浮点数。
返回值:
- Float16 - 返回传入浮点数的伽马函数值。
示例:
import std.math.gamma
main() {
let n: Float16 = -1.1
let gamma = gamma(n)
println(gamma)
}
运行结果:
9.750000
func gamma(Float32)
public func gamma(x: Float32): Float32
功能:求浮点数的伽马函数值,该函数是阶乘概念在实数上的推广。
参数:
- x: Float32 - 传入的需要求伽马函数值的单精度浮点数。
返回值:
- Float32 - 返回传入浮点数的伽马函数值。
示例:
import std.math.gamma
main() {
let n: Float32 = -1.1
let gamma = gamma(n)
println(gamma)
}
运行结果:
9.714804
func gamma(Float64)
public func gamma(x: Float64): Float64
功能:求浮点数的伽马函数值,该函数是阶乘概念在实数上的推广。
参数:
- x: Float64 - 传入的需要求伽马函数值的双精度浮点数。
返回值:
- Float64 - 返回传入浮点数的伽马函数值。
示例:
import std.math.gamma
main() {
let n: Float64 = -1.1
let gamma = gamma(n)
println(gamma)
}
运行结果:
9.714806
func gcd(Int16, Int16)
public func gcd(x: Int16, y: Int16): Int16
功能:求两个 16 位有符号整数的最大公约数。
参数:
返回值:
- Int16 - 返回两个整数的最大公约数。
异常:
- IllegalArgumentException - 当两参数都为有符号整数最小值,或一个参数为有符号整数的最小值且另一个参数为 0 时,抛出异常。
示例:
import std.math.gcd
main() {
let x: Int16 = 15
let y: Int16 = 9
let gcd = gcd(x, y)
println(gcd)
}
运行结果:
3
func gcd(Int32, Int32)
public func gcd(x: Int32, y: Int32): Int32
功能:求两个 32 位有符号整数的最大公约数。
参数:
返回值:
- Int32 - 返回两个整数的最大公约数。
异常:
- IllegalArgumentException - 当两参数都为有符号整数最小值,或一个参数为有符号整数的最小值且另一个参数为 0 时,抛出异常。
示例:
import std.math.gcd
main() {
let x: Int32 = 15
let y: Int32 = 9
let gcd = gcd(x, y)
println(gcd)
}
运行结果:
3
func gcd(Int64, Int64)
public func gcd(x: Int64, y: Int64): Int64
功能:求两个 64 位有符号整数的最大公约数。
参数:
返回值:
- Int64 - 返回两个整数的最大公约数。
异常:
- IllegalArgumentException - 当两参数都为有符号整数最小值,或一个参数为有符号整数的最小值且另一个参数为 0 时,抛出异常。
示例:
import std.math.gcd
main() {
let x: Int64 = 15
let y: Int64 = 9
let gcd = gcd(x, y)
println(gcd)
}
运行结果:
3
func gcd(Int8, Int8)
public func gcd(x: Int8, y: Int8): Int8
功能:求两个 8 位有符号整数的最大公约数。
参数:
返回值:
- Int8 - 返回两个整数的最大公约数。
异常:
- IllegalArgumentException - 当两参数都为有符号整数最小值,或一个参数为有符号整数的最小值且另一个参数为 0 时,抛出异常。
示例:
import std.math.gcd
main() {
let x: Int8 = 15
let y: Int8= 9
let gcd = gcd(x, y)
println(gcd)
}
运行结果:
3
func gcd(UInt16, UInt16)
public func gcd(x: UInt16, y: UInt16): UInt16
功能:求两个 16 位无符号整数的最大公约数。
参数:
返回值:
- UInt16 - 返回两个整数的最大公约数。
示例:
import std.math.gcd
main() {
let x: UInt16 = 15
let y: UInt16 = 9
let gcd = gcd(x, y)
println(gcd)
}
运行结果:
3
func gcd(UInt32, UInt32)
public func gcd(x: UInt32, y: UInt32): UInt32
功能:求两个 32 位无符号整数的最大公约数。
参数:
返回值:
- UInt32 - 返回两个整数的最大公约数。
示例:
import std.math.gcd
main() {
let x: UInt32 = 15
let y: UInt32 = 9
let gcd = gcd(x, y)
println(gcd)
}
运行结果:
3
func gcd(UInt64, UInt64)
public func gcd(x: UInt64, y: UInt64): UInt64
功能:求两个 64 位无符号整数的最大公约数。
参数:
返回值:
- UInt64 - 返回两个整数的最大公约数。
示例:
import std.math.gcd
main() {
let x: UInt64 = 15
let y: UInt64 = 9
let gcd = gcd(x, y)
println(gcd)
}
运行结果:
3
func gcd(UInt8, UInt8)
public func gcd(x: UInt8, y: UInt8): UInt8
功能:求两个 8 位无符号整数的最大公约数。
参数:
返回值:
- UInt8 - 返回两个整数的最大公约数。
示例:
import std.math.gcd
main() {
let x: UInt8 = 15
let y: UInt8= 9
let gcd = gcd(x, y)
println(gcd)
}
运行结果:
3
func lcm(Int16, Int16)
public func lcm(x: Int16, y: Int16): Int16
功能:求两个 16 位有符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。
参数:
返回值:
- Int16 - 返回两个整数的最小的非负的公倍数,当入参有 0 时才返回 0。
异常:
- IllegalArgumentException - 当返回值超出 16 位有符号整数的最大值时抛出异常。
示例:
import std.math.lcm
main() {
let x: Int16 = -15
let y: Int16 = 9
let lcm = lcm(x, y)
println(lcm)
}
运行结果:
45
func lcm(Int32, Int32)
public func lcm(x: Int32, y: Int32): Int32
功能:求两个 32 位有符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。
参数:
返回值:
- Int32 - 返回两个整数的最小的非负的公倍数,当入参有 0 时才返回 0。
异常:
- IllegalArgumentException - 当返回值超出 32 位有符号整数的最大值时抛出异常。
示例:
import std.math.lcm
main() {
let x: Int32 = -15
let y: Int32 = 9
let lcm = lcm(x, y)
println(lcm)
}
运行结果:
45
func lcm(Int64, Int64)
public func lcm(x: Int64, y: Int64): Int64
功能:求两个 64 位有符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。
参数:
返回值:
- Int64 - 返回两个整数的最小的非负的公倍数,当入参有 0 时才返回 0。
异常:
- IllegalArgumentException - 当返回值超出 64 位有符号整数的最大值时抛出异常。
示例:
import std.math.lcm
main() {
let x: Int64 = 15
let y: Int64 = 9
let lcm = lcm(x, y)
println(lcm)
}
运行结果:
45
func lcm(Int8, Int8)
public func lcm(x: Int8, y: Int8): Int8
功能:求两个 8 位有符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。
参数:
返回值:
- Int8 - 返回两个整数的最小的非负的公倍数,当入参有 0 时才返回 0。
异常:
- IllegalArgumentException - 当返回值超出 8 位有符号整数的最大值时抛出异常。
示例:
import std.math.lcm
main() {
let x: Int8 = 15
let y: Int8= 9
let lcm = lcm(x, y)
println(lcm)
}
运行结果:
45
func lcm(UInt16, UInt16)
public func lcm(x: UInt16, y: UInt16): UInt16
功能:求两个 16 位无符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。
参数:
返回值:
- UInt16 - 返回两个整数的最小的非负的公倍数,当入参有 0 时才返回 0。
异常:
- IllegalArgumentException - 当返回值超出 16 位无符号整数的最大值时抛出异常。
示例:
import std.math.lcm
main() {
let x: UInt16 = 15
let y: UInt16 = 9
let lcm = lcm(x, y)
println(lcm)
}
运行结果:
45
func lcm(UInt32, UInt32)
public func lcm(x: UInt32, y: UInt32): UInt32
功能:求两个 32 位无符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。
参数:
返回值:
- UInt32 - 返回两个整数的最小的非负的公倍数,当入参有 0 时才返回 0。
异常:
- IllegalArgumentException - 当返回值超出 32 位无符号整数的最大值时抛出异常。
示例:
import std.math.lcm
main() {
let x: UInt32 = 15
let y: UInt32 = 9
let lcm = lcm(x, y)
println(lcm)
}
运行结果:
45
func lcm(UInt64, UInt64)
public func lcm(x: UInt64, y: UInt64): UInt64
功能:求两个 64 位无符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。
参数:
返回值:
- UInt64 - 返回两个整数的最小的非负的公倍数,当入参有 0 时才返回 0。
异常:
- IllegalArgumentException - 当返回值超出 64 位无符号整数的最大值时抛出异常。
示例:
import std.math.lcm
main() {
let x: UInt64 = 15
let y: UInt64 = 9
let lcm = lcm(x, y)
println(lcm)
}
运行结果:
45
func lcm(UInt8, UInt8)
public func lcm(x: UInt8, y: UInt8): UInt8
功能:求两个 8 位无符号整数的最小的非负的公倍数,当入参有 0 时才返回 0。
参数:
返回值:
- UInt8 - 返回两个整数的最小的非负的公倍数,当入参有 0 时才返回 0。
异常:
- IllegalArgumentException - 当返回值超出 8 位无符号整数的最大值时抛出异常。
示例:
import std.math.lcm
main() {
let x: UInt8 = 15
let y: UInt8= 9
let lcm = lcm(x, y)
println(lcm)
}
运行结果:
45
func leadingZeros(Int16)
public func leadingZeros(x: Int16): Int64
功能:求 16 位有符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。
参数:
- x: Int16 - 需要求前导 0 的整数。
返回值:
- Int64 - 返回前导 0 的位数。
示例:
import std.math.leadingZeros
main() {
let x: Int16 = 512
let leadingZeros = leadingZeros(x)
println(leadingZeros)
}
运行结果:
6
func leadingZeros(Int32)
public func leadingZeros(x: Int32): Int64
功能:求 32 位有符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。
参数:
- x: Int32 - 需要求前导 0 的整数。
返回值:
- Int64 - 返回前导 0 的位数。
示例:
import std.math.leadingZeros
main() {
let x: Int32 = 512
let leadingZeros = leadingZeros(x)
println(leadingZeros)
}
运行结果:
22
func leadingZeros(Int64)
public func leadingZeros(x: Int64): Int64
功能:求 64 位有符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。
参数:
- x: Int64 - 需要求前导 0 的整数。
返回值:
- Int64 - 返回前导 0 的位数。
示例:
import std.math.leadingZeros
main() {
let x: Int64 = 512
let leadingZeros = leadingZeros(x)
println(leadingZeros)
}
运行结果:
54
func leadingZeros(Int8)
public func leadingZeros(x: Int8): Int64
功能:求 8 位有符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。
参数:
- x: Int8 - 需要求前导 0 的整数。
返回值:
- Int64 - 返回前导 0 的位数。
示例:
import std.math.leadingZeros
main() {
let x: Int8 = 4
let leadingZeros = leadingZeros(x)
println(leadingZeros)
}
运行结果:
5
func leadingZeros(UInt16)
public func leadingZeros(x: UInt16): Int64
功能:求 16 位无符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。
参数:
- x: UInt16 - 需要求前导 0 的整数。
返回值:
- Int64 - 返回前导 0 的位数。
示例:
import std.math.leadingZeros
main() {
let x: UInt16 = 512
let leadingZeros = leadingZeros(x)
println(leadingZeros)
}
运行结果:
6
func leadingZeros(UInt32)
public func leadingZeros(x: UInt32): Int64
功能:求 32 位无符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。
参数:
- x: UInt32 - 需要求前导 0 的整数。
返回值:
- Int64 - 返回前导 0 的位数。
示例:
import std.math.leadingZeros
main() {
let x: UInt32 = 512
let leadingZeros = leadingZeros(x)
println(leadingZeros)
}
运行结果:
22
func leadingZeros(UInt64)
public func leadingZeros(x: UInt64): Int64
功能:求 64 位无符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。
参数:
- x: UInt64 - 需要求前导 0 的整数。
返回值:
- Int64 - 返回前导 0 的位数。
示例:
import std.math.leadingZeros
main() {
let x: UInt64 = 512
let leadingZeros = leadingZeros(x)
println(leadingZeros)
}
运行结果:
54
func leadingZeros(UInt8)
public func leadingZeros(x: UInt8): Int64
功能:求 8 位无符号整数的二进制表达中的从最高位算起,连续位为 0 的个数。如果最高位不是 0,则返回 0。
参数:
- x: UInt8 - 需要求前导 0 的整数。
返回值:
- Int64 - 返回前导 0 的位数。
示例:
import std.math.leadingZeros
main() {
let x: UInt8 = 64
let leadingZeros = leadingZeros(x)
println(leadingZeros)
}
运行结果:
1
func log(Float16)
public func log(x: Float16): Float16
功能:求以 e 为底 x 的对数。
参数:
- x: Float16 - 真数。
返回值:
- Float16 - 返回以 e 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log
main() {
let x: Float16 = 2.718282
let log1 = log(x)
let log2 = log(-x)
let log3 = log(0.0)
println(log1)
println(log2)
println(log3)
let log4 = -log3
println(log4)
}
运行结果:
1.000000
nan
-inf
inf
func log(Float32)
public func log(x: Float32): Float32
功能:求以 e 为底 x 的对数。
参数:
- x: Float32 - 真数。
返回值:
- Float32 - 返回以 e 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log
main() {
let x: Float32 = 2.718282
let log = log(x)
println(log)
}
运行结果:
1.000000
func log(Float64)
public func log(x: Float64): Float64
功能:求以 e 为底 x 的对数。
参数:
- x: Float64 - 真数。
返回值:
- Float64 - 返回以 e 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log
main() {
let x: Float64 = 2.718282
let log = log(x)
println(log)
}
运行结果:
1.000000
func log10(Float16)
public func log10(x: Float16): Float16
功能:求以 10 为底 x 的对数。
参数:
- x: Float16 - 真数。
返回值:
- Float16 - 返回以 10 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log10
main() {
let x: Float16 = 1000.0
let log10 = log10(x)
println(log10)
}
运行结果:
3.000000
func log10(Float32)
public func log10(x: Float32): Float32
功能:求以 10 为底 x 的对数。
参数:
- x: Float32 - 真数。
返回值:
- Float32 - 返回以 10 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log10
main() {
let x: Float32 = 1000.0
let log10 = log10(x)
println(log10)
}
运行结果:
3.000000
func log10(Float64)
public func log10(x: Float64): Float64
功能:求以 10 为底 x 的对数。
参数:
- x: Float64 - 真数。
返回值:
- Float64 - 返回以 10 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log10
main() {
let x: Float64 = 1000.0
let log10 = log10(x)
println(log10)
}
运行结果:
3.000000
func log2(Float16)
public func log2(x: Float16): Float16
功能:求以 2 为底 x 的对数。
参数:
- x: Float16 - 真数。
返回值:
- Float16 - 返回以 2 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log2
main() {
let x: Float16 = 1024.0
let log2 = log2(x)
println(log2)
}
运行结果:
10.000000
func log2(Float32)
public func log2(x: Float32): Float32
功能:求以 2 为底 x 的对数。
参数:
- x: Float32 - 真数。
返回值:
- Float32 - 返回以 2 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log2
main() {
let x: Float32 = 1024.0
let log2 = log2(x)
println(log2)
}
运行结果:
10.000000
func log2(Float64)
public func log2(x: Float64): Float64
功能:求以 2 为底 x 的对数。
参数:
- x: Float64 - 真数。
返回值:
- Float64 - 返回以 2 为底
x的对数。
说明:
返回值存在如下特殊场景:
示例:
import std.math.log2
main() {
let x: Float64 = 1024.0
let log2 = log2(x)
println(log2)
}
运行结果:
10.000000
func logBase(Float16, Float16)
public func logBase(x: Float16, base: Float16): Float16
功能:求以 base 为底 x 的对数。
参数:
返回值:
- Float16 - 返回以以
base为底x的对数。
异常:
- IllegalArgumentException - 当真数或底数不为正,或底数为 1 时,抛出异常。
示例:
import std.math.logBase
main() {
let x: Float16 = 512.0
let base: Float16 = 2.0
let logBase = logBase(x, base)
println(logBase)
}
运行结果:
9.000000
以下示例将抛出相应异常:
import std.math.logBase
main() {
let x: Float16 = 512.0
let base: Float16 = -2.0
// 示例1:底数为负数
try {
let logBase1 = logBase(x, base)
println(logBase1)
} catch (e: IllegalArgumentException) {
println("异常1:底数为负数")
}
// 示例2:真数为负数
try {
let logBase2 = logBase(-x, base)
println(logBase2)
} catch (e: IllegalArgumentException) {
println("异常2:真数为负数")
}
// 示例3:底数为1
try {
let logBase3 = logBase(x, 1.0)
println(logBase3)
} catch (e: IllegalArgumentException) {
println("异常3:底数为1")
}
}
运行结果:
异常1:底数为负数
异常2:真数为负数
异常3:底数为1
func logBase(Float32, Float32)
public func logBase(x: Float32, base: Float32): Float32
功能:求以 base 为底 x 的对数。
参数:
返回值:
- Float32 - 返回以以
base为底x的对数。
异常:
- IllegalArgumentException - 当真数或底数不为正,或底数为 1 时,抛出异常。
示例:
import std.math.logBase
main() {
let x: Float32 = 1024.0
let base: Float32 = 2.0
let logBase = logBase(x, base)
println(logBase)
}
运行结果:
10.000000
func logBase(Float64, Float64)
public func logBase(x: Float64, base: Float64): Float64
功能:求以 base 为底 x 的对数。
参数:
返回值:
- Float64 - 返回以以
base为底x的对数。
异常:
- IllegalArgumentException - 当真数或底数不为正,或底数为 1 时,抛出异常。
示例:
import std.math.logBase
main() {
let x: Float64 = 1024.0
let base: Float64 = 2.0
let logBase = logBase(x, base)
println(logBase)
}
运行结果:
10.000000
func pow(Float32, Float32)
public func pow(base: Float32, exponent: Float32): Float32
功能:求浮点数 base 的 exponent 次幂。
参数:
返回值:
- Float32 - 返回传入浮点数
base的exponent次幂。如果值不存在,则返回nan。
示例:
import std.math.pow
main() {
let base: Float32 = -1.0
let exponent: Float32 = 0.5
let pow = pow(base, exponent)
println(pow)
}
运行结果:
nan
func pow(Float32, Int32)
public func pow(base: Float32, exponent: Int32): Float32
功能:求浮点数 base 的 exponent 次幂。
参数:
返回值:
- Float32 - 返回传入浮点数
base的exponent次幂。
示例:
import std.math.pow
main() {
let base: Float32 = -1.0
let exponent: Int32 = 2
let pow = pow(base, exponent)
println(pow)
}
运行结果:
1.000000
func pow(Float64, Float64)
public func pow(base: Float64, exponent: Float64): Float64
功能:求浮点数 base 的 exponent 次幂。
参数:
返回值:
- Float64 - 返回传入浮点数
base的exponent次幂。如果值不存在,则返回nan。
示例:
import std.math.pow
main() {
let base: Float64 = -1.0
let exponent: Float64 = 0.5
let pow = pow(base, exponent)
println(pow)
}
运行结果:
nan
func pow(Float64, Int64)
public func pow(base: Float64, exponent: Int64): Float64
功能:求浮点数 base 的 exponent 次幂。
参数:
返回值:
- Float64 - 返回传入浮点数
base的exponent次幂。
示例:
import std.math.pow
main() {
let base: Float64 = -1.0
let exponent: Int64 = 2
let pow = pow(base, exponent)
println(pow)
}
运行结果:
1.000000
func reverse(UInt16)
public func reverse(x: UInt16): UInt16
功能:求无符号整数按位反转后的数。
参数:
- x: UInt16 - 需要进行反转的无符号整数。
返回值:
- UInt16 - 返回反转后的无符号数。
示例:
import std.math.reverse
main() {
let n: UInt16 = 0x8000
let reverse = reverse(n)
println(reverse)
}
运行结果:
1
func reverse(UInt32)
public func reverse(x: UInt32): UInt32
功能:求无符号整数按位反转后的数。
参数:
- x: UInt32 - 需要进行反转的无符号整数。
返回值:
- UInt32 - 返回反转后的无符号数。
示例:
import std.math.reverse
main() {
let n: UInt32 = 0x8000_0000
let reverse = reverse(n)
println(reverse)
}
运行结果:
1
func reverse(UInt64)
public func reverse(x: UInt64): UInt64
功能:求无符号整数按位反转后的数。
参数:
- x: UInt64 - 需要进行反转的无符号整数。
返回值:
- UInt64 - 返回反转后的无符号数。
示例:
import std.math.reverse
main() {
let n: UInt64 = 0x8000_0000_0000_0000
let reverse = reverse(n)
println(reverse)
}
运行结果:
1
func reverse(UInt8)
public func reverse(x: UInt8): UInt8
功能:求无符号整数按位反转后的数。
参数:
- x: UInt8 - 需要进行反转的无符号整数。
返回值:
- UInt8 - 返回反转后的无符号数。
示例:
import std.math.reverse
main() {
let n: UInt8 = 0x80
let reverse = reverse(n)
println(reverse)
}
运行结果:
1
func rotate(Int16, Int8)
public func rotate(num: Int16, d: Int8): Int16
功能:求整数的按位旋转后的结果。
参数:
返回值:
- Int16 - 返回旋转后的整数。
示例:
import std.math.rotate
main() {
let n: Int16 = 1
let rotate = rotate(n, 2)
println(rotate)
}
运行结果:
4
func rotate(Int32, Int8)
public func rotate(num: Int32, d: Int8): Int32
功能:求整数的按位旋转后的结果。
参数:
返回值:
- Int32 - 返回旋转后的整数。
示例:
import std.math.rotate
main() {
let n: Int32 = 1
let rotate = rotate(n, 2)
println(rotate)
}
运行结果:
4
func rotate(Int64, Int8)
public func rotate(num: Int64, d: Int8): Int64
功能:求整数的按位旋转后的结果。
参数:
返回值:
- Int64 - 返回旋转后的整数。
示例:
import std.math.rotate
main() {
let n: Int64 = 1
let rotate = rotate(n, 2)
println(rotate)
}
运行结果:
4
func rotate(Int8, Int8)
public func rotate(num: Int8, d: Int8): Int8
功能:求整数的按位旋转后的结果。
参数:
返回值:
- Int8 - 返回旋转后的整数。
示例:
import std.math.rotate
main() {
let n: Int8 = 1
let rotate = rotate(n, 2)
println(rotate)
}
运行结果:
4
func rotate(UInt16, Int8)
public func rotate(num: UInt16, d: Int8): UInt16
功能:求整数的按位旋转后的结果。
参数:
返回值:
- UInt16 - 返回旋转后的整数。
示例:
import std.math.rotate
main() {
let n: UInt16 = 1
let rotate = rotate(n, 2)
println(rotate)
}
运行结果:
4
func rotate(UInt32, Int8)
public func rotate(num: UInt32, d: Int8): UInt32
功能:求整数的按位旋转后的结果。
参数:
返回值:
- UInt32 - 返回旋转后的整数。
示例:
import std.math.rotate
main() {
let n: UInt32 = 1
let rotate = rotate(n, 2)
println(rotate)
}
运行结果:
4
func rotate(UInt64, Int8)
public func rotate(num: UInt64, d: Int8): UInt64
功能:求整数的按位旋转后的结果。
参数:
返回值:
- UInt64 - 返回旋转后的整数。
示例:
import std.math.rotate
main() {
let n: UInt64 = 1
let rotate = rotate(n, 2)
println(rotate)
}
运行结果:
4
func rotate(UInt8, Int8)
public func rotate(num: UInt8, d: Int8): UInt8
功能:求整数的按位旋转后的结果。
参数:
返回值:
- UInt8 - 返回旋转后的整数。
示例:
import std.math.rotate
main() {
let n: UInt8 = 1
let rotate = rotate(n, 2)
println(rotate)
}
运行结果:
4
func round(Float16)
public func round(x: Float16): Float16
功能:此函数采用 IEEE-754 的向最近舍入规则,计算浮点数的舍入值。如果该浮点数有两个最近整数,则向偶数舍入。
参数:
- x: Float16 - 需要计算舍入值的浮点数。
返回值:
- Float16 - 返回浮点数向最近整数方向的舍入值。如果该浮点数有两个最近整数,则返回向偶数舍入值。
示例:
import std.math.round
main() {
let n: Float16 = 1.5
let round = round(n)
println(round)
}
运行结果:
2.000000
func round(Float32)
public func round(x: Float32): Float32
功能:此函数采用 IEEE-754 的向最近舍入规则,计算浮点数的舍入值。如果该浮点数有两个最近整数,则向偶数舍入。
参数:
- x: Float32 - 需要计算舍入值的浮点数。
返回值:
- Float32 - 返回浮点数向最近整数方向的舍入值。如果该浮点数有两个最近整数,则返回向偶数舍入值。
示例:
import std.math.round
main() {
let n: Float32 = 1.5
let round = round(n)
println(round)
}
运行结果:
2.000000
func round(Float64)
public func round(x: Float64): Float64
功能:此函数采用 IEEE-754 的向最近舍入规则,计算浮点数的舍入值。如果该浮点数有两个最近整数,则向偶数舍入。
参数:
- x: Float64 - 需要计算舍入值的浮点数。
返回值:
- Float64 - 返回浮点数向最近整数方向的舍入值。如果该浮点数有两个最近整数,则返回向偶数舍入值。
示例:
import std.math.round
main() {
let n: Float64 = 1.5
let round = round(n)
println(round)
}
运行结果:
2.000000
func sin(Float16)
public func sin(x: Float16): Float16
功能:计算半精度浮点数的正弦函数值。
参数:
- x: Float16 - 传入的半精度浮点数,入参单位为弧度。
返回值:
- Float16 - 返回传入参数的正弦函数值。
示例:
import std.math.sin
main() {
let n: Float16 = 3.1415926/2.0
let sin = sin(n)
println(sin)
}
运行结果:
1.000000
func sin(Float32)
public func sin(x: Float32): Float32
功能:计算单精度浮点数的正弦函数值。
参数:
- x: Float32 - 传入的单精度浮点数,入参单位为弧度。
返回值:
- Float32 - 返回传入参数的正弦函数值。
示例:
import std.math.sin
main() {
let n: Float32 = 3.1415926/2.0
let sin = sin(n)
println(sin)
}
运行结果:
1.000000
func sin(Float64)
public func sin(x: Float64): Float64
功能:计算双精度浮点数的正弦函数值。
参数:
- x: Float64 - 传入的双精度浮点数,入参单位为弧度。
返回值:
- Float64 - 返回传入参数的正弦函数值。
示例:
import std.math.sin
main() {
let n: Float64 = 3.1415926/2.0
let sin = sin(n)
println(sin)
}
运行结果:
1.000000
func sinh(Float16)
public func sinh(x: Float16): Float16
功能:计算半精度浮点数的双曲正弦函数值。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的双曲正弦函数值。
示例:
import std.math.sinh
main() {
let n: Float16 = 0.0
let sinh = sinh(n)
println(sinh)
}
运行结果:
0.000000
func sinh(Float32)
public func sinh(x: Float32): Float32
功能:计算单精度浮点数的双曲正弦函数值。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的双曲正弦函数值。
示例:
import std.math.sinh
main() {
let n: Float32 = 0.0
let sinh = sinh(n)
println(sinh)
}
运行结果:
0.000000
func sinh(Float64)
public func sinh(x: Float64): Float64
功能:计算双精度浮点数的双曲正弦函数值。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的双曲正弦函数值。
示例:
import std.math.sinh
main() {
let n: Float64 = 0.0
let sinh = sinh(n)
println(sinh)
}
运行结果:
0.000000
func sqrt(Float16)
public func sqrt(x: Float16): Float16
功能:求浮点数的算术平方根。
参数:
- x: Float16 - 需要计算算数平方根的浮点数。
x需要大于等于 0。
返回值:
- Float16 - 返回传入的浮点数的算术平方根。
异常:
- IllegalArgumentException - 当参数为负数时,抛出异常。
示例:
import std.math.sqrt
main() {
let n: Float16 = 16.0
let sqrt = sqrt(n)
println(sqrt)
}
运行结果:
4.000000
func sqrt(Float32)
public func sqrt(x: Float32): Float32
功能:求浮点数的算术平方根。
参数:
- x: Float32 - 需要计算算数平方根的浮点数。
x需要大于等于 0。
返回值:
- Float32 - 返回传入的浮点数的算术平方根。
异常:
- IllegalArgumentException - 当参数为负数时,抛出异常。
示例:
import std.math.sqrt
main() {
let n: Float32 = 16.0
let sqrt = sqrt(n)
println(sqrt)
}
运行结果:
4.000000
func sqrt(Float64)
public func sqrt(x: Float64): Float64
功能:求浮点数的算术平方根。
参数:
- x: Float64 - 需要计算算数平方根的浮点数。
x需要大于等于 0。
返回值:
- Float64 - 返回传入的浮点数的算术平方根。
异常:
- IllegalArgumentException - 当参数为负数时,抛出异常。
示例:
import std.math.sqrt
main() {
let n: Float64 = 16.0
let sqrt = sqrt(n)
println(sqrt)
}
运行结果:
4.000000
func tan(Float16)
public func tan(x: Float16): Float16
功能:计算半精度浮点数的正切函数值。
参数:
- x: Float16 - 传入的半精度浮点数,入参单位为弧度。
返回值:
- Float16 - 返回传入参数的正切函数值。
示例:
import std.math.tan
main() {
let n: Float16 = 0.0
let tan = tan(n)
println(tan)
}
运行结果:
0.000000
func tan(Float32)
public func tan(x: Float32): Float32
功能:计算单精度浮点数的正切函数值。
参数:
- x: Float32 - 传入的单精度浮点数,入参单位为弧度。
返回值:
- Float32 - 返回传入参数的正切函数值。
示例:
import std.math.tan
main() {
let n: Float32 = 0.0
let tan = tan(n)
println(tan)
}
运行结果:
0.000000
func tan(Float64)
public func tan(x: Float64): Float64
功能:计算双精度浮点数的正切函数值。
参数:
- x: Float64 - 传入的双精度浮点数,入参单位为弧度。
返回值:
- Float64 - 返回传入参数的正切函数值。
示例:
import std.math.tan
main() {
let n: Float64 = 0.0
let tan = tan(n)
println(tan)
}
运行结果:
0.000000
func tanh(Float16)
public func tanh(x: Float16): Float16
功能:计算半精度浮点数的双曲正切函数值。
参数:
- x: Float16 - 传入的半精度浮点数。
返回值:
- Float16 - 返回传入参数的双曲正切函数值。
示例:
import std.math.tanh
main() {
let n: Float16 = 0.0
let tanh = tanh(n)
println(tanh)
}
运行结果:
0.000000
func tanh(Float32)
public func tanh(x: Float32): Float32
功能:计算单精度浮点数的双曲正切函数值。
参数:
- x: Float32 - 传入的单精度浮点数。
返回值:
- Float32 - 返回传入参数的双曲正切函数值。
示例:
import std.math.tanh
main() {
let n: Float32 = 0.0
let tanh = tanh(n)
println(tanh)
}
运行结果:
0.000000
func tanh(Float64)
public func tanh(x: Float64): Float64
功能:计算双精度浮点数的双曲正切函数值。
参数:
- x: Float64 - 传入的双精度浮点数。
返回值:
- Float64 - 返回传入参数的双曲正切函数值。
示例:
import std.math.tanh
main() {
let n: Float64 = 0.0
let tanh = tanh(n)
println(tanh)
}
运行结果:
0.000000
func trailingZeros(Int16)
public func trailingZeros(x: Int16): Int64
功能:求 16 位有符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
- x: Int16 - 需要求后置 0 的整数。
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.trailingZeros
main() {
let x: Int16 = 512
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
9
func trailingZeros(Int32)
public func trailingZeros(x: Int32): Int64
功能:求 32 位有符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
- x: Int32 - 需要求后置 0 的整数。
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.trailingZeros
main() {
let x: Int32 = 512
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
9
func trailingZeros(Int64)
public func trailingZeros(x: Int64): Int64
功能:求 64 位有符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
- x: Int64 - 需要求后置 0 的整数。
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.trailingZeros
main() {
let x: Int64 = 512
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
9
func trailingZeros(Int8)
public func trailingZeros(x: Int8): Int64
功能:求 16 位有符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
- x: Int8 - 需要求后置 0 的整数。
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.trailingZeros
main() {
let x: Int8 = 64
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
6
func trailingZeros(UInt16)
public func trailingZeros(x: UInt16): Int64
功能:求 16 位无符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
- x: UInt16 - 需要求后置 0 的整数。
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.trailingZeros
main() {
let x: UInt16 = 512
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
9
func trailingZeros(UInt32)
public func trailingZeros(x: UInt32): Int64
功能:求 32 位无符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
- x: UInt32 - 需要求后置 0 的整数。
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.trailingZeros
main() {
let x: UInt32 = 512
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
9
func trailingZeros(UInt64)
public func trailingZeros(x: UInt64): Int64
功能:求 64 位无符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
- x: UInt64 - 需要求后置 0 的整数。
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.trailingZeros
main() {
let x: UInt64 = 512
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
9
func trailingZeros(UInt8)
public func trailingZeros(x: UInt8): Int64
功能:求 8 位无符号整数的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
- x: UInt8 - 需要求后置 0 的整数。
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.trailingZeros
main() {
let x: UInt8 = 64
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
6
func trunc(Float16)
public func trunc(x: Float16): Float16
功能:求浮点数的截断取整值。
参数:
- x: Float16 - 需要截断取整的浮点数。
返回值:
- Float16 - 返回传入浮点数截断取整后的值。
示例:
import std.math.trunc
main() {
let x: Float16 = 64.555566
let trunc = trunc(x)
println(trunc)
}
运行结果:
64.000000
func trunc(Float32)
public func trunc(x: Float32): Float32
功能:求浮点数的截断取整值。
参数:
- x: Float32 - 需要截断取整的浮点数。
返回值:
- Float32 - 返回传入浮点数截断取整后的值。
示例:
import std.math.trunc
main() {
let x: Float32 = 64.555566
let trunc = trunc(x)
println(trunc)
}
运行结果:
64.000000
func trunc(Float64)
public func trunc(x: Float64): Float64
功能:求浮点数的截断取整值。
参数:
- x: Float64 - 需要截断取整的浮点数。
返回值:
- Float64 - 返回传入浮点数截断取整后的值。
示例:
import std.math.trunc
main() {
let x: Float64 = 64.555566
let trunc = trunc(x)
println(trunc)
}
运行结果:
64.000000
枚举
enum RoundingMode
public enum RoundingMode <: Equatable<RoundingMode> & ToString {
| Ceiling
| Down
| Floor
| HalfEven
| HalfUp
| Up
}
功能:舍入规则枚举类,共包含 6 种舍入规则。除包含 IEEE 754 浮点数规定约定的 5 种舍入规则外,提供使用较多的 “四舍五入” 舍入规则。
| 十进制数 | Up | Down | Ceiling | Floor | HalfUp | HalfEven |
|---|---|---|---|---|---|---|
| 7.5 | 8 | 7 | 8 | 7 | 8 | 8 |
| 4.5 | 5 | 4 | 5 | 4 | 5 | 4 |
| -1.1 | -2 | -1 | -1 | -2 | -1 | -1 |
| -4.5 | -5 | -4 | -4 | -5 | -5 | -4 |
| -7.5 | -8 | -7 | -7 | -8 | -8 | -8 |
父类型:
Ceiling
Ceiling
功能:向正无穷方向舍入。
Down
Down
功能:向靠近零的方向舍入。
Floor
Floor
功能:向负无穷方向舍入。
HalfEven
HalfEven
功能:四舍六入五取偶,又称 “银行家舍入”。
HalfUp
HalfUp
功能:四舍五入。
Up
Up
功能:向远离零的方向舍入。
func toString()
public func toString(): String
功能:生成舍入规则名称字符串。
返回值:
- String - 舍入规则名称字符串。
operator func ==(RoundingMode)
public operator func ==(that: RoundingMode): Bool
功能:判等。
参数:
- that: RoundingMode - 被比较的舍入规则。
返回值:
- Bool - 若舍入规则相同,返回 true;否则,返回 false。
数学基础运算示例
import std.math.clamp
import std.math.gcd
import std.math.lcm
import std.math.rotate
// 范围截断示例
func clampTest() {
let min: Float16 = -0.123
let max: Float16 = 0.123
let v: Float16 = 0.121
let c = clamp(v, min, max)
println("${c==v}")
let min2: Float16 = -0.999
let max2: Float16 = 10.123
let v2: Float16 = 11.121
let c2 = clamp(v2, min2, max2)
println("${c2==max2}")
let min3: Float16 = -0.999
let max3: Float16 = 10.123
let v3: Float16 = -1.121
let c3 = clamp(v3, min3, max3)
println("${c3==min3}")
}
// 求两个数的最大公约数
func gcdTest() {
let c2 = gcd(0, -60)
println("c2=${c2}")
let c4 = gcd(-33, 27)
println("c4=${c4}")
}
// 求两个数的最小公倍数
func lcmTest() {
let a: Int8 = lcm(Int8(-3), Int8(5))
println("a=${a}")
}
// 整数按二进制某一位前后翻转
func rotateTest() {
let a: Int8 = rotate(Int8(92), Int8(4))
println("a=${a}")
let b: Int32 = rotate(Int32(1), Int8(4))
println("b=${b}")
}
main(): Unit {
println("/*********************** clampTest **********************/")
clampTest()
println("/*********************** gcdTest ************************/")
gcdTest()
println("/*********************** lcmTest ************************/")
lcmTest()
println("/*********************** rotateTest *********************/")
rotateTest()
}
运行结果:
/*********************** clampTest **********************/
true
true
true
/*********************** gcdTest ************************/
c2=60
c4=3
/*********************** lcmTest ************************/
a=15
/*********************** rotateTest *********************/
a=-59
b=16
std.math.numeric
功能介绍
math.numeric 包对基础类型可表达范围之外提供扩展能力。
例如:
- 支持大整数(BigInt);
- 支持高精度十进制数(Decimal)类型;
- 提供常见的数学运算能力包括高精度运算规则。
API 列表
函数
| 函数名 | 功能 |
|---|---|
| abs(BigInt) | 求一个 BigInt 的绝对值。 |
| abs(Decimal) | 求一个 Decimal 的绝对值。 |
| countOne(BigInt) (deprecated) | 计算并返回入参 BigInt 的二进制补码中 1 的个数。 |
| countOnes(BigInt) | 计算并返回入参 BigInt 的二进制补码中 1 的个数。 |
| gcd(BigInt, BigInt) | 求两个 BigInt 的最大公约数。总是返回非负数(相当于绝对值的最大公约数)。 |
| lcm(BigInt, BigInt) | 求两个 BigInt 的最小公倍数。除了入参有 0 时返回 0 外,总是返回正数(相当于绝对值的最小公倍数)。 |
| round(Decimal, RoundingMode) | 计算 Decimal 的舍入值,根据舍入方式向邻近的整数舍入。 |
| sqrt(BigInt) | 求 BigInt 的算术平方根,向下取整。 |
| sqrt(Decimal) | 求 Decimal 的算术平方根。结果为无限小数场景时,默认采用 IEEE 754-2019 decimal128 对结果进行舍入。 |
| trailingZeros(BigInt) | 求 BigInt 的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。 |
枚举
| 枚举 | 功能 |
|---|---|
| OverflowStrategy | 溢出策略枚举类,共包含 3 种溢出策略。BigInt 类型、Decimal 类型转换为整数类型时,允许指定不同的溢出处理策略。 |
结构体
| 结构体 | 功能 |
|---|---|
| BigInt | BigInt 定义为任意精度(二进制)的有符号整数。仓颉的 struct BigInt 用于任意精度有符号整数的计算,类型转换等。 |
| Decimal | Decimal 用于表示任意精度的有符号的十进制数。允许操作过程指定上下文,指定结果精度及舍入规则。提供基础类型 (Int、UInt、String、Float等) 与 BigInt 类型互相转换能力,支持 Decimal 对象基本属性查询等能力,支持基础数学运算操作,提供对象比较、hash、字符串打印等基础能力。 |
函数
func abs(BigInt)
public func abs(i: BigInt): BigInt
功能:求一个 BigInt 的绝对值。
参数:
返回值:
示例:
import std.math.numeric.*
main() {
let n: BigInt = BigInt(-23)
let abs = abs(n)
println(abs)
}
运行结果:
23
func abs(Decimal)
public func abs(d: Decimal): Decimal
功能:求一个 Decimal 的绝对值。
参数:
返回值:
示例:
import std.math.numeric.*
main() {
let d: Decimal = Decimal.parse("-1.23")
let abs = abs(d)
println(abs)
}
运行结果:
1.23
func countOne(BigInt) (deprecated)
public func countOne(i: BigInt): Int64
功能:计算并返回入参 BigInt 的二进制补码中 1 的个数。
注意:
未来版本即将废弃,使用 countOnes(BigInt) 替代。
参数:
返回值:
func countOnes(BigInt)
public func countOnes(i: BigInt): Int64
功能:计算并返回入参 BigInt 的二进制补码中 1 的个数。
参数:
返回值:
示例:
import std.math.numeric.*
main() {
let i: BigInt = BigInt(255)
let countOnes = countOnes(i)
println(countOnes)
}
运行结果:
8
func gcd(BigInt, BigInt)
public func gcd(i1: BigInt, i2: BigInt): BigInt
功能:求两个 BigInt 的最大公约数。总是返回非负数(相当于绝对值的最大公约数)。
参数:
返回值:
- BigInt - 返回
i1和i2的最大公约数,总是返回非负数。
示例:
import std.math.numeric.*
main() {
let i1: BigInt = BigInt(-36)
let i2: BigInt = BigInt(48)
let gcd = gcd(i1, i2)
println(gcd)
}
运行结果:
12
func lcm(BigInt, BigInt)
public func lcm(i1: BigInt, i2: BigInt): BigInt
功能:求两个 BigInt 的最小公倍数。除了入参有 0 时返回 0 外,总是返回正数(相当于绝对值的最小公倍数)。
参数:
返回值:
- BigInt - 返回
i1和i2的最小公倍数,当入参有 0 时返回 0,其余情况返回正数。
示例:
import std.math.numeric.*
main() {
let i1: BigInt = BigInt(-36)
let i2: BigInt = BigInt(48)
let lcm = lcm(i1, i2)
println(lcm)
}
运行结果:
144
func round(Decimal, RoundingMode)
public func round(d: Decimal, roundingMode!: RoundingMode = RoundingMode.HalfEven): Decimal
功能:计算 Decimal 的舍入值,根据舍入方式向邻近的整数舍入。
参数:
- d: Decimal - 需要计算舍入值的 Decimal。
- roundingMode!: RoundingMode - 舍入规则。
返回值:
异常:
- OverflowException - 当舍入操作结果标度值溢出时,抛出此异常。
func sqrt(BigInt)
public func sqrt(i: BigInt): BigInt
功能:求 BigInt 的算术平方根,向下取整。
参数:
返回值:
异常:
- IllegalArgumentException - 如果入参为负数,则抛此异常。
示例:
import std.math.numeric.*
main() {
let n: BigInt = BigInt(23)
let sqrt = sqrt(n)
println(sqrt)
}
运行结果:
4
func sqrt(Decimal)
public func sqrt(d: Decimal): Decimal
功能:求 Decimal 的算术平方根。结果为无限小数场景时,默认采用 IEEE 754-2019 decimal128 对结果进行舍入。
参数:
返回值:
异常:
- IllegalArgumentException - 如果入参为负数,则抛此异常。
- OverflowException - 当计算平方根操作结果标度值溢出时,抛出此异常。
示例:
import std.math.numeric.*
main() {
let n: Decimal = Decimal.parse("36")
let sqrt = sqrt(n)
println(sqrt)
}
运行结果:
6
func trailingZeros(BigInt)
public func trailingZeros(x: BigInt): Int64
功能:求 BigInt 的二进制表达中的从最低位算起,连续位为 0 的个数。如果最低位不是 0,则返回 0。
参数:
返回值:
- Int64 - 后置 0 的位数。
示例:
import std.math.numeric.{BigInt, trailingZeros}
main() {
let x: BigInt = BigInt(0xC000_0000)
let trailingZeros = trailingZeros(x)
println(trailingZeros)
}
运行结果:
30
枚举
enum OverflowStrategy
public enum OverflowStrategy <: Equatable<OverflowStrategy> & ToString {
| Saturating
| Throwing
| Wrapping
}
功能:溢出策略枚举类,共包含 3 种溢出策略。BigInt 类型、Decimal 类型转换为整数类型时,允许指定不同的溢出处理策略。
父类型:
Saturating
Saturating
功能:出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
Throwing
Throwing
功能:出现溢出,抛出异常。
Wrapping
Wrapping
功能:出现溢出,高位截断。
func toString()
public func toString(): String
功能:生成溢出策略名称字符串。
返回值:
- String - 溢出策略名称字符串。
operator func ==(OverflowStrategy)
public operator func ==(that: OverflowStrategy): Bool
功能:判等。
参数:
- that: OverflowStrategy - 被比较的溢出策略。
返回值:
- Bool - 溢出策略相同,返回 true;否则,返回 false。
结构体
struct BigInt
public struct BigInt <: Comparable<BigInt> & Hashable & ToString {
public init(bytes: Array<Byte>)
public init(sign: Bool, magnitude: Array<Byte>)
public init(n: Int8)
public init(n: Int16)
public init(n: Int32)
public init(n: Int64)
public init(n: UInt8)
public init(n: UInt16)
public init(n: UInt32)
public init(n: UInt64)
public init(n: UIntNative)
public init(n: IntNative)
public init(n: Float16)
public init(n: Float32)
public init(n: Float64)
public init(sign: Bool, bitLen: Int64, rand!: Random = Random())
public init(s: String, base!: Int64 = 10)
}
功能:BigInt 定义为任意精度(二进制)的有符号整数。仓颉的 struct BigInt 用于任意精度有符号整数的计算,类型转换等。
父类型:
prop bitLen
public prop bitLen: Int64
功能:获取此 BigInt 的最短 bit 长度。如 -3 (101) 返回 3,-1 (11) 返回 2,0 (0) 返回 1。
类型:Int64
示例:
import std.math.numeric.BigInt
main() {
let bigInt1 = BigInt(-3)
let bitLen1 = bigInt1.bitLen
println(bitLen1)
let bigInt2 = BigInt(-1)
let bitLen2 = bigInt2.bitLen
println(bitLen2)
let bigInt3 = BigInt(0)
let bitLen3 = bigInt3.bitLen
println(bitLen3)
}
运行结果:
3
2
1
prop sign
public prop sign: Int64
功能:获取此 BigInt 的符号。正数返回 1;0 返回 0;负数返回 -1。
类型:Int64
示例:
import std.math.numeric.BigInt
main() {
let bigInt1 = BigInt(-3)
let sign1 = bigInt1.sign
println(sign1)
let bigInt2 = BigInt(3)
let sign2 = bigInt2.sign
println(sign2)
let bigInt3 = BigInt(0)
let sign3 = bigInt3.sign
println(sign3)
}
运行结果:
-1
1
0
init(Array<Byte>)
public init(bytes: Array<Byte>)
功能:通过大端的 Byte 数组以补码形式构建一个 BigInt 结构体。
数据存储方法有以下两种:
-
大端存储方式:高位字节存放在低位地址。
-
小端存储方式:将数据的低位字节存放在内存的高位地址。
参数:
异常:
- IllegalArgumentException - 当传入空数组时,抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt([1, 2, 3])
println(bigInt)
}
运行结果:
66051
init(Bool, Array<Byte>)
public init(sign: Bool, magnitude: Array<Byte>)
功能:通过符号位和真值的绝对值构建一个 BigInt 结构体。视空数组为 0。
参数:
异常:
- IllegalArgumentException - 当
sign为 false 且传入的数组为 0 时,抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(false, [1, 2, 3])
println(bigInt)
}
运行结果:
-66051
init(Bool, Int64, Random)
public init(sign: Bool, bitLen: Int64, rand!: Random = Random())
功能:通过指定正负、bit 长度和随机数种子构建一个随机的 BigInt 结构体。bit 长度需要大于 0。
参数:
异常:
- IllegalArgumentException - 如果指定的 bit 长度小于等于 0,则抛此异常。
示例:
import std.math.numeric.BigInt
import std.random.*
main() {
let random = Random(2)
let bigInt = BigInt(false, 3, rand: random)
println(bigInt)
}
运行结果:
-4
init(Float16)
public init(n: Float16)
功能:通过半精度浮点数构建一个 BigInt 结构体。
将丢弃浮点数的小数部分,即向零取整。
参数:
- n: Float16 - 半精度浮点数。
异常:
- IllegalArgumentException - 如果 n 为
Inf或NaN,则抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let float16: Float16 = 24.8
let bigInt = BigInt(float16)
println(bigInt)
}
运行结果:
24
init(Float32)
public init(n: Float32)
功能:通过单精度浮点数构建一个 BigInt 结构体。
将丢弃浮点数的小数部分,即向零取整。
参数:
- n: Float32 - 单精度浮点数。
异常:
- IllegalArgumentException - 如果 n 为
Inf或NaN,则抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let float32: Float32 = 24.8
let bigInt = BigInt(float32)
println(bigInt)
}
运行结果:
24
init(Float64)
public init(n: Float64)
功能:通过双精度浮点数构建一个 BigInt 结构体。
将丢弃浮点数的小数部分,即向零取整。
参数:
- n: Float64 - 单精度浮点数。
异常:
- IllegalArgumentException - 如果 n 为
Inf或NaN,则抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let float64: Float64 = 24.8
let bigInt = BigInt(float64)
println(bigInt)
}
运行结果:
24
init(Int16)
public init(n: Int16)
功能:通过 16 位有符号整数构建一个 BigInt 结构体。
参数:
- n: Int16 - 16 位有符号整数。
示例:
import std.math.numeric.BigInt
main() {
let int16: Int16 = 24
let bigInt = BigInt(int16)
println(bigInt)
}
运行结果:
24
init(Int32)
public init(n: Int32)
功能:通过 32 位有符号整数构建一个 BigInt 结构体。
参数:
- n: Int32 - 32 位有符号整数。
示例:
import std.math.numeric.BigInt
main() {
let int32: Int32 = 24
let bigInt = BigInt(int32)
println(bigInt)
}
运行结果:
24
init(Int64)
public init(n: Int64)
功能:通过 64 位有符号整数构建一个 BigInt 结构体。
参数:
- n: Int64 - 64 位有符号整数。
示例:
import std.math.numeric.BigInt
main() {
let int64: Int64 = 24
let bigInt = BigInt(int64)
println(bigInt)
}
运行结果:
24
init(Int8)
public init(n: Int8)
功能:通过 8 位有符号整数构建一个 BigInt 结构体。
参数:
- n: Int8 - 8 位有符号整数。
示例:
import std.math.numeric.BigInt
main() {
let int8: Int8 = 24
let bigInt = BigInt(int8)
println(bigInt)
}
运行结果:
24
init(IntNative)
public init(n: IntNative)
功能:通过平台相关有符号整数构建一个 BigInt 结构体。
参数:
- n: IntNative - 平台相关有符号整数。
示例:
import std.math.numeric.BigInt
main() {
let intNative: IntNative = 24
let bigInt = BigInt(intNative)
println(bigInt)
}
运行结果:
24
init(String, Int64) (deprecated)
public init(s: String, base!: Int64 = 10)
功能:通过字符串和进制构建一个 BigInt 结构体,支持 2 进制到 36 进制。
字符串的规则如下,即开头是可选的符号(正号或负号),接一串字符串表示的数字:
IntegerString : (SignString)? ValueString
-
SignString : + | -
-
ValueString : Digits
-
Digits: Digit | Digit Digits
-
Digit : '0' ~ '9' | 'A' ~ 'Z' | 'a' ~ 'z'
-
如果 Digit 在 '0' ~ '9' 内, 需要满足 (Digit - '0') < base;
-
如果 Digit 在 'A' ~ 'Z' 内, 需要满足 (Digit - 'A') + 10 < base;
-
如果 Digit 在 'a' ~ 'z' 内, 需要满足 (Digit - 'A') + 10 < base。
-
-
-
注意:
未来版本即将废弃,使用 parse(String, Int) 替代。
参数:
- s: String - 用于构建 BigInt 结构体的字符串。字符串规则为,开头可选一个正号(+)或者负号(-)。接下来必选非空阿拉伯数字或大小写拉丁字母的字符序列,大小写字符含义一样,'a' 和 'A' 的大小等于十进制的 10,'b' 和 'B' 的大小等于十进制的 11,以此类推。序列中的字符大小不得大于等于进制大小。
- base!: Int64 - 进制。字符串所表示的进制,范围为 [2, 36]。
异常:
- IllegalArgumentException - 如果字符串
s不符合上述规则,或base表示的进制不在 [2, 36] 区间内,抛此异常。
init(UInt16)
public init(n: UInt16)
功能:通过 16 位无符号整数构建一个 BigInt 结构体。
参数:
- n: UInt16 - 16 位无符号整数。
示例:
import std.math.numeric.BigInt
main() {
let uint16: UInt16 = 24
let bigInt = BigInt(uint16)
println(bigInt)
}
运行结果:
24
init(UInt32)
public init(n: UInt32)
功能:通过 32 位无符号整数构建一个 BigInt 结构体。
参数:
- n: UInt32 - 32 位无符号整数。
示例:
import std.math.numeric.BigInt
main() {
let uint32: UInt32 = 24
let bigInt = BigInt(uint32)
println(bigInt)
}
运行结果:
24
init(UInt64)
public init(n: UInt64)
功能:通过 64 位无符号整数构建一个 BigInt 结构体。
参数:
- n: UInt64 - 64 位无符号整数。
示例:
import std.math.numeric.BigInt
main() {
let uint64: UInt64 = 24
let bigInt = BigInt(uint64)
println(bigInt)
}
运行结果:
24
init(UInt8)
public init(n: UInt8)
功能:通过 8 位无符号整数构建一个 BigInt 结构体。
参数:
- n: UInt8 - 8 位无符号整数。
示例:
import std.math.numeric.BigInt
main() {
let uint8: UInt8 = 24
let bigInt = BigInt(uint8)
println(bigInt)
}
运行结果:
24
init(UIntNative)
public init(n: UIntNative)
功能:通过平台相关无符号整数构建一个 BigInt 结构体。
参数:
- n: UIntNative - 平台相关无符号整数。
示例:
import std.math.numeric.BigInt
main() {
let uintnative: UIntNative = 24
let bigInt = BigInt(uintnative)
println(bigInt)
}
运行结果:
24
static func randomProbablePrime(Int64, UInt64, Random)
public static func randomProbablePrime(bitLen: Int64, certainty: UInt64, rand!: Random = Random()): BigInt
功能:通过可选的随机数种子构建一个随机的 BigInt 素数,素数的 bit 长度不超过入参 bitLen。
显然,素数必定是大于等于 2 的整数,因此 bitLen 必须大于等于 2。素数检测使用 Miller-Rabin 素数测试算法。Miller-Rabin 测试会有概率将一个合数判定为素数,其出错概率随着入参 certainty 的增加而减少。
参数:
- bitLen: Int64 - 所要生成的随机素数的 bit 长度的上限。
- certainty: UInt64 - 生成的随机素数通过 Miller-Rabin 素数测试算法的次数,通过的次数越多,将合数误判为素数的概率越低。
- rand!: Random - 指定的随机数种子。
返回值:
- BigInt - 返回生成的随机素数。
异常:
- IllegalArgumentException - 如果指定的 bit 长度小于等于 1,则抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let randomProbablePrime = BigInt.randomProbablePrime(6, 3)
println(randomProbablePrime)
}
func clearBit(Int64)
public func clearBit(index: Int64): BigInt
功能:通过将指定索引位置的 bit 修改为 0 来构造一个新 BigInt。
参数:
- index: Int64 - 需要设置的 bit 位置的索引。
index需要大于等于 0。
返回值:
异常:
- IllegalArgumentException - 如果入参
index小于 0,则抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1024)
let clearBit = bigInt.clearBit(10)
println(clearBit)
}
运行结果:
0
func compare(BigInt)
public func compare(that: BigInt): Ordering
参数:
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1024)
let that1 = BigInt(512)
let that2 = BigInt(2048)
let that3 = BigInt(1024)
let compare1 = bigInt.compare(that1)
println(compare1)
let compare2 = bigInt.compare(that2)
println(compare2)
let compare3 = bigInt.compare(that3)
println(compare3)
}
运行结果:
Ordering.GT
Ordering.LT
Ordering.EQ
func divAndMod(BigInt)
public func divAndMod(that: BigInt): (BigInt, BigInt)
功能:BigInt 的除法运算。
与另一个 BigInt 相除,返回商和模。此除法运算的行为与基础类型保持一致,即商向靠近 0 的方向取整,模的符号与被除数保持一致。
参数:
- that: BigInt - 除数。除数不得为 0。
返回值:
异常:
- ArithmeticException - 除数为 0 抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1025)
let that = BigInt(512)
let (div, mod) = bigInt.divAndMod(that)
println(div)
println(mod)
}
运行结果:
2
1
func flipBit(Int64)
public func flipBit(index: Int64): BigInt
功能:通过翻转指定索引位置的 bit 来构造一个新 BigInt。
参数:
- index: Int64 - 需要翻转的 bit 位置的索引。
index需要大于等于 0。
返回值:
异常:
- IllegalArgumentException - 如果入参
index小于 0,则抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1024)
let flipBit = bigInt.flipBit(10)
println(flipBit)
}
运行结果:
0
func hashCode()
public func hashCode(): Int64
功能:计算并返回此 BigInt 的哈希值。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1024)
let hashCode = bigInt.hashCode()
println(hashCode)
}
运行结果:
1024
func isProbablePrime(UInt64)
public func isProbablePrime(certainty: UInt64): Bool
功能:判断一个数是不是素数。
说明:
该函数使用了 Miller-Rabin 测试算法,此算法的准确率会随着 certainty 参数的增加而增加。如果该数是素数,那么 Miller-Rabin 测试必定返回 true;如果该数是合数(期待返回 false),那么会有低于 1/4certainty 概率返回 true。素数只对大于等于 2 的正整数有意义,即负数,0,1 都不是素数。
参数:
- certainty: UInt64 - 需要执行 Miller-Rabin 测试的次数。注意,如果测试次数为 0,表示不测试,那么总是返回 true(即不是素数的数也必定返回 true)。
返回值:
- Bool - 如果使用此函数测定了一个数为素数,则返回 true;不为素数,则返回 false。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1024)
let isProbablePrime = bigInt.isProbablePrime(10)
println(isProbablePrime)
}
运行结果:
false
func lowestOneBit() (deprecated)
public func lowestOneBit(): Int64
功能:判断为 1 的最低位的 bit 的位置。
注意:
未来版本即将废弃,使用 trailingZeros(BigInt) 替代。
返回值:
- Int64 - 返回为 1 的最低位的 bit 的位置。如果 bit 全为 0,则返回 -1。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(-1)
let lowestOneBit = bigInt.lowestOneBit()
println(lowestOneBit)
}
运行结果:
0
func modInverse(BigInt)
public func modInverse(that: BigInt): BigInt
功能:求模逆元。
模逆元 r 满足 $(this * r) % that == 1$。显然,this 和 that 必须互质。当 that 为 正负 1 时,结果总是 0。
参数:
返回值:
- BigInt - 返回模逆元。
异常:
- IllegalArgumentException - 当
this和that不互质或that为 0 时,抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1025)
let that = BigInt(512)
let modInverse = bigInt.modInverse(that)
println(modInverse)
}
运行结果:
1
func modPow(BigInt, ?BigInt)
public func modPow(n: BigInt, m!: ?BigInt = None): BigInt
功能:计算此 BigInt 的 n 次幂模 m 的结果,并返回。
模的规则与基础类型一致,即模的符号与被除数保持一致。
参数:
返回值:
- BigInt - 乘方后取模的运算结果。
异常:
- ArithmeticException - 除数为 0 抛此异常。
- IllegalArgumentException - 指数为负数时抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(2)
let n = BigInt(10)
let modPow = bigInt.modPow(n)
println(modPow)
}
运行结果:
1024
func quo(BigInt) (deprecated)
public func quo(that: BigInt): BigInt
功能:BigInt 的除法运算。
与另一个 BigInt 相除,返回结果。此除法运算的行为与运算符重载函数区别于,如果被除数为负数,此函数的结果向着远离 0 的方向取整,保证余数大于等于 0。
注意:
未来版本即将废弃。
参数:
- that: BigInt - 除数。除数不得为 0。
返回值:
异常:
- ArithmeticException - 除数为 0 抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1025)
let that = BigInt(512)
let quo = bigInt.quo(that)
println(quo)
}
运行结果:
2
func quoAndRem(BigInt) (deprecated)
public func quoAndRem(that: BigInt): (BigInt, BigInt)
功能:BigInt 的除法运算。
与另一个 BigInt 相除,返回商和余数。此除法运算的行为与 divAndMod 函数区别于,如果被除数为负数,此函数的结果向着远离 0 的方向取整,保证余数总是大于等于 0。
注意:
未来版本即将废弃。
参数:
- that: BigInt - 除数。除数不得为 0。
返回值:
异常:
- ArithmeticException - 除数为 0 抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1025)
let that = BigInt(512)
let (quo, rem) = bigInt.quoAndRem(that)
println(quo)
println(rem)
}
运行结果:
2
1
func rem(BigInt) (deprecated)
public func rem(that: BigInt): BigInt
功能:BigInt 的模运算。
与另一个 BigInt 相除,返回余数。余数的结果总是大于等于 0。
注意:
未来版本即将废弃。
参数:
- that: BigInt - 除数。除数不得为 0。
返回值:
异常:
- ArithmeticException - 除数为 0 抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(1025)
let that = BigInt(512)
let rem = bigInt.rem(that)
println(rem)
}
运行结果:
1
func setBit(Int64)
public func setBit(index: Int64): BigInt
功能:通过将指定索引位置的 bit 修改为 1 来构造一个新 BigInt。
参数:
- index: Int64 - 需要设置的 bit 位置的索引。
index需要大于等于 0。
返回值:
异常:
- IllegalArgumentException - 如果入参
index小于 0,则抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(0)
let setBit = bigInt.setBit(10)
println(setBit)
}
运行结果:
1024
func testBit(Int64)
public func testBit(index: Int64): Bool
功能:判断指定位置的 bit 信息,如果指定位置的 bit 为 0,则返回 false;为 1,则返回 true。
参数:
- index: Int64 - 需要知道的 bit 的索引。
index需要大于等于 0。
返回值:
- Bool - 指定位置的 bit 信息。
异常:
- IllegalArgumentException - 如果入参
index小于 0,则抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(-1)
let testBit = bigInt.testBit(100)
println(testBit)
}
运行结果:
true
func toBytes()
public func toBytes(): Array<Byte>
功能:计算并返回此 BigInt 的大端补码字节数组。
字节数组最低索引的最低位为符号位,如 128 返回 [0, 128](符号位为 0),-128 返回 [128](符号位为 1)。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(0x400)
let toBytes = bigInt.toBytes()
println(toBytes)
}
运行结果:
[4, 0]
func toFloat16()
public func toFloat16(): Float16
功能:将当前 BigInt 对象转化为 Float16 类型。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(32)
let toFloat16 = bigInt.toFloat16()
println(toFloat16)
}
运行结果:
32.000000
func toFloat32()
public func toFloat32(): Float32
功能:将当前 BigInt 对象转化为 Float32 类型。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(32)
let toFloat32 = bigInt.toFloat32()
println(toFloat32)
}
运行结果:
32.000000
func toFloat64()
public func toFloat64(): Float64
功能:将当前 BigInt 对象转化为 Float64 类型。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(32)
let toFloat64 = bigInt.toFloat64()
println(toFloat64)
}
运行结果:
32.000000
func toInt16(OverflowStrategy)
public func toInt16(overflowHandling!: OverflowStrategy = Throwing): Int16
功能:将当前 BigInt 对象转化为 Int16 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt(0x8000_0000_0000)
let toInt16 = bigInt.toInt16(overflowHandling: Saturating)
println(toInt16)
}
运行结果:
32767
func toInt32(OverflowStrategy)
public func toInt32(overflowHandling!: OverflowStrategy = Throwing): Int32
功能:将当前 BigInt 对象转化为 Int32 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt(0x8000_0000_00FF)
let toInt32 = bigInt.toInt32(overflowHandling: Wrapping)
println(toInt32)
}
运行结果:
255
func toInt64(OverflowStrategy)
public func toInt64(overflowHandling!: OverflowStrategy = Throwing): Int64
功能:将当前 BigInt 对象转化为 Int64 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt.parse("800000000000000000", radix: 16)
let toInt64 = bigInt.toInt64(overflowHandling: Wrapping)
println(toInt64)
}
运行结果:
0
func toInt8(OverflowStrategy)
public func toInt8(overflowHandling!: OverflowStrategy = Throwing): Int8
功能:将当前 BigInt 对象转化为 Int8 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "Throwing":异常模式。出现溢出抛出异常。
- "Wrapping":溢出模式。出现溢出高位截断。
- "Saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt(1024)
let toInt8 = bigInt.toInt8(overflowHandling: Saturating)
println(toInt8)
}
运行结果:
127
func toIntNative(OverflowStrategy)
public func toIntNative(overflowHandling!: OverflowStrategy = Throwing): IntNative
功能:将当前 BigInt 对象转化为 IntNative 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt.parse("800000000000000000", radix: 16)
let toIntNative = bigInt.toIntNative(overflowHandling: Wrapping)
println(toIntNative)
}
运行结果:
0
func toString()
public func toString(): String
功能:计算并返回此 BigInt 的十进制字符串表示。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(0x400)
let toString = bigInt.toString()
println(toString)
}
运行结果:
1024
func toUInt16(OverflowStrategy)
public func toUInt16(overflowHandling!: OverflowStrategy = Throwing): UInt16
功能:将当前 BigInt 对象转化为 UInt16 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt.parse("800000000000000000", radix: 16)
let toUInt16 = bigInt.toUInt16(overflowHandling: Wrapping)
println(toUInt16)
}
运行结果:
0
func toUInt32(OverflowStrategy)
public func toUInt32(overflowHandling!: OverflowStrategy = Throwing): UInt32
功能:将当前 BigInt 对象转化为 UInt32 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt.parse("800000000000000000", radix: 16)
let toUInt32 = bigInt.toUInt32(overflowHandling: Wrapping)
println(toUInt32)
}
运行结果:
0
func toUInt64(OverflowStrategy)
public func toUInt64(overflowHandling!: OverflowStrategy = Throwing): UInt64
功能:将当前 BigInt 对象转化为 UInt64 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt.parse("-800000000000000000", radix: 16)
let toUInt64 = bigInt.toUInt64(overflowHandling: Saturating)
println(toUInt64)
}
运行结果:
0
func toUInt8(OverflowStrategy)
public func toUInt8(overflowHandling!: OverflowStrategy = Throwing): UInt8
功能:将当前 BigInt 对象转化为 UInt8 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt.parse("800000000000000000", radix: 16)
try {
bigInt.toUInt8(overflowHandling: Throwing)
} catch (e: OverflowException) {
println(e.message)
}
return
}
运行结果:
Out of range of the UInt8.
func toUIntNative(OverflowStrategy)
public func toUIntNative(overflowHandling!: OverflowStrategy = Throwing): UIntNative
功能:将当前 BigInt 对象转化为 UIntNative 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
- "throwing":异常模式。出现溢出抛出异常。
- "wrapping":溢出模式。出现溢出高位截断。
- "saturating":边界值模式。出现溢出,当前值大于目标类型的 MAX 值,返回目标类型 MAX 值,当前值小于目标类型的 MIN 值,返回目标类型 MIN 值。
返回值:
- UIntNative - 返回转换后的 UInt64 值。
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.BigInt
import std.math.numeric.OverflowStrategy
main() {
let bigInt = BigInt.parse("-800000000000000000", radix: 16)
let toUIntNative = bigInt.toUIntNative(overflowHandling: Saturating)
println(toUIntNative)
}
运行结果:
0
operator func !()
public operator func !(): BigInt
功能:按位非。将操作数中的二进制位 0 变 1,1 变 0。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let no = !bigInt
println(no)
}
运行结果:
0
operator func !=(BigInt)
public operator func !=(that: BigInt): Bool
功能:判不等运算。
参数:
返回值:
- Bool - 判不等的结果。不等返回 true,相等返回 false。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let that = BigInt.parse("-2")
println(bigInt != that)
}
运行结果:
true
operator func %(BigInt)
public operator func %(that: BigInt): BigInt
功能:BigInt 的模运算。
取模运算的行为与基础类型保持一致,即符号与被除数保持一致。
参数:
- that: BigInt - 除数。除数不得为 0。
返回值:
异常:
- ArithmeticException - 除数为 0 抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-23456789123456789")
let that = BigInt.parse("-23456789123456789")
let mod = bigInt % that
println(mod)
}
运行结果:
0
operator func &(BigInt)
public operator func &(that: BigInt): BigInt
功能:按位与。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位都为 1 时,结果位才为 1。
参数:
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("8")
let that = BigInt.parse("7")
let and = bigInt & that
println(and)
}
运行结果:
0
operator func *(BigInt)
public operator func *(that: BigInt): BigInt
功能:BigInt 乘法。
参数:
- that: BigInt - 乘数。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let that = BigInt.parse("-23456789123456789")
let mul = bigInt * that
println(mul)
}
运行结果:
23456789123456789
operator func **(UInt64)
public operator func **(n: UInt64): BigInt
功能:求 BigInt 的 n 次幂。
参数:
- n: UInt64 - 指数。
返回值:
- BigInt - 幂运算结果。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-2")
let power = bigInt ** 64
println(power.toString(radix: 16))
}
运行结果:
10000000000000000
operator func +(BigInt)
public operator func +(that: BigInt): BigInt
功能:BigInt 加法。
参数:
- that: BigInt - 加数。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("123456789123456789")
let that = BigInt.parse("-23456789123456789")
let plus = bigInt + that
println(plus)
}
运行结果:
100000000000000000
operator func -()
public operator func -(): BigInt
功能:求 BigInt 的相反数。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-23456789123456789")
let opposite = -bigInt
println(opposite)
}
运行结果:
23456789123456789
operator func -(BigInt)
public operator func -(that: BigInt): BigInt
功能:BigInt 减法。
参数:
- that: BigInt - 减数。
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("100000000000000000")
let that = BigInt.parse("-23456789123456789")
let sub = bigInt - that
println(sub)
}
运行结果:
123456789123456789
operator func <(BigInt)
public operator func <(that: BigInt): Bool
功能:小于比较运算。
参数:
返回值:
- Bool - 比较的结果。小于返回 true,否则返回 false。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let that = BigInt.parse("-2")
println(bigInt < that)
}
运行结果:
false
operator func <<(Int64)
public operator func <<(n: Int64): BigInt
功能:左移运算。
参数:
- n: Int64 - 左移 n 位,n 需要大于等于 0。
返回值:
异常:
- ArithmeticException - 入参小于 0 时抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let leftShift = bigInt << 64
println(leftShift.toString(radix: 16))
}
运行结果:
-10000000000000000
operator func <=(BigInt)
public operator func <=(that: BigInt): Bool
功能:小于等于比较运算。
参数:
返回值:
- Bool - 比较的结果。小于等于返回 true,否则返回 false。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let that = BigInt.parse("-2")
println(bigInt <= that)
}
运行结果:
false
operator func ==(BigInt)
public operator func ==(that: BigInt): Bool
功能:判等运算。
参数:
返回值:
- Bool - 判等的结果。相等返回 true,不等返回 false。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let that = BigInt.parse("-2")
println(bigInt == that)
}
运行结果:
false
operator func >(BigInt)
public operator func >(that: BigInt): Bool
功能:大于比较运算。
参数:
返回值:
- Bool - 比较的结果。大于返回 true,否则返回 false。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let that = BigInt.parse("-2")
println(bigInt > that)
}
运行结果:
true
operator func >=(BigInt)
public operator func >=(that: BigInt): Bool
功能:大于等于比较运算。
参数:
返回值:
- Bool - 比较的结果。大于等于返回 true,否则返回 false。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let that = BigInt.parse("-2")
println(bigInt >= that)
}
运行结果:
true
operator func >>(Int64)
public operator func >>(n: Int64): BigInt
功能:右移运算。
参数:
- n: Int64 - 右移 n 位,n 需要大于等于 0。
返回值:
异常:
- ArithmeticException - 入参小于 0 时抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let rightShift = bigInt >> 10000
println(rightShift)
}
运行结果:
-1
operator func /(BigInt)
public operator func /(that: BigInt): BigInt
功能:BigInt 除法。
除法运算的行为与基础类型保持一致,即结果向靠近 0 的方向取整。
参数:
- that: BigInt - 除数。除数不得为 0。
返回值:
异常:
- ArithmeticException - 除数为 0 抛此异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-23456789123456789")
let that = BigInt.parse("-23456789123456789")
let div = bigInt / that
println(div)
}
运行结果:
1
operator func ^(BigInt)
public operator func ^(that: BigInt): BigInt
功能:按位异或。其功能是参与运算的两数各对应的二进位相异或。二进制位结果不相同时,异或结果为 1;二进制位结果相同时,异或结果为 0。
参数:
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("-1")
let that = BigInt.parse("7")
let xor = bigInt ^ that
println(xor)
}
运行结果:
-8
operator func |(BigInt)
public operator func |(that: BigInt): BigInt
功能:按位或。其功能是参与运算的两数各对应的二进位相或。只有对应的两个二进位都为 0 时,结果位才为 0。
参数:
返回值:
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt.parse("8")
let that = BigInt.parse("7")
let or = bigInt | that
println(or)
}
运行结果:
15
extend BigInt <: Integer<BigInt>
extend BigInt <: Integer<BigInt>
功能:为 BigInt 类型扩展 Integer<T> 接口。
父类型:
static func isSigned()
public static func isSigned(): Bool
功能:判断 BigInt 类型是否是有符号类型。
返回值:
- Bool - 总是返回
true。
extend BigInt <: Formattable
extend BigInt <: Formattable
功能:为 BigInt 扩展 Formattable 接口,以实现将 BigInt 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 BigInt 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend BigInt <: Number<BigInt>
extend BigInt <: Number<BigInt> {}
功能:为 BigInt 类型扩展 Number<T> 接口。
父类型:
extend BigInt <: Parsable<BigInt>
extend BigInt <: Parsable<BigInt>
功能:此扩展主要用于实现将 BigInt 类型字面量的字符串转换为 BigInt 结构体的相关操作函数。
父类型:
static func parse(String)
public static func parse(value: String): BigInt
功能:将字符串解析成一个 BigInt 结构体。
字符串的规则如下,即开头是可选的符号(正号或负号),接进制前缀,再接一串字符串表示的数字:
IntegerString : SignString? BaseString? ValueString
-
SignString : + | -
-
BaseString : "0b" | "0B" | "0o" | "0O" | "0x" | "0X" | ""
-
ValueString : Digits
-
Digits: Digit | Digit Digits
-
Digit : '0' ~ '9' | 'A' ~ 'Z' | 'a' ~ 'z'
-
如果进制前缀是 "0b" 或 "0B",则 Digit 取值范围应为 '0' ~ '1';
-
如果进制前缀是 "0o" 或 "0O",则 Digit 取值范围应为 '0' ~ '7';
-
如果进制前缀是 "0x" 或 "0X",则 Digit 取值范围应为 '0' ~ '9'、'a' ~ 'z' 或 'A' ~ 'Z';
-
如果进制前缀是空,则 Digit 取值范围应为 '0' ~ '9'。
-
-
-
参数:
- value: String - 用于构建 BigInt 结构体的字符串。字符串规则为,开头可选一个正号(+)或者负号(-)。接下来可选的进制前缀,默认为十进制,使用 "0b" 或 "0B" 表示二进制,使用 "0o" 或 "0O" 表示八进制,使用 "0x" 或 "0X" 表示十六进制。再接下来必选非空阿拉伯数字或大小写拉丁字母的字符序列,大小写字符含义一样,'a' 和 'A' 的大小等于十进制的 10,'b' 和 'B' 的大小等于十进制的 11,以此类推。序列中的字符应符合相应进制的字符集要求。
返回值:
异常:
- IllegalArgumentException - 如果字符串
value不符合上述规则,抛此异常。
static func tryParse(String)
public static func tryParse(value: String): ?BigInt
功能:尝试将字符串解析成一个 BigInt 结构体。
字符串的规则如下,即开头是可选的符号(正号或负号),接进制前缀,再接一串字符串表示的数字:
IntegerString : SignString? BaseString? ValueString
-
SignString : + | -
-
BaseString : "0b" | "0B" | "0o" | "0O" | "0x" | "0X" | ""
-
ValueString : Digits
-
Digits: Digit | Digit Digits
-
Digit : '0' ~ '9' | 'A' ~ 'Z' | 'a' ~ 'z'
-
如果进制前缀是 "0b" 或 "0B",则 Digit 取值范围应为 '0' ~ '1';
-
如果进制前缀是 "0o" 或 "0O",则 Digit 取值范围应为 '0' ~ '7';
-
如果进制前缀是 "0x" 或 "0X",则 Digit 取值范围应为 '0' ~ '9'、'a' ~ 'z' 或 'A' ~ 'Z';
-
如果进制前缀是空,则 Digit 取值范围应为 '0' ~ '9'。
-
-
-
参数:
- value: String - 用于构建 BigInt 结构体的字符串。字符串规则为,开头可选一个正号(+)或者负号(-)。接下来可选的进制前缀,默认为十进制,使用 "0b" 或 "0B" 表示二进制,使用 "0o" 或 "0O" 表示八进制,使用 "0x" 或 "0X" 表示十六进制。再接下来必选非空阿拉伯数字或大小写拉丁字母的字符序列,大小写字符含义一样,'a' 和 'A' 的大小等于十进制的 10,'b' 和 'B' 的大小等于十进制的 11,以此类推。序列中的字符应符合相应进制的字符集要求。
返回值:
extend BigInt <: RadixConvertible<BigInt>
extend BigInt <: RadixConvertible<BigInt>
功能:此扩展主要用于实现将 BigInt 类型字面量的字符串转换为 BigInt 结构体的相关操作函数。
父类型:
static func parse(String, Int)
public static func parse(value: String, radix!: Int): BigInt
功能:根据指定进制将字符串解析成一个 BigInt 结构体,支持 2 进制到 36 进制。
字符串的规则如下,即开头是可选的符号(正号或负号),接一串字符串表示的数字:
IntegerString : SignString? ValueString
-
SignString : + | -
-
ValueString : Digits
-
Digits: Digit | Digit Digits
-
Digit : '0' ~ '9' | 'A' ~ 'Z' | 'a' ~ 'z'
-
如果 Digit 在 '0' ~ '9' 内, 需要满足 (Digit - '0') < radix;
-
如果 Digit 在 'A' ~ 'Z' 内, 需要满足 (Digit - 'A') + 10 < radix;
-
如果 Digit 在 'a' ~ 'z' 内, 需要满足 (Digit - 'A') + 10 < radix。
-
-
-
参数:
- value: String - 用于构建 BigInt 结构体的字符串。字符串规则为,开头可选一个正号(+)或者负号(-)。接下来必选非空阿拉伯数字或大小写拉丁字母的字符序列,大小写字符含义一样,'a' 和 'A' 的大小等于十进制的 10,'b' 和 'B' 的大小等于十进制的 11,以此类推。序列中的字符大小不得大于等于进制大小。
- radix!: Int - 进制。字符串所表示的进制,范围为 [2, 36]。
返回值:
异常:
- IllegalArgumentException - 如果字符串
value不符合上述规则,或radix表示的进制不在 [2, 36] 区间内,抛此异常。
static func tryParse(String, Int)
public static func tryParse(value: String, radix!: Int): ?BigInt
功能:尝试根据指定进制将字符串解析成一个 BigInt 结构体,支持 2 进制到 36 进制。
字符串的规则如下,即开头是可选的符号(正号或负号),接一串字符串表示的数字:
IntegerString : SignString? ValueString
-
SignString : + | -
-
ValueString : Digits
-
Digits: Digit | Digit Digits
-
Digit : '0' ~ '9' | 'A' ~ 'Z' | 'a' ~ 'z'
-
如果 Digit 在 '0' ~ '9' 内, 需要满足 (Digit - '0') < radix;
-
如果 Digit 在 'A' ~ 'Z' 内, 需要满足 (Digit - 'A') + 10 < radix;
-
如果 Digit 在 'a' ~ 'z' 内, 需要满足 (Digit - 'A') + 10 < radix。
-
-
-
参数:
- value: String - 用于构建 BigInt 结构体的字符串。字符串规则为,开头可选一个正号(+)或者负号(-)。接下来必选非空阿拉伯数字或大小写拉丁字母的字符序列,大小写字符含义一样,'a' 和 'A' 的大小等于十进制的 10,'b' 和 'B' 的大小等于十进制的 11,以此类推。序列中的字符大小不得大于等于进制大小。
- radix!: Int - 进制。字符串所表示的进制,范围为 [2, 36]。
返回值:
func toString(Int)
public func toString(radix!: Int): String
功能:计算并返回此 BigInt 的任意进制字符串表示。
参数:
- radix!: Int - 进制。字符串所表示的进制,范围为 [2, 36]。
返回值:
异常:
- IllegalArgumentException - 当入参 radix 不在 [2, 36] 范围内时,抛出异常。
示例:
import std.math.numeric.BigInt
main() {
let bigInt = BigInt(0x400)
let toString = bigInt.toString(radix: 2)
println(toString)
}
运行结果:
10000000000
struct Decimal
public struct Decimal <: Comparable<Decimal> & Hashable & ToString {
public init(val: String)
public init(val: BigInt, scale: Int32)
public init(val: BigInt)
public init(val: Int8)
public init(val: Int16)
public init(val: Int32)
public init(val: IntNative)
public init(val: Int64)
public init(val: UInt8)
public init(val: UInt16)
public init(val: UInt32)
public init(val: UIntNative)
public init(val: UInt64)
public init(val: Float16)
public init(val: Float32)
public init(val: Float64)
}
功能:Decimal 用于表示任意精度的有符号的十进制数。允许操作过程指定结果精度及舍入规则。提供基础类型 (Int、UInt、String、Float等) 与 BigInt 类型互相转换能力,支持 Decimal 对象基本属性查询等能力,支持基础数学运算操作,提供对象比较、hash、字符串打印等基础能力。
父类型:
prop precision
public prop precision: Int64
功能:获取 Decimal 精度值,即无标度整数部分十进制有效数字位数,非负数。如果精度值为 0,表示无精度限制。
类型:Int64
prop scale
public prop scale: Int32
功能:获取 Decimal 标度值。
类型:Int32
prop sign
public prop sign: Int64
功能:获取 Decimal 实例符号值。
类型:Int64
prop value
public prop value: BigInt
功能:获取 Decimal 无标度整数值,BigInt 承载。
类型:BigInt
init(BigInt)
public init(val: BigInt)
功能:通过有符号大整数 BigInt 构建 Deciaml 结构体。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: BigInt - 有符号大整数值。
示例:
import std.math.numeric.BigInt
import std.math.numeric.Decimal
main() {
let bigInt = BigInt(24)
let decimal = Decimal(bigInt)
println(decimal)
}
运行结果:
24
init(BigInt, Int32)
public init(val: BigInt, scale: Int32)
功能:通过有符号大整数 BigInt 和标度值构建 Deciaml 结构体。默认采用精度值为 0,即无限精度进行构建。
参数:
示例:
import std.math.numeric.BigInt
import std.math.numeric.Decimal
main() {
let bigInt = BigInt(24)
let decimal = Decimal(bigInt, 4)
println(decimal)
}
运行结果:
0.0024
init(Float16)
public init(val: Float16)
功能:通过 16 位有符号浮点数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
注意:
由于部分十进制小数无法通过二进制浮点数精确表示,此构造函数以精确值构建 Decimal 对象,传入浮点数值可能与最终构建 Decimal 对象字符串打印值不一致。
参数:
- val: Float16 - 16 位有符号二进制浮点数。
异常:
- IllegalArgumentException - 当入参为
inf、-inf或nan时,抛出此异常。
示例:
import std.math.numeric.Decimal
main() {
let float16: Float16 = 0.8
let decimal = Decimal(float16)
println(decimal)
}
运行结果:
0.7998046875
init(Float32)
public init(val: Float32)
功能:通过 32 位有符号浮点数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
注意:
由于部分十进制小数无法通过二进制浮点数精确表示,此构造函数以精确值构建 Decimal 对象,传入浮点数值可能与最终构建 Decimal 对象字符串打印值不一致。
参数:
- val: Float32 - 32 位有符号二进制浮点数。
异常:
- IllegalArgumentException - 当入参为
inf、-inf或nan时,抛出此异常。
示例:
import std.math.numeric.Decimal
main() {
let float32: Float32 = 0.8
let decimal = Decimal(float32)
println(decimal)
}
运行结果:
0.800000011920928955078125
init(Float64)
public init(val: Float64)
功能:通过 64 位有符号浮点数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
注意:
由于部分十进制小数无法通过二进制浮点数精确表示,此构造函数以精确值构建 Decimal 对象,传入浮点数值可能与最终构建 Decimal 对象字符串打印值不一致。
参数:
- val: Float64 - 64 位有符号二进制浮点数。
异常:
- IllegalArgumentException - 当入参为
inf、-inf或nan时,抛出此异常。
示例:
import std.math.numeric.Decimal
main() {
let float64: Float64 = 0.8
let decimal = Decimal(float64)
println(decimal)
}
运行结果:
0.8000000000000000444089209850062616169452667236328125
init(Int16)
public init(val: Int16)
功能:通过 16 位有符号整数构建 Decimal 结构体。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: Int16 - 16 位有符号整数。
示例:
import std.math.numeric.Decimal
main() {
let int16: Int16 = 24
let decimal = Decimal(int16)
println(decimal)
}
运行结果:
24
init(Int32)
public init(val: Int32)
功能:通过 32 位有符号整数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: Int32 - 32 位有符号整数。
示例:
import std.math.numeric.Decimal
main() {
let int32: Int32 = 24
let decimal = Decimal(int32)
println(decimal)
}
运行结果:
24
init(Int64)
public init(val: Int64)
功能:通过 64 位有符号整数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: Int64 - 64 位有符号整数。
示例:
import std.math.numeric.Decimal
main() {
let int64: Int64 = 24
let decimal = Decimal(int64)
println(decimal)
}
运行结果:
24
init(Int8)
public init(val: Int8)
功能:通过 8 位有符号整数构建 Decimal 结构体。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: Int8 - 8 位有符号整数。
示例:
import std.math.numeric.Decimal
main() {
let int8: Int8 = 24
let decimal = Decimal(int8)
println(decimal)
}
运行结果:
24
init(IntNative)
public init(val: IntNative)
功能:通过 32 位或 64 位 (具体长度与平台相关) 有符号整数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: IntNative - 32 位或 64位有符号整数。
示例:
import std.math.numeric.Decimal
main() {
let intnative: IntNative = 24
let decimal = Decimal(intnative)
println(decimal)
}
运行结果:
24
init(String) (deprecated)
public init(val: String)
功能:通过规定格式字符串构建 Decimal 结构体。默认采用精度值为 0,即无限精度进行构建。字符串需满足如下格式,即开头可选的符号(正号或负号),接 ValueString 字符串,再接可选的 ExponentString 字符串:
Decimal 字符串: (SignString)? ValueString (ExponentString)?
-
SignString: + | -
-
ValueString: IntegerPart.(FractionPart)? | .FractionPart | IntegerPart
-
IntegerPart:Digits
-
FractionPart:Digits
-
Digits: Digit | Digit Digits
- Digit:'0' ~ '9'
-
-
ExponentString: ExponentIndicator (SignString)? IntegerPart
- ExponentIndicator:e | E
注意:
未来版本即将废弃,使用 parse(String) 替代。
参数:
- val: String - 规定格式字符串。
异常:
- IllegalArgumentException - 当入参字符串不满足规定格式时,抛此异常。
- OverflowException - 当构建值标度溢出时,抛此异常。
init(UInt16)
public init(val: UInt16)
功能:通过 16 位无符号整数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: UInt16 - 16 位无符号整数。
示例:
import std.math.numeric.Decimal
main() {
let uint16: UInt16 = 24
let decimal = Decimal(uint16)
println(decimal)
}
运行结果:
24
init(UInt32)
public init(val: UInt32)
功能:通过 32 位无符号整数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: UInt32 - 32 位无符号整数。
示例:
import std.math.numeric.Decimal
main() {
let uint32: UInt32 = 24
let decimal = Decimal(uint32)
println(decimal)
}
运行结果:
24
init(UInt64)
public init(val: UInt64)
功能:通过 64 位无符号整数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: UInt64 - 64 位无符号整数。
示例:
import std.math.numeric.Decimal
main() {
let uint64: UInt64 = 24
let decimal = Decimal(uint64)
println(decimal)
}
运行结果:
24
init(UInt8)
public init(val: UInt8)
功能:通过 8 位无符号整数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: UInt8 - 8 位无符号整数。
示例:
import std.math.numeric.Decimal
main() {
let uint8: UInt8 = 24
let decimal = Decimal(uint8)
println(decimal)
}
运行结果:
24
init(UIntNative)
public init(val: UIntNative)
功能:通过 32 位或 64 位 (具体长度与平台相关) 无符号整数构建 Decimal 对象。默认采用精度值为 0,即无限精度进行构建。
参数:
- val: UIntNative - 32 位或 64位无符号整数。
示例:
import std.math.numeric.Decimal
main() {
let uintnative: UIntNative = 24
let decimal = Decimal(uintnative)
println(decimal)
}
运行结果:
24
func compare(Decimal)
public func compare(d: Decimal): Ordering
功能:比较当前对象与入参 Decimal 对象,返回比较结果值。
参数:
返回值:
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(-5)
let B = Decimal(3)
let C = A.compare(B)
println(C)
}
运行结果:
Ordering.LT
func divWithPrecision(Decimal, Int64, RoundingMode)
public func divWithPrecision(d: Decimal, precision: Int64, roundingMode!: RoundingMode = HalfEven): Decimal
功能:除法运算,支持自定义运算精度和舍入方式,除以入参 Decimal 对象,返回结果值,如果结果精度超过 precision 指定精度,则根据指定的精度对除法运算结果进行舍入。
参数:
- d: Decimal - Decimal 除数对象。
- precision: Int64 - 精度值。
- roundingMode!: RoundingMode - 舍入规则。
返回值:
异常:
- ArithmeticException - 当除数为 0 时,抛出此异常。
- OverflowException - 当除法结果值范围超过 [-(maxValue(precision) * (10 Int32.MAX)), maxValue(precision) * (10 Int32.MAX)] 时,抛出此异常。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(2)
let B = Decimal(3)
let C = A.divWithPrecision(B, 0)
println("C = ${C}")
}
运行结果:
C = 0.6666666666666666666666666666666667
func divAndRem(Decimal) (deprecated)
public func divAndRem(d: Decimal): (BigInt, Decimal)
功能:除法取商和余数运算,除以入参 Decimal 对象,返回整数商值和余数值。结果保留实际精度值。
注意:
未来版本即将废弃,使用 divAndMod(Decimal) 替代。
参数:
返回值:
异常:
- ArithmeticException - 当除数为 0 时,抛出此异常。
- OverflowException - 当除法结果值范围超过 [-(maxValue(precision) * (10 Int32.MAX)), maxValue(precision) * (10 Int32.MAX)] 时,抛出此异常。
func divAndMod(Decimal)
public func divAndMod(d: Decimal): (BigInt, Decimal)
功能:除法取商和余数运算,除以入参 Decimal 对象,返回整数商值和余数值。结果保留实际精度值。
参数:
返回值:
异常:
- ArithmeticException - 当除数为 0 时,抛出此异常。
- OverflowException - 当除法结果值范围超过 [-(maxValue(precision) * (10 Int32.MAX)), maxValue(precision) * (10 Int32.MAX)] 时,抛出此异常。
func hashCode()
public func hashCode(): Int64
功能:获取当前对象哈希值。
返回值:
- Int64 - 返回当前对象哈希值。
示例:
import std.math.numeric.Decimal
main() {
let decimal = Decimal(24)
let hashcode = decimal.hashCode()
println(hashcode)
}
运行结果:
744
func isInteger()
public func isInteger(): Bool
功能:判断当前 Decimal 对象是否为整数。
返回值:
- Bool - 返回当前对象是否为整数判断结果。当前对象为整数时返回 true,否则返回 false。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(100)
println("${A}.isInteger() = ${A.isInteger()}")
}
运行结果:
100.isInteger() = true
func powWithPrecision(Int64, Int64, RoundingMode)
public func powWithPrecision(n: Int64, precision: Int64, roundingMode!: RoundingMode = RoundingMode.HalfEven): Decimal
功能:乘方运算,支持自定义运算精度和舍入方式,获取当前对象为底数,入参 Int64 为指数的乘方运算结果,如果运算结果超过 precision 指定的精度,则根据指定的精度对乘方结果进行舍入。
参数:
- n: Int64 - 乘方运算的指数值。
- precision: Int64 - 精度值。
- roundingMode!: RoundingMode - 舍入规则。
返回值:
异常:
- OverflowException - 当乘方运算结果标度值溢出时,抛出此异常。
示例:
import std.math.numeric.*
import std.math.*
main(): Unit {
let A = Decimal(2.5)
println("A.powWithPrecision(3, 0) = ${A.powWithPrecision(3, 0, roundingMode: HalfEven)}")
}
运行结果:
A.powWithPrecision(3, 0) = 15.625
func reScale(Int32, RoundingMode)
public func reScale(newScale: Int32, roundingMode!: RoundingMode = HalfEven): Decimal
功能:调整 Decimal 对象标度值,允许指定舍入规则,返回标度调整后新的 Decimal 对象。
参数:
- newScale: Int32 - 新的标度值。
- roundingMode!: RoundingMode - 舍入规则。
返回值:
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(1.234568)
println("A.reScale(3) = ${A.reScale(3)}")
}
运行结果:
A.reScale(3) = 1.235
func removeTrailingZeros()
public func removeTrailingZeros(): Decimal
功能:对当前 Decimal 对象移除尾部零,不改变对象数值。
返回值:
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(1.00)
println("A.removeTrailingZeros() = ${A.removeTrailingZeros()}")
}
运行结果:
A.removeTrailingZeros() = 1
func roundWithPrecision(Int64, RoundingMode)
public func roundWithPrecision(precision: Int64, roundingMode!: RoundingMode = RoundingMode.HalfEven): Decimal
功能:按照指定舍入精度和舍入规则对当前 Decimal 对象进行舍入操作。
参数:
- precision: Int64 - 精度值。
- roundingMode!: RoundingMode - 舍入规则。
返回值:
异常:
- OverflowException - 当舍入操作结果标度值溢出时,抛出此异常。
示例:
import std.math.numeric.Decimal
import std.math.*
main(): Unit {
let A = Decimal(1.0)
println("A.roundWithPrecision(1.0) = ${A.roundWithPrecision(0, roundingMode: HalfEven)}")
let B = Decimal(0.1f16).roundWithPrecision(5, roundingMode: Up)
println("B = ${B}")
}
运行结果:
A.roundWithPrecision(1.0) = 1
B = 0.099976
func scaleUnit()
public func scaleUnit(): Decimal
功能:对当前 Decimal 对象返回标度单位,即数值为 1 ,标度值与当前对象相等的 Decimal 对象。
返回值:
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(100)
println("A.scaleUnit() = ${A.scaleUnit()}")
}
运行结果:
A.scaleUnit() = 1
func shiftPoint(Int32)
public func shiftPoint(n: Int32): Decimal
功能:移动当前 Decimal 对象小数点 abs(n) 位返回结果对象,当 n 为正数时,左移小数点,n 为负数时,右移小数点,n 为零时,返回当前对象。
参数:
- n: Int32 - 指定小数点移动位数及方向。
返回值:
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(25)
println("A.shiftPoint(1) = ${A.shiftPoint(1)}")
}
运行结果:
A.shiftPoint(1) = 2.5
func sqrtWithPrecision(Int64, RoundingMode)
public func sqrtWithPrecision(precision: Int64, roundingMode!: RoundingMode = RoundingMode.HalfEven): Decimal
功能:开方运算,支持自定义运算精度和结果舍入方式,获取当前对象开方结果,如果运算结果超过 presision 指定的精度,则根据指定的精度对开方结果进行舍入。
参数:
- precision: Int64 - 精度值。
- roundingMode!: RoundingMode - 舍入规则。
返回值:
异常:
- IllegalArgumentException - 如果被计算平方根的对象为负数,则抛此异常。
- OverflowException - 当计算平方根操作结果标度值溢出时,抛出此异常。
示例:
import std.math.numeric.*
main() {
let n: Decimal = Decimal.parse("2")
let s = n.sqrtWithPrecision(2)
println(s)
}
运行结果:
1.4
func toBigInt()
public func toBigInt(): BigInt
功能:将当前 Decimal 对象转化为 BigInt 类型。
返回值:
func toEngString()
public func toEngString(): String
功能:以工程计数法的形式打印输出 Decimal 对象,指数为 3 的倍数, 当值小于 0 时以 “-” 开头后跟十进制数字,大于等于 0 时,直接打印输出数字,不额外添加 “+”。指数小于 0 时同样遵循以上规则。
返回值:
func toSciString()
public func toSciString(): String
功能:以科学计数法的形式打印输出 Decimal 对象,当值小于 0 时以 “-” 开头后跟十进制数字,大于等于 0 时,直接打印输出数字,不额外添加 “+”。指数小于 0 时同样遵循以上规则。
返回值:
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(6.25)
println("A.toFloat16() = ${A.toFloat16()}")
println("A.toFloat32() = ${A.toFloat32()}")
println("A.toFloat64() = ${A.toFloat64()}")
println("A.toBigInt() = ${A.toBigInt()}")
println("A.toEngString() = ${A.toEngString()}")
println("A.toSciString() = ${A.toSciString()}")
}
运行结果:
A.toFloat16() = 6.250000
A.toFloat32() = 6.250000
A.toFloat64() = 6.250000
A.toBigInt() = 6
A.toEngString() = 6.25E0
A.toSciString() = 6.25E0
func toFloat16()
public func toFloat16(): Float16
功能:将当前 Decimal 对象转化为 Float16 类型。
返回值:
func toFloat32()
public func toFloat32(): Float32
功能:将当前 Decimal 对象转化为 Float32 类型。
返回值:
func toFloat64()
public func toFloat64(): Float64
功能:将当前 Decimal 对象转化为 Float64 类型。
返回值:
func toInt16(OverflowStrategy)
public func toInt16(overflowHandling!: OverflowStrategy = Throwing): Int16
功能:将当前 Decimal 对象转化为 Int16 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
func toInt32(OverflowStrategy)
public func toInt32(overflowHandling!: OverflowStrategy = Throwing): Int32
功能:将当前 Decimal 对象转化为 Int32 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
func toInt64(OverflowStrategy)
public func toInt64(overflowHandling!: OverflowStrategy = Throwing): Int64
功能:将当前 Decimal 对象转化为 Int64 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
func toInt8(OverflowStrategy)
public func toInt8(overflowHandling!: OverflowStrategy = Throwing): Int8
功能:将当前 Decimal 对象转化为 Int8 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
func toIntNative(OverflowStrategy)
public func toIntNative(overflowHandling!: OverflowStrategy = Throwing): IntNative
功能:将当前 Decimal 对象转化为 IntNative 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(6.25)
println("A.toInt8() = ${A.toInt8()}")
println("A.toInt16() = ${A.toInt16()}")
println("A.toInt32() = ${A.toInt32()}")
println("A.toInt64() = ${A.toInt64()}")
println("A.toIntNative() = ${A.toIntNative()}")
}
运行结果:
A.toInt8() = 6
A.toInt16() = 6
A.toInt32() = 6
A.toInt64() = 6
A.toIntNative() = 6
func toString()
public func toString(): String
功能:以不带指数形式打印输出 Decimal 对象,小于 0 时以 “-” 开头后跟十进制数字,大于等于 0 时,直接打印输出数字,不额外添加 “+”。
返回值:
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(-5)
let B = Decimal(3 ** 5)
println("A.hashCode() = ${A.hashCode()}")
println("B.toString() = ${B.toString()}")
}
运行结果:
A.hashCode() = 155
B.toString() = 243
func toUInt16(OverflowStrategy)
public func toUInt16(overflowHandling!: OverflowStrategy = Throwing): UInt16
功能:将当前 Decimal 对象转化为 UInt16 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
func toUInt32(OverflowStrategy)
public func toUInt32(overflowHandling!: OverflowStrategy = Throwing): UInt32
功能:将当前 Decimal 对象转化为 UInt32 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
func toUInt64(OverflowStrategy)
public func toUInt64(overflowHandling!: OverflowStrategy = Throwing): UInt64
功能:将当前 Decimal 对象转化为 UInt64 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
func toUInt8(OverflowStrategy)
public func toUInt8(overflowHandling!: OverflowStrategy = Throwing): UInt8
功能:将当前 Decimal 对象转化为 UInt8 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
func toUIntNative(OverflowStrategy)
public func toUIntNative(overflowHandling!: OverflowStrategy = Throwing): UIntNative
功能:将当前 Decimal 对象转化为 UIntNative 类型,支持自定义溢出策略。
参数:
- overflowHandling!: OverflowStrategy - 转换溢出策略。
返回值:
- UIntNative - 转换后的 UIntNative 值。
异常:
- OverflowException - 当不指定溢出策略或溢出策略为
throwing转换溢出时,抛出此异常。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(6.25)
println("A.toUInt8() = ${A.toUInt8()}")
println("A.toUInt16() = ${A.toUInt16()}")
println("A.toUInt32() = ${A.toUInt32()}")
println("A.toUInt64() = ${A.toUInt64()}")
println("A.toUIntNative() = ${A.toUIntNative()}")
}
运行结果:
A.toUInt8() = 6
A.toUInt16() = 6
A.toUInt32() = 6
A.toUInt64() = 6
A.toUIntNative() = 6
operator func !=(Decimal)
public operator func !=(d: Decimal): Bool
功能:不等比较运算,不等运算符重载,判断入参 Decimal 对象与当前对象是否不相等,返回比较结果值。
参数:
返回值:
- Bool - 返回不等比较运算结果。当前对象不等于入参时,返回 true,否则返回 false。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(-5)
let B = Decimal(3)
println(" -A = ${-A}")
println(" A <= B = ${ A <= B}")
println(" A != B = ${ A != B}")
}
运行结果:
-A = 5
A <= B = true
A != B = true
operator func *(Decimal)
public operator func *(d: Decimal): Decimal
功能:乘法运算,乘法运算符重载,乘以入参 Decimal 对象,返回结果值。保留乘法运算结果实际精度值。
参数:
返回值:
异常:
- OverflowException - 当两个乘数标度值相加溢出时,抛出此异常。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(2)
let B = Decimal(3)
let C = A * B
println("C = ${C}")
}
运行结果:
C = 6
operator func **(Int64)
public operator func **(n: Int64): Decimal
功能:乘方运算,乘方运算符重载,获取当前对象为底数,入参 Int64 为指数的乘方运算结果,其中指数为入参 Decimal 对象的整数部分。
注意:
指数为负值且结果为无限小数场景时,默认采用 IEEE 754-2019 decimal128 对结果进行舍入。
参数:
- n: Int64 - 乘方运算的指数值。
返回值:
异常:
- OverflowException - 当乘方运算结果标度值溢出时,抛出此异常。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(2.5)
println("A ** 3 = ${A ** 3}")
}
运行结果:
A ** 3 = 15.625
operator func +(Decimal)
public operator func +(d: Decimal): Decimal
功能:加法运算,加法运算符重载,加上入参 Decimal 对象,返回结果值。结果保留实际精度值。
参数:
返回值:
异常:
- OverflowException - 当两个加数标度值相减溢出时,抛出此异常。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(2)
let B = Decimal(3)
let C = A + B
println("C = ${C}")
}
运行结果:
C = 5
operator func -()
public operator func -(): Decimal
功能:取反运算,一元负数运算符重载,对当前 Decimal 对象取反,返回结果值。保留取反运算结果实际精度值。
返回值:
operator func -(Decimal)
public operator func -(d: Decimal): Decimal
功能:减法运算,减法运算符重载,减去入参 Decimal 对象,返回结果值。保留减法运算结果实际精度值。
参数:
返回值:
异常:
- OverflowException - 当被减数与减数标度值相减溢出时,抛出此异常。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(2)
let B = Decimal(3)
let C = A - B
println("C = ${C}")
}
运行结果:
C = -1
operator func <(Decimal)
public operator func <(d: Decimal): Bool
功能:小于比较运算,小于运算符重载,判断入参 Decimal 对象是否小于当前对象,返回比较结果值。
参数:
返回值:
- Bool - 返回小于比较运算结果。当前对象小于入参时,返回 true,否则返回 false。
operator func <=(Decimal)
public operator func <=(d: Decimal): Bool
功能:小于等于比较运算,小于等于运算符重载,判断入参 Decimal 对象是否小于等于当前对象,返回比较结果值。
参数:
返回值:
- Bool - 返回小于等于比较运算结果。当前对象小于等于入参时,返回 true,否则返回 false
operator func ==(Decimal)
public operator func ==(d: Decimal): Bool
功能:等于比较运算,等于运算符重载,判断入参 Decimal 对象与当前对象是否相等,返回比较结果值。
参数:
返回值:
- Bool - 返回等于比较运算结果。当前对象等于入参时,返回 true,否则返回 false。
operator func >(Decimal)
public operator func >(d: Decimal): Bool
功能:大于比较运算,大于运算符重载,判断入参 Decimal 对象是否大于当前对象,返回比较结果值。
参数:
返回值:
- Bool - 返回大于比较运算结果。当前对象大于入参时,返回 true,否则返回 false
operator func >=(Decimal)
public operator func >=(d: Decimal): Bool
功能:大于等于比较运算,大于等于运算符重载,判断入参 Decimal 对象是否大于等于当前对象,返回比较结果值。
参数:
返回值:
- Bool - 返回大于等于比较运算结果。当前对象大于等于入参时,返回 true,否则返回 false。
operator func /(Decimal)
public operator func /(d: Decimal): Decimal
功能:除法运算,除法运算符重载,除以入参 Decimal 对象,返回结果值。
注意:
结果为无限小数场景时,默认采用 IEEE 754-2019 decimal128 对结果进行舍入。
参数:
返回值:
异常:
- IllegalArgumentException - 当除数为 0 时,抛出此异常。
- OverflowException - 当除法结果值范围超过 [-(maxValue(precision) * (10 Int32.MAX)), maxValue(precision) * (10 Int32.MAX)] 时,抛出此异常。
示例:
import std.math.numeric.Decimal
main(): Unit {
let A = Decimal(2)
let B = Decimal(3)
let C = A / B
println("C = ${C}")
}
运行结果:
C = 0.6666666666666666666666666666666667
extend Decimal <: Formattable
extend Decimal <: Formattable
功能:为 Decimal 扩展 Formattable 接口,以实现将 Decimal 实例转换为格式化字符串。
父类型:
func format(String)
public func format(fmt: String): String
功能:根据格式化参数将当前 Decimal 类型实例格式化为对应格式的字符串。
参数:
- fmt: String - 格式化参数。
返回值:
异常:
- IllegalArgumentException - 当 fmt 不合法时抛出异常。
extend Decimal <: Number<Decimal>
extend Decimal <: Number<Decimal> {}
功能:为 Decimal 类型扩展 Number<T> 接口。
父类型:
extend Decimal <: Parsable<Decimal>
extend Decimal <: Parsable<Decimal>
功能:此扩展主要用于实现将 Decimal 类型字面量的字符串转换为 Decimal 结构体的相关操作函数。
父类型:
static func parse(String)
public static func parse(value: String): Decimal
功能:通过规定格式字符串构建 Decimal 结构体。默认采用精度值为 0,即无限精度进行构建。字符串需满足如下格式,即开头可选的符号(正号或负号),接 ValueString 字符串,再接可选的 ExponentString 字符串:
Decimal 字符串: SignString? ValueString ExponentString?
-
SignString: + | -
-
ValueString: IntegerPart.(FractionPart)? | .FractionPart | IntegerPart
-
IntegerPart:Digits
-
FractionPart:Digits
-
Digits: Digit | Digit Digits
- Digit:'0' ~ '9'
-
-
ExponentString: ExponentIndicator (SignString)? IntegerPart
- ExponentIndicator:e | E
参数:
- value: String - 规定格式字符串。
返回值:
异常:
- IllegalArgumentException - 当入参字符串不满足规定格式时,抛此异常。
- OverflowException - 当构建值标度溢出时,抛此异常。
static func tryParse(String)
public static func tryParse(value: String): ?Decimal
功能:尝试通过规定格式字符串构建 Decimal 结构体。默认采用精度值为 0,即无限精度进行构建。字符串需满足如下格式,即开头可选的符号(正号或负号),接 ValueString 字符串,再接可选的 ExponentString 字符串:
Decimal 字符串: SignString? ValueString ExponentString?
-
SignString: + | -
-
ValueString: IntegerPart.(FractionPart)? | .FractionPart | IntegerPart
-
IntegerPart:Digits
-
FractionPart:Digits
-
Digits: Digit | Digit Digits
- Digit:'0' ~ '9'
-
-
ExponentString: ExponentIndicator (SignString)? IntegerPart
- ExponentIndicator:e | E
参数:
- value: String - 规定格式字符串。
返回值:
BigInt 基础数学运算示例
以下为通过不同构造函数初始化 BigInt 对象的,并进行基础数学运算示例:
import std.math.numeric.*
main() {
let int1: BigInt = BigInt.parse("123456789")
let int2: BigInt = BigInt.parse("987654321")
println("${int1} + ${int2} = ${int1 + int2}")
println("${int1} - ${int2} = ${int1 - int2}")
println("${int1} * ${int2} = ${int1 * int2}")
println("${int1} / ${int2} = ${int1 / int2}")
let (quo, mod) = int1.divAndMod(int2)
println("${int1} / ${int2} = ${quo} .. ${mod}")
return 0
}
运行结果:
123456789 + 987654321 = 1111111110
123456789 - 987654321 = -864197532
123456789 * 987654321 = 121932631112635269
123456789 / 987654321 = 0
123456789 / 987654321 = 0 .. 123456789
BigInt 基本属性示例
以下为初始化 BigInt 对象的,并查询对象的基本属性的示例:
import std.math.numeric.*
main() {
let int = BigInt.parse("-123456")
println("BigInt: ${int}")
println("BigInt sign: ${int.sign}")
println("BigInt bitLen: ${int.bitLen}")
return 0
}
运行结果:
BigInt: -123456
BigInt sign: -1
BigInt bitLen: 18
BigInt 大小比较示例
以下为初始化多个 BigInt 对象,相互之间大小比较的示例:
import std.math.numeric.*
main() {
let int1 = BigInt.parse("123456789")
let int2 = BigInt.parse("987654321")
println("${int1} > ${int2} = ${int1 > int2}")
println("${int1} < ${int2} = ${int1 < int2}")
println("${int1} == ${int2} = ${int1 == int2}")
println("${int1} != ${int2} = ${int1 != int2}")
println("${int1} <= ${int2} = ${int1 <= int2}")
println("${int1} >= ${int2} = ${int1 >= int2}")
println("${int1}.compare(${int2}) = ${int1.compare(int2)}")
return 0
}
运行结果:
123456789 > 987654321 = false
123456789 < 987654321 = true
123456789 == 987654321 = false
123456789 != 987654321 = true
123456789 <= 987654321 = true
123456789 >= 987654321 = false
123456789.compare(987654321) = Ordering.LT
Decimal 基础数学运算示例
以下为通过不同构造函数初始化 Decimal 对象的,并进行基础数学运算示例:
import std.math.*
import std.math.numeric.*
main() {
let decimal1: Decimal = Decimal.parse("12345.6789")
let decimal2: Decimal = Decimal(BigInt.parse("987654321"), 6)
println("${decimal1} + ${decimal2} = ${decimal1 + decimal2}")
println("${decimal1} - ${decimal2} = ${decimal1 - decimal2}")
println("${decimal1} * ${decimal2} = ${decimal1 * decimal2}")
println("${decimal1} / ${decimal2} = ${decimal1 / decimal2}")
println("${decimal1} / ${decimal2} with precision 10 and rounding mode HalfEven = ${decimal1.divWithPrecision(decimal2, 10, roundingMode: HalfEven)}")
let (quo, rem) = decimal1.divAndMod(decimal2)
println("${decimal1} / ${decimal2} = ${quo} .. ${rem}")
return 0
}
运行结果:
12345.6789 + 987.654321 = 13333.333221
12345.6789 - 987.654321 = 11358.024579
12345.6789 * 987.654321 = 12193263.1112635269
12345.6789 / 987.654321 = 12.49999988609375000142382812498220
12345.6789 / 987.654321 with precision 10 and rounding mode HalfEven = 12.49999989
12345.6789 / 987.654321 = 12 .. 493.827048
Decimal 基本属性示例
以下为初始化 Decimal 对象,并查询对象的基本属性的示例:
import std.math.*
import std.math.numeric.*
main() {
let decimalProperties = Decimal.parse("-123456.7890123456789")
println("decimal: ${decimalProperties}")
println("decimal sign: ${decimalProperties.sign}")
println("decimal scale: ${decimalProperties.scale}")
println("decimal value: ${decimalProperties.value}")
println("decimal precision: ${decimalProperties.precision}")
// 如果希望初始化一个带有指定精度和舍入方式的 Decimal 对象,可以采用如下方式
let decimalProperties2 = Decimal.parse("-123456.7890123456789").roundWithPrecision(10, roundingMode: HalfEven)
println("decimal2: ${decimalProperties2}")
println("decimal2 sign: ${decimalProperties2.sign}")
println("decimal2 scale: ${decimalProperties2.scale}")
println("decimal2 value: ${decimalProperties2.value}")
println("decimal2 precision: ${decimalProperties2.precision}")
return 0
}
运行结果:
decimal: -123456.7890123456789
decimal sign: -1
decimal scale: 13
decimal value: -1234567890123456789
decimal precision: 19
decimal2: -123456.7890
decimal2 sign: -1
decimal2 scale: 4
decimal2 value: -1234567890
decimal2 precision: 10
Decimal 大小比较示例
以下为初始化多个 Decimal 对象,相互之间大小比较的示例:
import std.math.*
import std.math.numeric.*
main() {
let decimal1 = Decimal.parse("12345.6789")
let decimal2 = Decimal.parse("987.654321")
println("${decimal1} > ${decimal2} = ${decimal1 > decimal2}")
println("${decimal1} < ${decimal2} = ${decimal1 < decimal2}")
println("${decimal1} == ${decimal2} = ${decimal1 == decimal2}")
println("${decimal1} != ${decimal2} = ${decimal1 != decimal2}")
println("${decimal1} <= ${decimal2} = ${decimal1 <= decimal2}")
println("${decimal1} >= ${decimal2} = ${decimal1 >= decimal2}")
println("${decimal1}.compare(${decimal2}) = ${decimal1.compare(decimal2)}")
return 0
}
运行结果:
12345.6789 > 987.654321 = true
12345.6789 < 987.654321 = false
12345.6789 == 987.654321 = false
12345.6789 != 987.654321 = true
12345.6789 <= 987.654321 = false
12345.6789 >= 987.654321 = true
12345.6789.compare(987.654321) = Ordering.GT
std.net
功能介绍
net 包用于进行网络通信,提供启动 Socket 服务器、连接 Socket 服务器、发送数据、接收数据等功能和 IP 地址、IP前缀(又称IP子网)、Socket 地址的相关数据结构。
我们支持 UDP/TCP/UDS 三种 Socket 类型,用户可按需选用。
UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输协议,它不提供可靠性和流量控制,但是具有较低的延迟和较小的网络开销。UDP协议主要用于一些实时性要求高的应用场景,例如视频直播、在线游戏等。
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的传输协议。它提供了可靠的数据传输、流量控制、拥塞控制、错误检测和流量管理等功能,是互联网中最常用的传输协议之一。
UDS(Unix Domain Socket)是一种用于在同一台计算机上的进程之间进行通信的机制。与网络套接字不同,UDS不需要网络协议栈和网络设备,因此可以更快地进行通信,具有更低的延迟和更高的吞吐量。
如下为本库提供 Socket 的类继承关系:
Hierarchy
Resource
├StreamingSocket
│ ├TcpSocket
│ └UnixSocket
│
├DatagramSocket
│ ├UdpSocket
│ └UnixDatagramSocket
│
└ServerSocket
├TcpServerSocket
└UnixServerSocket
API 列表
接口
| 接口名 | 功能 |
|---|---|
| DatagramSocket | DatagramSocket 是一种接收和读取数据包的套接字。 |
| ServerSocket | 提供服务端的 Socket 需要的接口。 |
| StreamingSocket | 双工流模式下的运行的 Socket,可被读写。 |
类
| 类名 | 功能 |
|---|---|
| IPAddress | 此类表示Internet协议(IP)地址。 |
| IPPrefix | 这个类表示一个 IP 前缀(也称为“IP子网”),即一个连续的 IP 地址块,边界为2的幂。 |
| IPSocketAddress | 此类实现了IP协议 Socket 地址(IP地址+端口号)。 |
| IPv4Address | 此类表示 Internet 协议版本4(IPv4)地址。 |
| IPv6Address | 此类表示 Internet 协议版本6(IPv6)地址。 |
| RawSocket | RawSocket 提供了套接字的基本功能。 |
| SocketAddress | 此类表示协议无关的 Socket 地址。 |
| TcpServerSocket | 监听 TCP 连接的服务端。 |
| TcpSocket | 请求 TCP 连接的客户端。 |
| UdpSocket | 提供 udp 报文通信。 |
| UnixDatagramSocket | 提供基于数据包的主机通讯能力。 |
| UnixServerSocket | 提供基于双工流的主机通讯服务端。 |
| UnixSocket | 提供基于双工流的主机通讯客户端。 |
| UnixSocketAddress | 此类实现了 Unix Domain Socket 地址。 |
枚举
| 枚举名 | 功能 |
|---|---|
| SocketNet | 传输层协议类型。 |
结构体
| 结构体名 | 功能 |
|---|---|
| AddressFamily | 地址族用于在个别地址的使用可能不明确的上下文中标识用于网络通信的个别网络地址方案或编号计划。 |
| OptionLevel | 提供了常用的套接字选项级别。 |
| OptionName | 提供了常用的套接字选项。 |
| ProtocolType | 提供了常用的套接字协议,以及通过指定 Int32 值来构建套接字协议的功能。 |
| RawAddress | 提供了 RawSocket 的通信地址创建和获取功能。 |
| SocketDomain | 提供了常用的套接字通信域,以及通过指定 Int32 值来构建套接字通信域的功能。 |
| SocketKeepAliveConfig | TCP KeepAlive 属性配置。 |
| SocketOptions | SocketOptions 存储了设置套接字选项的一些参数常量方便后续调用。 |
| SocketType | 提供了常用的套接字类型,以及通过指定 Int32 值来构建套接字类型的功能。 |
异常类
| 异常类名 | 功能 |
|---|---|
| SocketException | 提供套接字相关的异常处理。 |
| SocketTimeoutException | 提供字符格式相关的异常处理。 |
接口
interface DatagramSocket
public interface DatagramSocket <: Resource & ToString {
prop localAddress: SocketAddress
prop remoteAddress: ?SocketAddress
mut prop receiveTimeout: ?Duration
mut prop sendTimeout: ?Duration
func receiveFrom(buffer: Array<Byte>): (SocketAddress, Int64)
func sendTo(address: SocketAddress, payload: Array<Byte>): Unit
}
功能:DatagramSocket 是一种接收和读取数据包的套接字。
一个数据包通常有有限的大小,可能为空。不同的数据包套接字类型有不同的数据包最大值。例如 UDP 套接字一次可以处理最大 64KB 的数据包。
数据包传输不是一种可靠的传输,不保证传输顺序。数据包大小在发送端决定,例如:一端发送了 10 字节和 15 字节的报文,对端将收到相同大小的对应报文,10 字节和 15 字节。
父类型:
prop localAddress
prop localAddress: SocketAddress
功能:读取 Socket 将要或已经被绑定的本地地址。
异常:
- SocketException - 当
Socket已经被关闭或无可用的本地地址(本地地址未配置并且套接字未连接)时,抛出异常。
prop receiveTimeout
mut prop receiveTimeout: ?Duration
功能:设置和读取 receiveFrom 超时时间,无超时时间设置为 None。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
prop remoteAddress
prop remoteAddress: ?SocketAddress
功能:读取 Socket 已经连接的远端地址,当 Socket 未连接时返回 None。
类型:?SocketAddress
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
prop sendTimeout
mut prop sendTimeout: ?Duration
功能:设置和读取 sendTo 超时时间,默认设置为 None。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
func receiveFrom(Array<Byte>)
func receiveFrom(buffer: Array<Byte>): (SocketAddress, Int64)
功能:阻塞式等待收取报文到 buffer 中。
参数:
返回值:
- (SocketAddress, Int64) - 报文发送地址和收取到的报文大小(可能为 0,或大于参数
buffer大小)。
异常:
- SocketException - 当本机缓存过小无法读取报文时,抛出异常。
- SocketTimeoutException - 当读取超时时,抛出异常。
func sendTo(SocketAddress, Array<Byte>)
func sendTo(address: SocketAddress, payload: Array<Byte>): Unit
功能:发送报文到指定的远端地址,当对端无足够缓存时,此操作可能被阻塞,报文可能被丢弃。
参数:
- address: SocketAddress - 需要发送到的远端地址。
- payload: Array<Byte> - 需要发送的报文内容。
interface ServerSocket
public interface ServerSocket <: Resource & ToString {
prop localAddress: SocketAddress
func accept(): StreamingSocket
func accept(timeout!: ?Duration): StreamingSocket
func bind(): Unit
}
功能:提供服务端的 Socket 需要的接口。
父类型:
prop localAddress
prop localAddress: SocketAddress
功能:读取 Socket 将要或已经被绑定的本地地址。
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
func accept()
func accept(): StreamingSocket
功能:接受一个客户端套接字的连接请求,阻塞式等待连接请求。
返回值:
- StreamingSocket - 连接成功的客户端套接字。
func accept(?Duration)
func accept(timeout!: ?Duration): StreamingSocket
功能:接受一个客户端套接字的连接请求,阻塞式等待连接请求。
参数:
- timeout!: ?Duration - 等待连接超时的时间。
返回值:
- StreamingSocket - 连接成功的客户端套接字。
异常:
- SocketTimeoutException - 当等待连接请求超时,抛出异常。
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
func bind()
func bind(): Unit
功能:绑定套接字。
当没有设置 reuse 属性,本地端口、地址、文件路径已被占用或者上次绑定套接字的连接失败后需要 close 套接字。不支持多次重试此操作后可执行 accept() 操作。
异常:
- SocketException - 当因系统原因绑定失败时,抛出异常。
interface StreamingSocket
public interface StreamingSocket <: IOStream & Resource & ToString {
prop localAddress: SocketAddress
prop remoteAddress: SocketAddress
mut prop readTimeout: ?Duration
mut prop writeTimeout: ?Duration
}
功能:双工流模式下的运行的 Socket,可被读写。
StreamingSocket 可以被绑定 (bind) 和连接 (connect),用户可以通过属性设置绑定和连接的远端和本地地址。
StreamingSocket 可以有序分包传输字节流。我们会使用一段缓存空间存储读写的字节流。读取接口 (read()) 默认在无数据到来时阻塞式等待,直到下一次数据到达,或超时。写操作 (write()) 会写入缓存中的数据并在后续被发出,如果缓存不足,或者写入速度快于转发速度,写操作将会阻塞等待缓存空闲,或超时。
读写字符始终保持有序,但不保证传输过程中的分包策略及大小与发包时一致。例如:一端发送 10 字节报文后,又发送了 15 字节报文,对端可能分别收到 10 字节 和 15 字节报文,也可能一次性收到 25 字节的一个报文。
当收到一段异常报文时,将返回报文长度为 -1 。
父类型:
prop localAddress
prop localAddress: SocketAddress
功能:读取 Socket 将要或已经被绑定的本地地址。
异常:
- SocketException - 当
Socket已经被关闭或无可用的本地地址(本地地址未配置并且套接字未连接)时,抛出异常。
prop readTimeout
mut prop readTimeout: ?Duration
功能:设置和读取读超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
prop remoteAddress
prop remoteAddress: SocketAddress
功能:读取 Socket 将要或已经连接的远端地址。
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
prop writeTimeout
mut prop writeTimeout: ?Duration
功能:设置和读取写超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
类
class IPAddress
abstract sealed class IPAddress <: ToString & Equatable<IPAddress> & Hashable & BigEndianOrder<IPAddress>
功能:此类表示Internet协议(IP)地址。互联网协议地址(IP地址)是一个数字标签,例如 192.0.2.1 或 2001:0db8:0000:0000:0000:ff00:0042:8329,分配给连接到使用互联网协议进行通信的计算机网络设备。IP地址有两个主要功能:网络接口标识和位置寻址。
父类型:
prop hostName
public prop hostName: ?String
功能:返回当前 IPAddress 对象对应的主机名,如果无法成功解析,则为 None,当前暂未实现。
异常:
- UnsupportedException - 如果不是合法字符串,抛出异常。
类型:?String
prop size
public prop size: Int64
功能:获取 IP 地址对象字节长度。
类型:Int64
static func parse(String)
public static func parse(s: String): IPAddress
功能:将 IP 协议的 Socket 字符串转换为 IPAddress 对象。
参数:
- s: String - IP 协议的 Socket 字符串。
返回值:
异常:
- IllegalFormatException - 如果不是合法字符串,抛出异常。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let v4: IPAddress = IPAddress.parse("192.168.1.2")
let v6: IPAddress = IPAddress.parse("2001:0250:1006:dff0:4913:2aa5:8075:7c10")
@Assert(v4.toString(), "192.168.1.2")
@Assert(v6.toString(), "2001:250:1006:dff0:4913:2aa5:8075:7c10")
}
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): IPAddress
功能:从字节数组中以大端序的方式读取一个 IPAddress 对象。
参数:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 IPAddress 值时,抛出异常。
返回值:
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let bufferV4: Array<Byte> = [0xC0, 0xA8, 0x1, 0x2]
let bufferV6: Array<Byte> = [0x20, 0x01, 0x02, 0x50, 0x10, 0x06, 0xdf, 0xf0, 0x49, 0x13, 0x2a, 0xa5, 0x80, 0x75, 0x7c, 0x10]
let v4: IPAddress = IPAddress.readBigEndian(bufferV4)
let v6: IPAddress = IPAddress.readBigEndian(bufferV6)
@Assert(v4.toString(), "192.168.1.2")
@Assert(v6.toString(), "2001:250:1006:dff0:4913:2aa5:8075:7c10")
}
static func resolve(AddressFamily, String)
public static func resolve(family: AddressFamily, domain: String): Array<IPAddress>
功能:解析域名,得到 IPAddress 列表。
参数:
- family: AddressFamily - 地址族。
- domain: String - 域名。
返回值:
示例:
import std.net.*
main () {
let iplist: Array<IPAddress> = IPAddress.resolve(AddressFamily.UNSPEC, "localhost")
println(iplist)
}
// may output: [127.0.0.1, ::1]
static func resolve(String)
public static func resolve(domain: String): Array<IPAddress>
功能:解析域名,得到 IPAddress 列表。
参数:
- domain: String - 域名。
返回值:
示例:
import std.net.*
main () {
let iplist: Array<IPAddress> = IPAddress.resolve("localhost")
println(iplist)
}
// may output: [127.0.0.1, ::1]
static func tryParse(String)
public static func tryParse(s: String): ?IPAddress
功能:将 IP 地址字符串转换为 IPAddress 对象,如果不是合法字符串,则返回 None。
参数:
- s: String - IP 地址字符串。
返回值:
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let v4: ?IPAddress = IPAddress.tryParse("192.168.1.2")
let v6: ?IPAddress = IPAddress.tryParse("2001:0250:1006:dff0:4913:2aa5:8075:7c10")
@Assert(v4.toString(), "Some(192.168.1.2)")
@Assert(v6.toString(), "Some(2001:250:1006:dff0:4913:2aa5:8075:7c10)")
}
func getAddressBytes()
public func getAddressBytes(): Array<Byte>
功能:返回此 IPAddress 对象的原始IP地址。
返回值:
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let expectV4: Array<Byte> = [0xC0, 0xA8, 0x1, 0x2]
let expectV6: Array<Byte> = [0x20, 0x01, 0x02, 0x50, 0x10, 0x06, 0xdf, 0xf0, 0x49, 0x13, 0x2a, 0xa5, 0x80, 0x75, 0x7c, 0x10]
let v4: IPAddress = IPAddress.parse("192.168.1.2")
let v6: IPAddress = IPAddress.parse("2001:0250:1006:dff0:4913:2aa5:8075:7c10")
@Assert(v4.getAddressBytes(), expectV4)
@Assert(v6.getAddressBytes(), expectV6)
}
func getPrefix(UInt8)
public open func getPrefix(prefixLen: UInt8): IPPrefix
功能:此 IPAddress 地址对象根据指定的网络前缀长度创建一个网络前缀对象。
参数:
- prefixLen: UInt8 - 网络前缀长度。
异常:
- IllegalArgumentException - 如果 prefixLen 大小超出范围,抛出异常。
返回值:
- IPPrefix - 网络前缀对象。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let prefix: IPPrefix = IPAddress.parse("192.168.1.2").getPrefix(24)
@Assert(prefix.toString(), "192.168.1.2/24")
}
func hashCode()
public func hashCode(): Int64
功能:获取 hashcode 值。
返回值:
- Int64 -
hashcode值。
func isGlobalUnicast()
public open func isGlobalUnicast(): Bool
功能:判断此 IPAddress 对象是不是全局单播地址。
返回值:
- Bool - 返回 true 表示是全局单播地址,否则返回 false。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
// 2000::/3
@Assert(IPAddress.parse("2001:250:1006:dff0:4913:2aa5:8075:7c10").isGlobalUnicast(), true)
}
func isIPv4()
public func isIPv4(): Bool
功能:判断此 IPAddress 对象是不是 IPv4 地址。
返回值:
- Bool - 返回 true 表示是 IPv4 地址,否则返回 false。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
@Assert(IPAddress.parse("192.168.1.2").isIPv4(), true)
}
func isIPv6()
public func isIPv6(): Bool
功能:判断此 IPAddress 对象是不是 IPv6 地址。
返回值:
- Bool - 返回 true 表示是 IPv6 地址,否则返回 false。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
@Assert(IPAddress.parse("2001:250:1006:dff0:4913:2aa5:8075:7c10").isIPv6(), true)
}
func isLinkLocal()
public open func isLinkLocal(): Bool
功能:判断此 IPAddress 对象是不是链路本地地址。
返回值:
- Bool - 返回 true 表示是链路本地地址,否则返回 false。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
// 169.254.0.0 ~ 169.254.255.255
@Assert(IPAddress.parse("169.254.0.1").isLinkLocal(), true)
// fe80::/10
@Assert(IPAddress.parse("fe80::1").isLinkLocal(), true)
}
func isLoopback()
public open func isLoopback(): Bool
功能:判断此 IPAddress 对象是不是环回地址。
返回值:
- Bool - 返回 true 表示是环回地址,否则返回 false。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
@Assert(IPAddress.parse("127.0.0.1").isLoopback(), true)
@Assert(IPAddress.parse("::1").isLoopback(), true)
}
func isMulticast()
public open func isMulticast(): Bool
功能:判断此 IPAddress 对象是不是多播地址。
返回值:
- Bool - 返回 true 表示是多播地址,否则返回 false。
func isPrivate()
public open func isPrivate(): Bool
功能:判断此 IPAddress 对象是不是私有地址。
返回值:
- Bool - 返回 true 表示是私有地址,否则返回 false。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
// 10.0.0.0 ~ 10.255.255.255
@Assert(IPAddress.parse("10.0.0.1").isPrivate(), true)
// 172.16.0.0 ~ 172.31.255.255
@Assert(IPAddress.parse("172.16.0.1").isPrivate(), true)
// 192.168.0.0 ~192.168.255.255
@Assert(IPAddress.parse("192.168.0.1").isPrivate(), true)
// fc00::/7
@Assert(IPAddress.parse("fc00::1").isPrivate(), true)
}
func isUnspecified()
public open func isUnspecified(): Bool
功能:判断此 IPAddress 对象是不是“未指定” IP 地址。
返回值:
- Bool - 返回 true 表示是“未指定” IP 地址,否则返回 false。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
@Assert(IPAddress.parse("0.0.0.0").isUnspecified(), true)
@Assert(IPAddress.parse("::").isUnspecified(), true)
}
func writeBigEndian(Array<Byte>)
public open func writeBigEndian(buffer: Array<Byte>): Int64
功能:返回此 IPAddress 对象以大端序的方式写入字节数组中。
参数:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以写入 IPv4Address 或 IPv6Address 值时,抛出异常。
返回值:
- Int64 - 写入的数据的字节数。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let buffer = Array<Byte>(128, repeat: 0)
let expectV4: Array<Byte> = [0xC0, 0xA8, 0x1, 0x2]
let expectV6: Array<Byte> = [0x20, 0x01, 0x02, 0x50, 0x10, 0x06, 0xdf, 0xf0, 0x49, 0x13, 0x2a, 0xa5, 0x80, 0x75, 0x7c, 0x10]
let v4: IPAddress = IPAddress.parse("192.168.1.2")
let v6: IPAddress = IPAddress.parse("2001:0250:1006:dff0:4913:2aa5:8075:7c10")
var len = v4.writeBigEndian(buffer)
@Assert(buffer[..len], expectV4)
len = v6.writeBigEndian(buffer)
@Assert(buffer[..len], expectV6)
}
operator func ==(IPAddress)
public operator func ==(rhs: IPAddress): Bool
功能:判断两个 IPAddress 对象是否相等。
参数:
返回值:
operator func !=(IPAddress)
public operator func !=(rhs: IPAddress): Bool
功能:判断两个 IPAddress 对象是否不等。
参数:
返回值:
class IPPrefix
abstract sealed class IPPrefix <: Equatable<IPPrefix> & Hashable & ToString
功能:这个类表示一个 IP 前缀,即一个连续的 IP 地址块,边界为2的幂(也称为“IP子网”)。
一个 IP 前缀由两条信息指定:
- 起始IP地址(IPv4或IPv6)。这是前缀的第一个IP地址。
- 前缀长度。这通过指定IP地址中的位数来指定前缀的长度,从网络字节顺序中的最高有效位开始,对于前缀中的所有地址都是恒定的。
例如,前缀 192.0.2.0/24 涵盖从192.0.2.0到192.0.2.255(含)的256个IPv4地址,前缀2001:db8:1:2涵盖从2001:db8:1:2:: 到 2001:db8:1:2:ffff:ffff:ffff:ffff(含)的2^64个IPv6地址。这个类的对象是不可变的。
父类型:
prop address
public prop address: IPAddress
功能:获取构造当前 IPPrefix 对象时的 IPAddress 地址。
类型:IPAddress
prop prefixLength
public prop prefixLength: UInt8
功能:获取前缀长度。
类型:UInt8
static func parse(String)
public static func parse(s: String): IPPrefix
功能:将 IP 协议的 Socket 字符串转换为 IPPrefix 对象。
参数:
- s: String - IP 协议的 Socket 字符串。
异常:
- IllegalFormatException - 如果不是合法字符串,抛出异常。
返回值:
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let v4: IPPrefix = IPPrefix.parse("192.168.1.2/24")
let v6: IPPrefix = IPPrefix.parse("2001:0250:1006:dff0:4913:2aa5:8075:7c10/32")
@Assert(v4.toString(), "192.168.1.2/24")
@Assert(v6.toString(), "2001:250:1006:dff0:4913:2aa5:8075:7c10/32")
}
static func tryParse(String)
public static func tryParse(s: String): ?IPPrefix
功能:将 IP 协议的 Socket 字符串转换为 IPPrefix 对象,如果不是合法字符串,则返回 None。
参数:
- s: String - IP 协议的 Socket 字符串。
返回值:
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let v4: ?IPPrefix = IPPrefix.tryParse("192.168.1.2/24")
let v6: ?IPPrefix = IPPrefix.tryParse("2001:0250:1006:dff0:4913:2aa5:8075:7c10/32")
@Assert(v4.toString(), "Some(192.168.1.2/24)")
@Assert(v6.toString(), "Some(2001:250:1006:dff0:4913:2aa5:8075:7c10/32)")
}
func broadcast()
public open func broadcast(): IPAddress
功能:返回此 IPPrefix 地址的广播地址。
返回值:
func contains(IPAddress)
public func contains(rhs: IPAddress): Bool
功能:此 IPPrefix 地址是不是包含指定的 IPAddress 地址。
参数:
返回值:
func contains(IPPrefix)
public func contains(rhs: IPPrefix): Bool
功能:此 IPPrefix 地址是不是包含指定的 IPPrefix 地址。
参数:
返回值:
func hostmask()
public open func hostmask(): IPAddress
功能:返回此 IPPrefix 地址的主机网络掩码地址。
返回值:
func masked()
public open func masked(): IPPrefix
功能:返回此 IPPrefix 地址根据前缀长度进行掩码后的 IPPrefix 地址,比如 192.168.12.34/16 返回 192.168.0.0/16; fc00::1:2:3:4/16 返回 fc00::/16。
返回值:
func netmask()
public open func netmask(): IPAddress
功能:返回此 IPPrefix 地址的网络掩码地址。
返回值:
func network()
public open func network(): IPAddress
功能:返回此 IPPrefix 地址的网络地址。
返回值:
func overlaps(IPPrefix)
public func overlaps(rhs: IPPrefix): Bool
功能:此 IPPrefix 地址是不是和指定的 IPPrefix 地址有重叠。
参数:
返回值:
func toString()
public func toString(): String
功能:返回当前 IPPrefix 的文本表示字符串。
返回值:
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let v4: IPPrefix = IPAddress.parse("192.168.1.2").getPrefix(24)
let v6: IPPrefix = IPAddress.parse("2001:0250:1006:dff0:4913:2aa5:8075:7c10").getPrefix(32)
@Assert(v4.toString(), "192.168.1.2/24")
@Assert(v6.toString(), "2001:250:1006:dff0:4913:2aa5:8075:7c10/32")
}
operator func ==(IPPrefix)
public operator func ==(rhs: IPPrefix): Bool
功能:判断两个 IPPrefix 对象是否相等。
参数:
返回值:
operator func !=(IPPrefix)
public operator func !=(rhs: IPPrefix): Bool
功能:判断两个 IPPrefix 对象是否不等。
参数:
返回值:
class IPSocketAddress
public class IPSocketAddress <: SocketAddress & Equatable<IPSocketAddress>{
public init(address: Array<Byte>, port: UInt16)
public init(address: String, port: UInt16)
public init(address: IPAddress, port: UInt16)
}
功能:此类实现了IP协议 Socket 地址(IP地址+端口号)。它提供了一个不可变的对象,用于 Socket 的绑定、连接或作为返回值。
父类型:
prop address
public prop address: IPAddress
功能:获取当前 IPSocketAddress 对象的 IP 地址。
类型:IPAddress
prop family
public prop family: AddressFamily
功能:获取当前 IPSocketAddress 对象的地址族。
prop port
public prop port: UInt16
功能:获取当前 IPSocketAddress 对象的端口。
类型:UInt16
prop size
public prop size: Int64
功能:获取当前 IPSocketAddress 对象的原始字节长度。
类型:Int64
init(Array<Byte>, UInt16)
public init(address: Array<Byte>, port: UInt16)
功能:根据大端序 Array<Byte> 表示的 IP 地址和本机序 UInt16 端口构造 IPSocketAddress 地址。
参数:
异常:
- IllegalArgumentException - 如果 address 不合法,抛出异常。
init(String, UInt16)
public init(address: String, port: UInt16)
功能:根据字符串表示的 IP 地址和 本机序 UInt16 端口构造 IPSocketAddress 地址。
参数:
异常:
- IllegalFormatException - 如果传入的 IP 地址不合法,抛出异常。
init(IPAddress, UInt16)
public init(address: IPAddress, port: UInt16)
功能:根据 IPAddress 对象和 本机序 UInt16 端口构造 IPSocketAddress 地址。
参数:
static func parse(String)
public static func parse(s: String): IPSocketAddress
功能:将 IP 协议的 Socket 字符串转换为 IPSocketAddress 对象。
参数:
- s: String - IP 协议的 Socket 字符串。
返回值:
异常:
- IllegalFormatException - 入参需要是合法的socket地址,比如 192.168.0.0:80 或 [fc00::1]:8080,否则抛出异常。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let v4: IPSocketAddress = IPSocketAddress.parse("192.168.1.2:8080")
let v6: IPSocketAddress = IPSocketAddress.parse("[2001:0250:1006:dff0:4913:2aa5:8075:7c10]:8080")
@Assert(v4.address.toString(), "192.168.1.2")
@Assert(v4.port, 8080u16)
@Assert(v6.address.toString(), "2001:250:1006:dff0:4913:2aa5:8075:7c10")
@Assert(v6.port, 8080u16)
@Assert(v4.toString(), "192.168.1.2:8080")
@Assert(v6.toString(), "[2001:250:1006:dff0:4913:2aa5:8075:7c10]:8080")
}
static func tryParse(String)
public static func tryParse(s: String): ?IPSocketAddress
功能:将 IP 协议的 Socket 字符串转换为 IPSocketAddress 对象,如果不是合法字符串,则返回 None。
参数:
- s: String - IP 协议的 Socket 字符串。
返回值:
- ?IPSocketAddress - ?IPSocketAddress 对象。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let v4: ?IPSocketAddress = IPSocketAddress.tryParse("192.168.1.2:8080")
let v6: ?IPSocketAddress = IPSocketAddress.tryParse("[2001:0250:1006:dff0:4913:2aa5:8075:7c10]:8080")
@Assert(v4.toString(), "Some(192.168.1.2:8080)")
@Assert(v6.toString(), "Some([2001:250:1006:dff0:4913:2aa5:8075:7c10]:8080)")
}
func getAddressBytes()
public func getAddressBytes(): Array<Byte>
功能:返回此 IPSocketAddress 对象的原始地址的 Array<Byte> 表示,内容布局与 sockaddr_in 或 sockaddr_in6 一致。
返回值:
- Array<Byte> - IPSocketAddress 对象的原始地址的 Array<Byte> 表示。
func hashCode()
public func hashCode(): Int64
功能:获取 hashcode 值。
返回值:
- Int64 -
hashcode值。
func isIPv4()
public func isIPv4(): Bool
功能:判断此 IPSocketAddress 对象是不是 IPv4 Socket 地址。
返回值:
- Bool - 返回 true 表示是 IPv4 地址,否则返回 false。
func isIPv6()
public func isIPv6(): Bool
功能:判断此 IPSocketAddress 对象是不是 IPv6 Socket 地址。
返回值:
- Bool - 返回 true 表示是 IPv6 地址,否则返回 false。
func toString()
public func toString(): String
功能:返回当前 IPSocketAddress 的文本表示字符串。
返回值:
- String - 当前 IPSocketAddress 的文本表示字符串,比如
192.168.1.2:8080或[fc00::/16]:8080。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let v4: IPSocketAddress = IPSocketAddress.parse("192.168.1.2:8080")
let v6: IPSocketAddress = IPSocketAddress.parse("[2001:0250:1006:dff0:4913:2aa5:8075:7c10]:8080")
@Assert(v4.toString(), "192.168.1.2:8080")
@Assert(v6.toString(), "[2001:250:1006:dff0:4913:2aa5:8075:7c10]:8080")
}
operator func ==(IPSocketAddress)
public operator func ==(rhs: IPSocketAddress): Bool
功能:判断两个 IPSocketAddress 对象是否相等。
参数:
- rhs: IPSocketAddress - 参与比较的 IPSocketAddress 对象。
返回值:
- Bool - 如果两个 IPSocketAddress 对象相等,则返回
true;否则,返回false。
operator func !=(IPSocketAddress)
public operator func !=(rhs: IPSocketAddress): Bool
功能:判断两个 IPSocketAddress 对象是否不等。
参数:
- rhs: IPSocketAddress - 参与比较的 IPSocketAddress 对象。
返回值:
- Bool - 如果两个 IPSocketAddress 对象不等,则返回
true;否则,返回false。
class IPv4Address
public class IPv4Address <: IPAddress & ToString & Equatable<IPv4Address> & LessOrEqual<IPv4Address> {
public static let broadcast = IPv4Address(0xFF, 0xFF, 0xFF, 0xFF)
public static let localhost = IPv4Address(0x7F, 0, 0, 0x01)
public static let unspecified = IPv4Address(0, 0, 0, 0)
public init(bits: UInt32)
public init(a: Byte, b: Byte, c: Byte, d: Byte)
}
功能:此类表示 Internet 协议版本4 (IPv4)地址。由 RFC 790、RFC 1918 和 RFC 2365 定义。
父类型:
static let broadcast
public static let broadcast = IPv4Address(0xFF, 0xFF, 0xFF, 0xFF)
功能:返回 IPv4Address 的广播地址:255.255.255.255。
类型:IPv4Address
static let localhost
public static let localhost = IPv4Address(0x7F, 0, 0, 0x01)
功能:返回 IPv4Address 的 localhost 地址:127.0.0.1。
类型:IPv4Address
static let unspecified
public static let unspecified = IPv4Address(0, 0, 0, 0)
功能:返回表示未指定的 IPv4Address 地址:0.0.0.0,这对应于其他语言中的常量 INADDR_ANY。
类型:IPv4Address
init(UInt32)
public init(bits: UInt32)
功能:根据本机字节序 UInt32 值构造 IPv4Address 地址。
参数:
init(Byte, Byte, Byte, Byte)
public init(a: Byte, b: Byte, c: Byte, d: Byte)
功能:根据4 个 8-bit 字节构造 IPv4Address 地址对象,文本将表示为 a.b.c.d。
参数:
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): IPv4Address
功能:从字节数组中以大端序的方式读取一个 IPv4Address 对象。
参数:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 IPv4Address 值时,抛出异常。
返回值:
- IPv4Address - IPv4Address 对象。
func getPrefix(UInt8)
public func getPrefix(prefixLen: UInt8): IPPrefix
功能:将 IPv4Address 地址根据指定的网络前缀长度创建一个网络前缀对象。
参数:
- prefixLen: UInt8 - 网络前缀长度,必须 >= 0 且 <= 32。
异常:
- IllegalArgumentException - 如果 prefixLen 大小超出范围,抛出异常。
返回值:
- IPPrefix - 网络前缀对象。
func isBroadcast()
public func isBroadcast(): Bool
功能:判断此 IPv4Address 对象是不是广播地址。
返回值:
- Bool - 返回 true 表示是广播地址,否则返回 false。
func isGlobalUnicast()
public func isGlobalUnicast(): Bool
功能:判断此 IPv4Address 对象是不是全局单播地址。
返回值:
- Bool - 返回 true 表示是全局单播地址,否则返回 false。
func isLinkLocal()
public func isLinkLocal(): Bool
功能:判断此 IPv4Address 对象是不是链路本地地址。
返回值:
- Bool - 返回 true 表示是链路本地地址,否则返回 false。
func isLoopback()
public func isLoopback(): Bool
功能:判断此 IPv4Address 对象是不是环回地址。
返回值:
- Bool - 返回 true 表示是环回地址,否则返回 false。
func isMulticast()
public func isMulticast(): Bool
功能:判断此 IPv4Address 对象是不是多播地址。
返回值:
- Bool - 返回 true 表示是多播地址,否则返回 false。
func isPrivate()
public func isPrivate(): Bool
功能:判断此 IPv4Address 对象是不是私有地址。
返回值:
- Bool - 返回 true 表示是私有地址,否则返回 false。
func isUnspecified()
public func isUnspecified(): Bool
功能:判断此 IPv4Address 对象是不是“未指定” IP 地址。
返回值:
- Bool - 返回 true 表示是“未指定” IP 地址,否则返回 false。
func toBits()
public func toBits(): UInt32
功能:此 IPv4Address 地址转换为本机字节序的 UInt32 值。
返回值:
func toIPv6Compatible()
public func toIPv6Compatible(): IPv6Address
功能:此 IPv4Address 地址转换为 IPv4 兼容的 IPv6Address 地址。a.b.c.d 变为 ::a.b.c.d。
返回值:
- IPv6Address - IPv6Address 对象。
func toIPv6Mapped()
public func toIPv6Mapped(): IPv6Address
功能:此 IPv4Address 地址转换为 IPv4 映射的 IPv6Address 地址。a.b.c.d 变为 ::ffff:a.b.c.d。
返回值:
- IPv6Address - IPv6Address 对象。
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:此 IPv4Address 对象以大端序的方式写入字节数组中。
参数:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以写入 IPv4Address 值时,抛出异常。
返回值:
- Int64 - 写入的数据的字节数。
func toString()
public func toString(): String
功能:返回当前 IPv4Address 的文本表示字符串。
返回值:
- String - 当前 IPv4Address 的文本表示字符串,比如
a.b.c.d。
operator func <=(IPv4Address)
public operator func <=(rhs: IPv4Address): Bool
功能:判断本 IPv4Address 对象是否小于等于被比较的 IPv4Address 对象。
参数:
- rhs: IPv4Address - 被比较的 IPv4Address 对象。
返回值:
- Bool - 如果本 IPv4Address 对象小于等于被比较的 IPv4Address 对象,则返回
true;否则,返回false。
operator func ==(IPv4Address)
public operator func ==(rhs: IPv4Address): Bool
功能:判断两个 IPv4Address 对象是否相等。
参数:
- rhs: IPv4Address - 参与比较的 IPv4Address 对象。
返回值:
- Bool - 如果两个 IPv4Address 对象相等,则返回
true;否则,返回false。
operator func !=(IPv4Address)
public operator func !=(rhs: IPv4Address): Bool
功能:判断两个 IPv4Address 对象是否不等。
参数:
- rhs: IPv4Address - 参与比较的 IPv4Address 对象。
返回值:
- Bool - 如果两个 IPv4Address 对象不等,则返回
true;否则,返回false。
class IPv6Address
public class IPv6Address <: IPAddress & ToString & Equatable<IPv6Address> & LessOrEqual<IPv6Address> {
public static let localhost = IPv6Address(0u16, 0, 0, 0, 0, 0, 0, 1)
public static let unspecified = IPv6Address(0u16, 0, 0, 0, 0, 0, 0, 0)
public init(octets: Array<Byte>, scopeId!: ?UInt32 = None)
public init(a: UInt16, b: UInt16, c: UInt16, d: UInt16, e: UInt16, f: UInt16, g: UInt16, h: UInt16, scopeId!: ?UInt32 = None)
}
功能:此类表示 Internet 协议版本6 (IPv6)地址。由 RFC4291、RFC5952、RFC4007 定义。
父类型:
static let localhost
public static let localhost = IPv6Address(0u16, 0, 0, 0, 0, 0, 0, 1)
功能:返回 IPv6Address 的 localhost 地址:::1。
类型:IPv6Address
static let unspecified
public static let unspecified = IPv6Address(0u16, 0, 0, 0, 0, 0, 0, 0)
功能:返回表示未指定的 IPv6Address 地址:::,这对应于其他语言中的常量 INADDR_ANY。
类型:IPv6Address
prop scopeId
public prop scopeId: ?UInt32
功能:获取默认范围 ID。
init(Array<Byte>, ?UInt32)
public init(octets: Array<Byte>, scopeId!: ?UInt32 = None)
功能:根据大端序 Array<Byte> 构造 IPv6Address 地址。
异常:
- IllegalArgumentException - 如果 octets 长度小于 16,抛出异常。
参数:
init(UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, ?UInt32)
public init(a: UInt16, b: UInt16, c: UInt16, d: UInt16, e: UInt16, f: UInt16, g: UInt16, h: UInt16, scopeId!: ?UInt32 = None)
功能:根据 8 个 16-bit 分段构造 IPv6Address 地址对象,文本将表示为 a:b:c:d:e:f:g:h%scopeId。
参数:
- a: UInt16 - 16-bit 分段。
- b: UInt16 - 16-bit 分段。
- c: UInt16 - 16-bit 分段。
- d: UInt16 - 16-bit 分段。
- e: UInt16 - 16-bit 分段。
- f: UInt16 - 16-bit 分段。
- g: UInt16 - 16-bit 分段。
- h: UInt16 - 16-bit 分段。
- scopeId!: ?UInt32 - 范围 ID。
static func readBigEndian(Array<Byte>)
public static func readBigEndian(buffer: Array<Byte>): IPv6Address
功能:从字节数组中以大端序的方式读取一个 IPv6Address 对象。
参数:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以读出 IPv6Address 值时,抛出异常。
返回值:
- IPv6Address - IPv6Address 对象。
func getPrefix(UInt8)
public func getPrefix(prefixLen: UInt8): IPPrefix
功能:此 IPv6Address 地址对象根据指定的网络前缀长度创建一个网络前缀对象。
参数:
- prefixLen: UInt8 - 网络前缀长度,必须 >= 0 且 <= 128。
异常:
- IllegalArgumentException - 如果 prefixLen 大小超出范围,抛出异常。
返回值:
- IPPrefix - 网络前缀对象。
func isGlobalUnicast()
public func isGlobalUnicast(): Bool
功能:判断此 IPv6Address 对象是不是全局单播地址。
返回值:
- Bool - 返回 true 表示是全局单播地址,否则返回 false。
func isIPv4Mapped()
public func isIPv4Mapped(): Bool
功能:判断此 IPv6Address 对象是不是 IPv4 映射地址。
返回值:
- Bool - 返回 true 表示是 IPv4 映射地址,否则返回 false。
func isLinkLocal()
public func isLinkLocal(): Bool
功能:判断此 IPv6Address 对象是不是链路本地地址。
返回值:
- Bool - 返回 true 表示是链路本地地址,否则返回 false。
func isLoopback()
public func isLoopback(): Bool
功能:判断此 IPv6Address 对象是不是环回地址。
返回值:
- Bool - 返回 true 表示是环回地址,否则返回 false。
func isMulticast()
public func isMulticast(): Bool
功能:判断此 IPv6Address 对象是不是多播地址。
返回值:
- Bool - 返回 true 表示是多播地址,否则返回 false。
func isPrivate()
public func isPrivate(): Bool
功能:判断此 IPv6Address 对象是不是私有地址。
返回值:
- Bool - 返回 true 表示是私有地址,否则返回 false。
func isTeredo()
public func isTeredo(): Bool
功能:判断此 IPv6Address 对象是不是 Teredo 地址。Teredo 前缀为 2001::/32。
返回值:
- Bool - 返回 true 表示是
Teredo地址,否则返回 false。
func isUnspecified()
public func isUnspecified(): Bool
功能:判断此 IPv6Address 对象是不是“未指定” IP 地址。
返回值:
- Bool - 返回 true 表示是“未指定” IP 地址,否则返回 false。
func scope(?UInt32)
public func scope(scopeId: ?UInt32): IPv6Address
功能:使用本 IPv6Address 对象的地址值和指定的范围 ID 转换为新的 IPv6Address 对象,如果指定的范围 ID 为 None,则去除已有的范围 ID。
参数:
- scopeId: ?UInt32 - 范围 ID。
返回值:
- IPv6Address - 转换后的 IPv6Address 对象。
func toIPv4()
public func toIPv4(): ?IPv4Address
功能:此 IPv6Address 地址转换为 IPv4 兼容的 IPv4Address 地址。比如 ::a.b.c.d 和 ::ffff:a.b.c.d 转成 a.b.c.d; ::1 转成 0.0.0.1. 所有不以全零或 ::ffff 开头的地址将返回 None。
返回值:
- ?IPv4Address - ?IPv4Address 值。
func toIPv4Mapped()
public func toIPv4Mapped(): ?IPv4Address
功能:此 IPv6Address 地址转换为 IPv4 映射的 IPv4Address 地址。比如 ::ffff:a.b.c.d 转换为 a.b.c.d, 所有不以 ::ffff 开头的地址将返回 None。
返回值:
- ?IPv4Address - ?IPv4Address 值。
func writeBigEndian(Array<Byte>)
public func writeBigEndian(buffer: Array<Byte>): Int64
功能:返回此 IPv6Address 对象以大端序的方式写入字节数组中。
参数:
异常:
- IllegalArgumentException - 当 buffer 太小,不足以写入 IPv6Address 值时,抛出异常。
返回值:
- Int64 - 写入的数据的字节数。
func toString()
public func toString(): String
功能:返回当前 IPv6Address 的文本表示字符串。
返回值:
- String - 当前 IPv6Address 的文本表示字符串,比如
2001:db8:1:2:ffff:ffff:ffff:ffff。
operator func <=(IPv6Address)
public operator func <=(rhs: IPv6Address): Bool
功能:判断本 IPv6Address 对象是否小于等于被比较的 IPv6Address 对象。
参数:
- rhs: IPv6Address - 参与比较的 IPv6Address 对象。
返回值:
- Bool - 如果本 IPv6Address 对象小于等于被比较的 IPv6Address 对象,则返回
true;否则,返回false。
operator func ==(IPv6Address)
public operator func ==(rhs: IPv6Address): Bool
功能:判断两个 IPv6Address 对象是否相等。
参数:
- rhs: IPv6Address - 参与比较的 IPv6Address 对象。
返回值:
- Bool - 如果两个 IPv6Address 对象相等,则返回
true;否则,返回false。
operator func !=(IPv6Address)
public operator func !=(rhs: IPv6Address): Bool
功能:判断两个 IPv6Address 对象是否不等。
参数:
- rhs: IPv6Address - 参与比较的 IPv6Address 对象。
返回值:
- Bool - 如果两个 IPv6Address 对象不等,则返回
true;否则,返回false。
class RawSocket
public class RawSocket {
public init(domain: SocketDomain, `type`: SocketType, protocol: ProtocolType)
}
功能:RawSocket 提供了套接字的基本功能。
可以访问特定通信域(domain)、类型(type)和协议(protocol)组合的套接字。Socket 包已经提供了 TCP、 UDP 等常用网络协议的支持,因此,该类型适用于其他类型的网络编程需求。
注意:
- 当前 RawSocket 已经验证的功能包括 TCP、UDP、UDS 以及 ICMP 协议套接字,其他类型使用上可能存在预期之外的问题。
- 此外,由于接口的开放性,可以使用
connect再listen的组合,部分场景可能存在预期外的问题。建议开发者使用时遵循正常的调用逻辑,避免产生问题。
prop localAddr (deprecated)
public prop localAddr: RawAddress
功能:获取当前 RawSocket 实例的本地地址。
注意:
未来版本即将废弃不再使用,使用 localAddress 替代。
类型:RawAddress
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或无法获取本地地址时,抛出异常。
prop localAddress
public prop localAddress: RawAddress
功能:获取当前 RawSocket 实例的本地地址。
类型:RawAddress
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或无法获取本地地址时,抛出异常。
prop readTimeout
public mut prop readTimeout: ?Duration
功能:获取或设置当前 RawSocket 实例的读超时时间。
类型:?Duration
异常:
- SocketException - 当前 RawSocket 实例已经关闭时,抛出异常。
- IllegalArgumentException - 当设置的读超时时间为负时,抛出异常。
prop remoteAddr (deprecated)
public prop remoteAddr: RawAddress
功能:获取当前 RawSocket 实例的对端地址。
注意:
未来版本即将废弃不再使用,使用 remoteAddress 替代。
类型:RawAddress
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或无法获取对端地址时,抛出异常。
prop remoteAddress
public prop remoteAddress: RawAddress
功能:获取当前 RawSocket 实例的对端地址。
类型:RawAddress
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或无法获取对端地址时,抛出异常。
prop writeTimeout
public mut prop writeTimeout: ?Duration
功能:获取或设置当前 RawSocket 实例的写超时时间。
类型:?Duration
异常:
- SocketException - 当前 RawSocket 实例已经关闭时,抛出异常。
- IllegalArgumentException - 当设置的写超时时间为负时,抛出异常。
init(SocketDomain, SocketType, ProtocolType)
public init(domain: SocketDomain, `type`: SocketType, protocol: ProtocolType)
功能:创建特定通信域、类型、协议组合的套接字。
参数:
- domain: SocketDomain - 通信域。
- `type`: SocketType - 套接字类型。
- protocol: ProtocolType - 协议类型。
异常:
- SocketException - 当通信域、类型、协议组合无法创建套接字时,抛出异常。
func accept(?Duration)
public func accept(timeout!: ?Duration = None): RawSocket
功能:接收当前 RawSocket 实例监听时挂起连接队列上的第一个连接请求,返回一个用于通信的 RawSocket。
参数:
- timeout!: ?Duration - 等待连接请求的最大时间,默认值
None表示一直等待。
返回值:
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或接收失败时,抛出异常。
- SocketTimeoutException - 当等待超时时,抛出异常。
func bind(RawAddress)
public func bind(addr: RawAddress): Unit
功能:将当前 RawSocket 实例与指定的套接字地址进行绑定。
参数:
- addr: RawAddress - 套接字地址。
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或绑定失败时,抛出异常。
func close()
public func close(): Unit
功能:关闭当前 RawSocket 实例。
func connect(RawAddress, ?Duration)
public func connect(addr: RawAddress, timeout!: ?Duration = None): Unit
功能:向目标地址发送连接请求。
参数:
- addr: RawAddress - 发送连接请求的目标地址。
- timeout!: ?Duration - 等待连接接收的最大时间,默认值
None表示一直等待。
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或接收失败时,抛出异常。
- SocketTimeoutException - 当等待超时时,抛出异常。
func getSocketOption(Int32, Int32, CPointer<Byte>, CPointer<Int32>)
public unsafe func getSocketOption(level: Int32, option: Int32, value: CPointer<Byte>, len: CPointer<Int32>): Unit
功能:获取套接字选项的值。
参数:
- level: Int32 - 套接字选项级别。
- option: Int32 - 套接字选项名。
- value: CPointer<Byte> - 套接字选项值。
- len: CPointer<Int32> - 套接字选项值的长度。
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或获取套接字选项失败时,抛出异常。
func listen(Int32)
public func listen(backlog: Int32): Unit
功能:监听当前 RawSocket 实例绑定的地址。
参数:
- backlog: Int32 - 等待队列增长的最大长度。
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或监听失败时,抛出异常。
func receive(Array<Byte>, Int32)
public func receive(buffer: Array<Byte>, flags: Int32): Int64
功能:接收来自连接对端发送的数据。
参数:
返回值:
- Int64 - 数据长度。
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或接收数据失败时,抛出异常。
- SocketTimeoutException - 当超过指定的读超时时间时,抛出异常。
func receiveFrom(Array<Byte>, Int32)
public func receiveFrom(buffer: Array<Byte>, flags: Int32): (RawAddress, Int64)
功能:接收来自其他 RawSocket 实例的数据。
参数:
返回值:
- (RawAddress, Int64) - 数据来源的地址和数据长度。
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或接收数据失败时,抛出异常。
- SocketTimeoutException - 当超过指定的读超时时间时,抛出异常。
func send(Array<Byte>, Int32)
public func send(buffer: Array<Byte>, flags: Int32): Unit
功能:向连接的对端发送数据。
参数:
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或发送数据失败时,抛出异常。
- SocketTimeoutException - 当超过指定的写超时时间时,抛出异常。
func sendTo(RawAddress, Array<Byte>, Int32)
public func sendTo(addr: RawAddress, buffer: Array<Byte>, flags: Int32): Unit
功能:向目标地址发送数据。若 RawSocket 是 DATAGRAM 类型,发送的数据包大小不允许超过 65507 字节。
参数:
- addr: RawAddress - 发送数据的目标地址。
- buffer: Array<Byte> - 数据。
- flags: Int32 - 指定函数行为的标志。
异常:
- SocketException - 当前 RawSocket 实例已经关闭、发送数据失败或者 macOS 平台下
connect被调用后调用sendTo时,抛出异常。 - SocketTimeoutException - 当超过指定的写超时时间时,抛出异常。
func setSocketOption(Int32, Int32, CPointer<Byte>, Int32)
public unsafe func setSocketOption(level: Int32, option: Int32, value: CPointer<Byte>, len: Int32): Unit
功能:设置套接字选项。
参数:
- level: Int32 - 套接字选项级别。
- option: Int32 - 套接字选项名。
- value: CPointer<Byte> - 套接字选项值。
- len: Int32 - 套接字选项值的长度。
异常:
- SocketException - 当前 RawSocket 实例已经关闭,或设置套接字选项失败时,抛出异常。
class SocketAddress
abstract sealed class SocketAddress <: ToString & Equatable<SocketAddress> & Hashable
功能:此类表示协议无关的 Socket 地址。它提供了一个不可变的对象,用于 Socket 的绑定、连接或作为返回值。
父类型:
prop size
public prop size: Int64
功能:当前 SocketAddress 对象的原始字节长度。
类型:Int64
prop family
public prop family: AddressFamily
功能:当前 SocketAddress 对象的地址族。
func getAddressBytes()
public func getAddressBytes(): Array<Byte>
功能:返回此 SocketAddress 对象的原始IP地址。
返回值:
operator func ==(SocketAddress)
public operator func ==(rhs: SocketAddress): Bool
功能:判断两个 SocketAddress 对象是否相等。
参数:
- rhs: SocketAddress - 参与比较的 SocketAddress 对象。
返回值:
- Bool - 如果两个 SocketAddress 对象相等,则返回
true;否则,返回false。
operator func !=(SocketAddress)
public operator func !=(rhs: SocketAddress): Bool
功能:判断两个 SocketAddress 对象是否不等。
参数:
- rhs: SocketAddress - 参与比较的 SocketAddress 对象。
返回值:
- Bool - 如果两个 SocketAddress 对象不等,则返回
true;否则,返回false。
class TcpServerSocket
public class TcpServerSocket <: ServerSocket {
public init(bindAt!: SocketAddress)
public init(bindAt!: UInt16)
}
功能:监听 TCP 连接的服务端。
套接字被创建后,可通过属性和 setSocketOptionXX 接口配置属性。
启动监听需要调用 bind() 将套接字绑定到本地端口。accept() 接口将接受 TCP 连接,阻塞等待连接,若队列中已有连接,则可立即返回。
套接字需要通过 close 显式关闭。
父类型:
prop backlogSize
public mut prop backlogSize: Int64
功能:设置和读取 backlog 大小。
仅可在调用 bind 前调用,否则将抛出异常。
变量是否生效取决于系统行为。
类型:Int64
异常:
- SocketException - 当在
bind后调用时,抛出异常。
prop bindToDevice
public mut prop bindToDevice: ?String
功能:设置和读取绑定网卡。
类型:?String
prop localAddress
public override prop localAddress: SocketAddress
功能:读取 Socket 将要或已经被绑定的本地地址。
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
prop receiveBufferSize
public mut prop receiveBufferSize: Int64
功能:设置和读取 SO_RCVBUF 属性。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop reuseAddress
public mut prop reuseAddress: Bool
功能:设置和读取 SO_REUSEADDR 属性,默认设置为 true。
属性生效后的行为取决于系统,使用前,请参阅不同系统针对此属性 SO_REUSEADDR/SOCK_REUSEADDR 的说明文档。
类型:Bool
prop reusePort
public mut prop reusePort: Bool
功能:设置和读取 SO_REUSEPORT 属性。
仅可在绑定前被修改。Windows 上可使用 SO_REUSEADDR,无该属性,抛出异常。
属性默认及配置生效后的行为取决于系统,使用前,请参阅不同系统针对此属性 SO_REUSEPORT 的说明文档。
同时开启 SO_REUSEADDR/SO_REUSEPORT 会导致不可预知的系统错误,用户需谨慎配置值。
类型:Bool
异常:
- SocketException - Windows 上不支持此类型,抛出异常。
prop sendBufferSize
public mut prop sendBufferSize: Int64
功能:设置和读取 SO_SNDBUF 属性。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
init(SocketAddress)
public init(bindAt!: SocketAddress)
功能:创建一个 TcpServerSocket 实例,尚未绑定,因此客户端无法连接。
参数:
- bindAt!: SocketAddress - 指定本地绑定地址,端口号设置为 0 表示随机绑定空闲的本地地址。
init(UInt16)
public init(bindAt!: UInt16)
功能:创建一个 TcpServerSocket 实例,尚未绑定,因此客户端无法连接。
参数:
- bindAt!: UInt16 - 指定本地绑定端口,0 表示随机绑定空闲的本地端口。
func accept()
public override func accept(): TcpSocket
功能:监听或接受客户端连接。阻塞等待。
返回值:
- TcpSocket - 客户端套接字。
异常:
- SocketException - 当因系统原因监听失败时,抛出异常。
func accept(?Duration)
public override func accept(timeout!: ?Duration): TcpSocket
功能:监听或接受客户端连接。
参数:
- timeout!: ?Duration - 超时时间。
返回值:
- TcpSocket - 客户端套接字。
异常:
- SocketTimeoutException - 当连接超时,抛出异常。
- SocketException - 当因系统原因监听失败时,抛出异常。
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
func bind()
public override func bind(): Unit
功能:绑定本地端口失败后需要 close 套接字,不支持多次重试。
异常:
- SocketException - 当因系统原因绑定失败时,抛出异常。
func close()
public override func close(): Unit
功能:关闭套接字。接口允许多次调用。
func getSocketOption(Int32, Int32, CPointer<Unit>, CPointer<UIntNative>)
public func getSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: CPointer<UIntNative>
): Unit
功能:获取指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: CPointer<UIntNative> - 参数值长度。
异常:
- SocketException - 当
getsockopt返回失败时,抛出异常。
func getSocketOptionBool(Int32, Int32)
public func getSocketOptionBool(
level: Int32,
option: Int32
): Bool
功能:获取指定的套接字参数。从 IntNative 强转而来。0 => false,非 0 => true。
参数:
返回值:
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func getSocketOptionIntNative(Int32, Int32)
public func getSocketOptionIntNative(
level: Int32,
option: Int32
): IntNative
功能:获取指定的套接字参数。
参数:
返回值:
- IntNative - 获取的套接字参数值。
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func isClosed()
public override func isClosed(): Bool
功能:检查套接字是否关闭。
返回值:
- Bool - 如果已经关闭,返回
true,否则返回false。
func setSocketOption(Int32, Int32, CPointer<Unit>, UIntNative)
public func setSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: UIntNative
): Unit
功能:设置指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: UIntNative - 参数值长度。
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionBool(Int32, Int32,Bool)
public func setSocketOptionBool(
level: Int32,
option: Int32,
value: Bool
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionIntNative(Int32, Int32, IntNative)
public func setSocketOptionIntNative(
level: Int32,
option: Int32,
value: IntNative
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func toString()
public override func toString(): String
功能:返回当前 TcpServerSocket 的状态信息。
返回值:
- String - 包含当前 TcpServerSocket 状态信息的字符串。
class TcpSocket
public class TcpSocket <: StreamingSocket & Equatable<TcpSocket> & Hashable {
public init(address: String, port: UInt16)
public init(address: SocketAddress)
public init(address: SocketAddress, localAddress!: ?SocketAddress)
}
功能:请求 TCP 连接的客户端。
当实例对象被创建后,可使用 connect 函数创建连接,并在结束时显式执行 close 操作。
该类型继承自 StreamingSocket, 可参阅 StreamingSocket 章节获取更多信息。
父类型:
prop bindToDevice
public mut prop bindToDevice: ?String
功能:设置和读取绑定网卡。
类型:?String
prop keepAlive
public mut prop keepAlive: ?SocketKeepAliveConfig
功能:设置和读取保活属性,None 表示关闭保活。
用户未设置时将使用系统默认配置。设置此配置可能会被延迟或被系统忽略,取决于系统的处理能力。
prop linger
public mut prop linger: ?Duration
功能:设置和读取 SO_LINGER 属性,默认值取决于系统,None 表示禁用此选项。
说明:
- 如果
SO_LINGER被设置为Some(v),当套接字关闭时,如果还有等待的字节流,我们将在关闭连接前等待v时间,如果超过时间,字节流还未被发送,连接将会被异常终止(通过 RST 报文关闭)。- 如果
SO_LINGER被设置为None,当套接字关闭时,连接将被立即关闭,如果当前等待发送的字符,使用 FIN-ACK 关闭连接,当还有剩余待发送的字符时,使用 RST 关闭连接。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
prop localAddress
public override prop localAddress: SocketAddress
功能:读取 Socket 将要或已经被绑定的本地地址。
异常:
- SocketException - 当
Socket已经被关闭或无可用的本地地址(本地地址未配置并且套接字未连接)时,抛出异常。
prop noDelay
public mut prop noDelay: Bool
功能:设置和读取 TCP_NODELAY 属性,默认为 true。
这个选项将禁用 Nagel 算法,所有写入字节被无延迟得转发。当属性设置为 false 时,Nagel 算法将在发包前引入延时时间。
类型:Bool
prop quickAcknowledge
public mut prop quickAcknowledge: Bool
功能:设置和读取 TCP_QUICKACK 属性,默认为 false。
这个选项类似于 noDelay,但仅影响 TCP ACK 和第一次响应。不支持 Windows 和 macOS 系统。
类型:Bool
prop readTimeout
public override mut prop readTimeout: ?Duration
功能:设置和读取读操作超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
prop receiveBufferSize
public mut prop receiveBufferSize: Int64
功能:设置和读取 SO_RCVBUF 属性,提供一种方式指定收包缓存大小。选项的生效情况取决于系统。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop remoteAddress
public override prop remoteAddress: SocketAddress
功能:读取 Socket 已经或将要连接的远端地址。
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
prop sendBufferSize
public mut prop sendBufferSize: Int64
功能:设置和读取 SO_SNDBUF 属性,提供一种方式指定发包缓存大小。选项的生效情况取决于系统。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop writeTimeout
public override mut prop writeTimeout: ?Duration
功能:设置和读取写操作超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
init(SocketAddress)
public init(address: SocketAddress)
功能:创建一个未连接的套接字。
参数:
- address: SocketAddress - 即将要连接的地址。
异常:
- SocketException - 当
address参数不合法或者 Windows 平台下地址为全零地址时,抛出异常。
init(SocketAddress, ?SocketAddress)
public init(address: SocketAddress, localAddress!: ?SocketAddress)
功能:创建一个未连接的套接字,并且绑定到指定本地地址,本地地址为 None 时,将随机选定地址去绑定。
此接口当 localAddress 不为 None 时,将默认设置 SO_REUSEADDR 为 true,否则可能导致 "address already in use" 的错误。如果需要变更此配置,可以通过调用 setSocketOptionBool(SocketOptions.SOL_SOCKET, SocketOptions.SO_REUSEADDR, false)。另外,本地地址和远端地址需要均为 IPv4。
参数:
- address: SocketAddress - 即将要连接的地址。
- localAddress!: ?SocketAddress - 绑定的本地地址。
异常:
- SocketException - 当
address参数不合法或者 Windows 平台下地址为全零地址时,抛出异常。
init(String, UInt16)
public init(address: String, port: UInt16)
功能:创建一个未连接的套接字。
参数:
异常:
- SocketException - 当
address参数不合法或者 Windows 平台下地址为全零地址时,抛出异常。
func close()
public func close(): Unit
功能:关闭套接字,所有操作除了 close/isClosed 之外,均不允许再调用。接口允许多次调用。
func connect(?Duration)
public func connect(timeout!: ?Duration = None): Unit
功能:连接远端套接字,会自动绑定本地地址,因此不需要进行额外的绑定操作。
参数:
- timeout!: ?Duration - 连接超时时间,
None表示无超时时间,并且连接操作无重试,当服务端拒绝连接时,将返回连接失败。并且此操作包含了绑定操作,因此无需重复调用bind接口。
异常:
- IllegalArgumentException - 当远端地址不合法或者连接超时时间小于 0 或者超时时间小于 0 时,抛出异常。
- SocketException - 当连接因系统原因(例如:套接字已关闭,没有访问权限,系统错误等)无法建立时,抛出异常。再次调用可能成功。
- SocketTimeoutException - 当连接超时时,抛出异常。
func getSocketOption(Int32, Int32, CPointer<Unit>, CPointer<UIntNative>)
public func getSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: CPointer<UIntNative>
): Unit
功能:读取指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: CPointer<UIntNative> - 参数值长度。
异常:
- SocketException - 当
getsockopt返回失败时,抛出异常。
func getSocketOptionBool(Int32, Int32)
public func getSocketOptionBool(
level: Int32,
option: Int32
): Bool
功能:读取指定的套接字参数。从 IntNative 强转而来。0 => false,非 0 => true。
参数:
返回值:
- Bool - 读取到的参数值。
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func getSocketOptionIntNative(Int32, Int32)
public func getSocketOptionIntNative(
level: Int32,
option: Int32
): IntNative
功能:读取指定的套接字参数。
参数:
返回值:
- IntNative - 参数值。
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func hashCode()
public override func hashCode(): Int64
功能:获取当前 TcpSocket 实例的哈希值。
返回值:
func isClosed()
public func isClosed(): Bool
功能:判断套接字是否通过调用 close 显式关闭。
返回值:
- Bool - 套接字是否已经调用
close显式关闭。是则返回true;否则返回false。
func read(Array<Byte>)
public override func read(buffer: Array<Byte>): Int64
功能:读取报文。超时情况按 readTimeout 决定,详见 readTimeout。
说明:
- 由于系统底层接口差异,如果连接被对端关闭,
read和write接口的行为也有相应的差异。- Windows 系统上,对端关闭连接后,如果本端调用一次
write,会导致清空缓冲区内容,在此基础上再调用read会抛出连接关闭异常。- Linux/macOS 系统上,对端关闭连接后,先调用
write再调用read函数仍会读出缓冲区中的内容。
参数:
返回值:
- Int64 - 读取的数据长度。
异常:
- SocketException - 当
buffer大小为 0 或者因系统原因读取失败时,抛出异常。
func setSocketOption(Int32, Int32, CPointer<Unit>, UIntNative)
public func setSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: UIntNative
): Unit
功能:设置指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: UIntNative - 参数值长度。
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionBool(Int32, Int32, Bool)
public func setSocketOptionBool(
level: Int32,
option: Int32,
value: Bool
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionIntNative(Int32, Int32, IntNative)
public func setSocketOptionIntNative(
level: Int32,
option: Int32,
value: IntNative
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func toString()
public override func toString(): String
功能:返回当前 TcpSocket 的状态信息。
返回值:
func write(Array<Byte>)
public override func write(payload: Array<Byte>): Unit
功能:写入报文。超时情况按 writeTimeout 决定,详见 writeTimeout。
参数:
异常:
- SocketException - 当
buffer大小为 0 或者当因系统原因写入失败时,抛出异常。
operator func !=(TcpSocket)
public override operator func !=(other: TcpSocket): Bool
功能:判断两个 TcpSocket 实例是否不等。
参数:
返回值:
operator func ==(TcpSocket)
public override operator func ==(other: TcpSocket): Bool
功能:判断两个 TcpSocket 实例是否相等。
参数:
返回值:
class UdpSocket
public class UdpSocket <: DatagramSocket {
public init(bindAt!: SocketAddress)
public init(bindAt!: UInt16)
}
功能:提供 udp 报文通信。
UdpSocket 创建实例后,需要调用 bind() 绑定,可在不与远端建连的前提下接受报文。不过,UdpSocket 也可以通过 connect()/disconnect() 接口进行建连。
UDP 协议要求传输报文大小不可超过 64KB 。
UdpSocket 需要被显式 close() 。可以参阅 DatagramSocket 获取更多信息。
父类型:
prop localAddress
public override prop localAddress: SocketAddress
功能:读取 Socket 将要或已经被绑定的本地地址。
异常:
- SocketException - 当
Socket已经被关闭或无可用的本地地址(本地地址未配置并且套接字未连接)时,抛出异常。
prop receiveBufferSize
public mut prop receiveBufferSize: Int64
功能:设置和读取 SO_RCVBUF 属性。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop receiveTimeout
public override mut prop receiveTimeout: ?Duration
功能:设置和读取 receive/receiveFrom 操作超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
prop remoteAddress
public override prop remoteAddress: ?SocketAddress
功能:读取 Socket 已经连接的远端地址,当 Socket 未连接时返回 None。
类型:?SocketAddress
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
prop reuseAddress
public mut prop reuseAddress: Bool
功能:设置和读取 SO_REUSEADDR 属性。
属性默认以及生效后的行为取决于系统,使用前,请参阅不同系统针对此属性 SO_REUSEADDR/SOCK_REUSEADDR 的说明文档。
类型:Bool
prop reusePort
public mut prop reusePort: Bool
功能:设置和读取 SO_REUSEPORT 属性。
Windows 上可使用 SO_REUSEADDR,但无 SO_REUSEPORT 属性,因此会抛出异常。
属性默认以及配置生效后的行为取决于系统,使用前,请参阅不同系统针对此属性 SO_REUSEPORT 的说明文档。
类型:Bool
异常:
- SocketException - Windows 上不支持此类型,抛出异常。
prop sendBufferSize
public mut prop sendBufferSize: Int64
功能:设置和读取 SO_SNDBUF 属性。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop sendTimeout
public override mut prop sendTimeout: ?Duration
功能:设置和读取 send/sendTo 操作超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
init(SocketAddress)
public init(bindAt!: SocketAddress)
功能:创建一个未绑定的 UdpSocket 实例。
参数:
- bindAt!: SocketAddress - 绑定地址及端口。
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
init(UInt16)
public init(bindAt!: UInt16)
功能:创建一个未绑定的 UdpSocket 实例。
参数:
- bindAt!: UInt16 - 绑定端口。
func bind()
public func bind(): Unit
功能:绑定本地端口失败后需要 close 套接字,不支持多次重试。
异常:
- SocketException - 当因系统原因绑定失败时,抛出异常。
func close()
public override func close(): Unit
功能:关闭套接字,所有操作除了 close/isClosed 之外,均不允许再调用。接口允许多次调用。
func connect(SocketAddress)
public func connect(remote: SocketAddress): Unit
功能:连接特定远端地址,可通过 disconnect 撤销配置。
仅接受该远端地址的报文。必须在调用 bind 后执行。此操作执行后,端口将开始接收 ICMP 报文,若收到异常报文后,可能导致 send/sendTo 执行失败。
参数:
- remote: SocketAddress - 远端地址。
异常:
- IllegalArgumentException - 当远端地址不合法时,抛出异常。
- SocketException - 当端口未绑定、连接因系统原因无法建立或者 Windows 平台下远端地址为全零地址时,抛出异常。
func disconnect()
public func disconnect(): Unit
功能:停止连接。取消仅收取特定对端报文。可在 connect 前调用,可多次调用。
func getSocketOption(Int32, Int32, CPointer<Unit>, CPointer<UIntNative>)
public func getSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: CPointer<UIntNative>
): Unit
功能:获取指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: CPointer<UIntNative> - 参数值长度。
异常:
- SocketException - 当
getsockopt返回失败时,抛出异常。
func getSocketOptionBool(Int32, Int32)
public func getSocketOptionBool(
level: Int32,
option: Int32
): Bool
功能:获取指定的套接字参数。从 IntNative 强转而来。0 => false,非 0 => true。
参数:
返回值:
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func getSocketOptionIntNative(Int32, Int32)
public func getSocketOptionIntNative(
level: Int32,
option: Int32
): IntNative
功能:获取指定的套接字参数。
参数:
返回值:
- IntNative - 指定的套接字参数值。
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时抛出异常。
func isClosed()
public override func isClosed(): Bool
功能:判断套接字是否通过调用 close 显式关闭。
返回值:
- Bool - 如果该套接字已调用
close显示关闭,则返回true;否则,返回false。
func receive(Array<Byte>)
public func receive(buffer: Array<Byte>): Int64
功能:从 connect 连接到的地址收取报文。
参数:
返回值:
- Int64 - 收取到的报文大小。
func receiveFrom(Array<Byte>)
public override func receiveFrom(buffer: Array<Byte>): (SocketAddress, Int64)
功能:接收报文。
参数:
返回值:
- (SocketAddress, Int64) - 收取到的报文的发送端地址,及实际收取到的报文大小,可能为 0 或者大于参数
buffer的大小。
异常:
- SocketException - 当本机缓存过小无法读取报文时,抛出异常。
- SocketTimeoutException - 当读取超时时,抛出异常。
func send(Array<Byte>)
public func send(payload: Array<Byte>): Unit
功能:发送报文到 connect 连接到的地址。
参数:
异常:
- SocketException - 当
payload的大小超出系统限制或者系统发送失败(例如:当connect被调用,并且收到异常 ICMP 报文时,发送失败)时,抛出异常。
func sendTo(SocketAddress, Array<Byte>)
public override func sendTo(recipient: SocketAddress, payload: Array<Byte>): Unit
功能:发送报文。当没有足够的缓存地址时可能会被阻塞。
参数:
- recipient: SocketAddress - 发送的对端地址。
- payload: Array<Byte> - 发送报文内容。
异常:
- SocketException - 当
payload的大小超出系统限制、系统发送失败(例如:当connect被调用,并且收到异常 ICMP 报文时,发送失败)、Windows 平台下远端地址为全零地址或者 macOS 平台下connect被调用后调用sendTo时,抛出异常。
func setSocketOption(Int32, Int32, CPointer<Unit>, UIntNative)
public func setSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: UIntNative
): Unit
功能:设置指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: UIntNative - 参数值长度。
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionBool(Int32, Int32, Bool)
public func setSocketOptionBool(
level: Int32,
option: Int32,
value: Bool
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionIntNative(Int32, Int32, IntNative)
public func setSocketOptionIntNative(
level: Int32,
option: Int32,
value: IntNative
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func toString()
public override func toString(): String
功能:返回当前 UdpSocket 的状态信息。
返回值:
class UnixDatagramSocket
public class UnixDatagramSocket <: DatagramSocket {
public init(bindAt!: SocketAddress)
public init(bindAt!: String)
}
功能:提供基于数据包的主机通讯能力。
UnixDatagramSocket 实例创建后,应当显式调用 bind() 接口绑定。Unix 数据包套接字不需要连接,不需要与远端握手多次。不过用户也可以通过 connect/disconnect 接口与远端建连和断连。
不同于 UDP,UDS 没有数据包大小限制,限制来源于操作系统和接口实现。
套接字资源需要用 close 接口显式回收。可参阅 DatagramSocket 获取更多信息。
注意:
- 该类型不支持在 Windows 平台上运行。
父类型:
prop localAddress
public override prop localAddress: SocketAddress
功能:读取 socket 将要或已经绑定的本地地址。
异常:
- SocketException - 当
socket已经关闭时,抛出异常。
prop receiveBufferSize
public mut prop receiveBufferSize: Int64
功能:设置和读取 SO_RCVBUF 属性,提供一种方式指定发包缓存大小。选项的生效情况取决于系统。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop receiveTimeout
public override mut prop receiveTimeout: ?Duration
功能:设置和读取 receive/receiveFrom 操作超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
prop remoteAddress
public override prop remoteAddress: ?SocketAddress
功能:读取 Socket 已经连接的远端地址,当 Socket 未连接时返回 None。
类型:?SocketAddress
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
prop sendBufferSize
public mut prop sendBufferSize: Int64
功能:设置和读取 SO_SNDBUF 属性,提供一种方式指定发包缓存大小。选项的生效情况取决于系统。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop sendTimeout
public override mut prop sendTimeout: ?Duration
功能:设置和读取 send/sendTo 操作超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
init(SocketAddress)
public init(bindAt!: SocketAddress)
功能:创建一个未连接的 UnixDatagramSocket 实例。
此文件类型可通过 isSock() 判断是否存在,可通过 unlink() 接口删除。
参数:
- bindAt!: SocketAddress - 连接的套接字地址。地址应当不存在,在
bind时会创建。
异常:
- SocketException - 当路径为空或已存在时,抛出异常。
init(String)
public init(bindAt!: String)
功能:创建一个未连接的 UnixDatagramSocket 实例。
此文件类型可通过 isSock() 判断是否存在,可通过 unlink() 接口删除。
参数:
- bindAt!: String - 连接的文件地址。文件地址应当不存在,在
bind时会创建。
异常:
- IllegalArgumentException - 当文件地址不合法时,抛出异常。
- SocketException - 当文件地址为空或已存在时,抛出异常。
func bind()
public func bind(): Unit
功能:绑定一个 Unix datagram 套接字,并创建监听队列。
此接口自动在本地地址中创建一个套接字文件,如该文件已存在则会绑定失败。此文件类型可通过 isSock 判断是否存在,可通过 unlink() 接口删除,失败后需要 close 套接字,不支持多次重试。
异常:
- SocketException - 当文件地址已存在,或文件创建失败时,抛出异常。
func close()
public override func close(): Unit
功能:关闭套接字,所有操作除了 close/isClosed 之外,均不允许再调用。接口允许多次调用。
func connect(SocketAddress)
public func connect(remote: SocketAddress): Unit
功能:连接特定远端地址,可通过 disconnect 撤销配置。
仅接受该远端地址的报文。默认执行 bind,因此不需额外调用 bind。此操作执行后,端口将开始接收 ICMP 报文,若收到异常报文后,可能导致 send/sendTo 执行失败。
参数:
- remote: SocketAddress - 远端套接字地址。
异常:
- SocketException - 当地址未绑定时,抛出异常。
func connect(String)
public func connect(remotePath: String): Unit
功能:连接特定远端地址,可通过 disconnect 撤销配置。
仅接受该远端地址的报文。必须在 bind 后调用。此操作执行后,端口将开始接收 ICMP 报文,若收到异常报文后,可能导致 send/sendTo 执行失败。
参数:
- remotePath: String - 远端文件地址。
异常:
- SocketException - 当地址未绑定时,抛出异常。
func disconnect()
public func disconnect(): Unit
功能:停止连接。取消仅收取特定对端报文。可在 connect 前调用,可多次调用。
异常:
- SocketException - 当未绑定时,抛出异常。
func getSocketOption(Int32, Int32, CPointer<Unit>, CPointer<UIntNative>)
public func getSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: CPointer<UIntNative>
): Unit
功能:获取指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: CPointer<UIntNative> - 参数值长度。
异常:
- SocketException - 当
getsockopt返回失败时,抛出异常。
func getSocketOptionIntNative(Int32, Int32)
public func getSocketOptionIntNative(
level: Int32,
option: Int32
): IntNative
功能:获取指定的套接字参数。
参数:
返回值:
- IntNative - 返回指定的套接字参数值。
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func isClosed()
public override func isClosed(): Bool
功能:判断套接字是否通过调用 close 显式关闭。
返回值:
- Bool - 返回套接字是否已经通过调用
close显式关闭。是则返回true;否则,返回false。
func receive(Array<Byte>)
public func receive(buffer: Array<Byte>): Int64
功能:从 connect 连接到的地址收取报文。
参数:
返回值:
- Int64 - 收取到的报文大小。
func receiveFrom(Array<Byte>)
public override func receiveFrom(buffer: Array<Byte>): (SocketAddress, Int64)
功能:收取报文。
参数:
返回值:
- (SocketAddress, Int64) - 收取到的报文的发送端地址,及实际收取到的报文大小,可能为 0 或者大于参数
buffer的大小。
异常:
- SocketException - 本机缓存过小无法读取报文时,抛出异常。
- SocketTimeoutException - 当读取超时时,抛出异常。
func send(Array<Byte>)
public func send(payload: Array<Byte>): Unit
功能:发送报文到 connect 连接到的地址。
参数:
异常:
- SocketException - 当
payload的大小超出系统限制或者系统发送失败时,抛出异常。
func sendTo(SocketAddress, Array<Byte>)
public override func sendTo(recipient: SocketAddress, payload: Array<Byte>): Unit
功能:发送报文。当没有足够的缓存地址时可能会被阻塞。
参数:
- recipient: SocketAddress - 发送的对端地址。
- payload: Array<Byte> - 发送报文内容。
异常:
- SocketException - 当
payload的大小超出系统限制、系统发送失败(例如:当connect被调用,并且收到异常 ICMP 报文时,发送将失败)或者 macOS 平台下connect被调用后调用sendTo时,抛出异常。
func setSocketOption(Int32, Int32, CPointer<Unit>, UIntNative)
public func setSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: UIntNative
): Unit
功能:设置指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: UIntNative - 参数值长度。
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionBool(Int32, Int32, Bool)
public func setSocketOptionBool(
level: Int32,
option: Int32,
value: Bool
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionIntNative(Int32, Int32,IntNative)
public func setSocketOptionIntNative(
level: Int32,
option: Int32,
value: IntNative
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时抛出异常。
func getSocketOptionBool(Int32, Int32)
public func getSocketOptionBool(
level: Int32,
option: Int32
): Bool
功能:获取指定的套接字参数。从 IntNative 强转而来。0 => false,非 0 => true。
参数:
返回值:
异常:
- SocketException - 当
getsockopt返回失败时,抛出异常。
func toString()
public override func toString(): String
功能:返回当前 UDS 的状态信息。
返回值:
- String - 包含当前
UDS状态信息的字符串。
class UnixServerSocket
public class UnixServerSocket <: ServerSocket {
public init(bindAt!: String)
public init(bindAt!: SocketAddress)
}
功能:提供基于双工流的主机通讯服务端。
UnixServerSocket 监听连接,创建后可以通过属性和 setSocketOptionXX 接口配置属性值。需要调用 bind() 接口绑定本地地址开始监听连接。可以通过 accept() 接口接受连接。
注意:
- 该类型不支持在 Windows 平台上运行。
父类型:
prop backlogSize
public mut prop backlogSize: Int64
功能:设置和读取 backlog 大小。仅可在调用 bind 前调用,否则将抛出异常。
变量是否生效取决于系统行为。
类型:Int64
异常:
- SocketException - 当在
bind后调用,将抛出异常。
prop localAddress
public override prop localAddress: SocketAddress
功能:读取 Socket 将要或已经被绑定的本地地址。
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
prop receiveBufferSize
public mut prop receiveBufferSize: Int64
功能:设置和读取 SO_RCVBUF 属性。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop sendBufferSize
public mut prop sendBufferSize: Int64
功能:设置和读取 SO_SNDBUF 属性。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
init(SocketAddress)
public init(bindAt!: SocketAddress)
功能:创建一个未连接的 UnixServerSocket 实例。
参数:
- bindAt!: SocketAddress - 连接的套接字地址。
init(String)
public init(bindAt!: String)
功能:创建一个未连接的 UnixServerSocket 实例。
此文件类型可通过 isSock 判断是否存在,可通过 unlink() 接口删除。
参数:
- bindAt!: String - 连接的文件地址。
异常:
- IllegalArgumentException - 当文件地址不合法时,抛出异常。
func accept()
public override func accept(): UnixSocket
功能:等待接受一个客户端的连接,或从队列中读取连接。
返回值:
- UnixSocket - 连接的客户端套接字。
func accept(?Duration)
public override func accept(timeout!: ?Duration): UnixSocket
功能:等待接受一个客户端的连接,或从队列中读取连接。
参数:
- timeout!: ?Duration - 超时时间。
返回值:
- UnixSocket - 连接的客户端套接字。
异常:
- SocketTimeoutException - 当连接超时时,抛出异常。
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
func bind()
public override func bind(): Unit
功能:绑定一个 Unix domain 套接字,并创建监听队列。
此接口自动在本地地址中创建一个套接字文件,如该文件已存在则会绑定失败。此文件类型可通过 isSock 接口判断是否存在,可通过 unlink() 接口删除,失败后需要 close 套接字,不支持多次重试。
异常:
- SocketException - 当因系统原因绑定失败时,抛出异常。
func close()
public override func close(): Unit
功能:关闭套接字,该套接字的所有操作除了 close/isClosed 之外,均不允许再调用。此接口允许多次调用。
func getSocketOption(Int32, Int32, CPointer<Unit>, CPointer<UIntNative>)
public func getSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: CPointer<UIntNative>
): Unit
功能:获取指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: CPointer<UIntNative> - 参数值长度。
异常:
- SocketException - 当
getsockopt返回失败时,抛出异常。
func getSocketOptionBool(Int32, Int32)
public func getSocketOptionBool(
level: Int32,
option: Int32
): Bool
功能:获取指定的套接字参数。从 IntNative 强转而来。0 => false,非 0 => true。
参数:
返回值:
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func getSocketOptionIntNative(Int32, Int32)
public func getSocketOptionIntNative(
level: Int32,
option: Int32
): IntNative
功能:获取返回值为整型的套接字参数。
参数:
返回值:
- IntNative - 指定的套接字参数值。
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func isClosed()
public override func isClosed(): Bool
功能:判断套接字是否通过调用 close 显式关闭。
返回值:
- Bool - 如果套接字是通过调用
close显式关闭,则返回 true;否则,返回 false。
func setSocketOption(Int32, Int32, CPointer<Unit>, UIntNative)
public func setSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: UIntNative
): Unit
功能:设置返回值为整型的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: UIntNative - 参数值长度。
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionBool(Int32, Int32, Bool)
public func setSocketOptionBool(
level: Int32,
option: Int32,
value: Bool
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionIntNative(Int32, Int32, IntNative)
public func setSocketOptionIntNative(
level: Int32,
option: Int32,
value: IntNative
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func toString()
public override func toString(): String
功能:返回当前 UnixServerSocket 的状态信息。
返回值:
- String - 包含当前 UnixServerSocket 状态信息的字符串。
class UnixSocket
public class UnixSocket <: StreamingSocket {
public init(address: SocketAddress, localAddress!: ?SocketAddress = None)
public init(path: String, localPath!: ?String = None)
}
功能:提供基于双工流的主机通讯客户端。
UnixSocket 实例创建后应调用 connect() 接口创建连接,并且在结束时显式调用 close() 回收资源。可参阅 StreamingSocket 获取更多信息。
注意:
- 该类型不支持在 Windows 平台上运行。
父类型:
prop localAddress
public override prop localAddress: SocketAddress
功能:读取 Socket 将要或已经被绑定的本地地址。
异常:
- SocketException - 当
Socket已经被关闭或无可用的本地地址(本地地址未配置并且套接字未连接)时,抛出异常。
prop readTimeout
public override mut prop readTimeout: ?Duration
功能:设置和读取读操作超时时间。
如果设置的时间过小将会设置为最小时钟周期值,过大时将设置为None,默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
prop receiveBufferSize
public mut prop receiveBufferSize: Int64
功能:设置和读取 SO_RCVBUF 属性。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop remoteAddress
public override prop remoteAddress: SocketAddress
功能:读取 Socket 已经或将要连接的远端地址。
异常:
- SocketException - 当
Socket已经被关闭时,抛出异常。
prop sendBufferSize
public mut prop sendBufferSize: Int64
功能:设置和读取 SO_SNDBUF 属性。
类型:Int64
异常:
- IllegalArgumentException - 当
size小于等于 0 时,抛出异常。 - SocketException - 当
Socket已关闭时,抛出异常。
prop writeTimeout
public override mut prop writeTimeout: ?Duration
功能:设置和读取写操作超时时间。
如果设置的时间过小将会设置为最小时钟周期值;过大时将设置为最大超时时间(263-1 纳秒);默认值为 None。
类型:?Duration
异常:
- IllegalArgumentException - 当超时时间小于 0 时,抛出异常。
init(SocketAddress, ?SocketAddress)
public init(address: SocketAddress, localAddress!: ?SocketAddress = None)
功能:创建一个未连接的 UnixSocket 实例。
参数:
- address: SocketAddress - 连接的套接字地址。
- localAddress!: ?SocketAddress - 需要 bind 的本地套接字地址;默认值为
None。
init(String, ?String)
public init(path: String, localPath!: ?String = None)
功能:创建一个未连接的 UnixSocket 实例。
此文件类型可通过 isSock 判断是否存在,可通过 unlink() 接口删除。
参数:
异常:
- IllegalArgumentException - 当文件地址不合法时,抛出异常。
func close()
public func close(): Unit
功能:关闭套接字,所有操作除了 close/isClosed 之外,均不允许再调用。接口允许多次调用。
func connect(?Duration)
public func connect(timeout!: ?Duration = None): Unit
功能:建立远端连接,对端拒绝时连接失败,会自动绑定本地地址,因此不需要进行额外的绑定操作。
参数:
- timeout!: ?Duration - 超时时间,
None表示无超时时间。Unix 与 Tcp 不同,队列已满时,调用立即返回错误,而非重试阻塞等待。
异常:
- IllegalArgumentException - 当远端地址不合法或者超时时间小于 0 时,抛出异常。
- SocketException - 当连接因系统原因无法建立时。抛出异常。
- SocketTimeoutException - 当连接超时时。抛出异常。
func getSocketOption(Int32, Int32, CPointer<Unit>, CPointer<UIntNative>)
public func getSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: CPointer<UIntNative>
): Unit
功能:获取指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: CPointer<UIntNative> - 参数值长度。
异常:
- SocketException - 当
getsockopt返回失败时,抛出异常。
func getSocketOptionBool(Int32, Int32)
public func getSocketOptionBool(
level: Int32,
option: Int32
): Bool
功能:获取指定的套接字参数。从 IntNative 强转而来。0 => false,非 0 => true。
参数:
返回值:
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func getSocketOptionIntNative(Int32, Int32)
public func getSocketOptionIntNative(
level: Int32,
option: Int32
): IntNative
功能:获取指定的套接字参数。
参数:
返回值:
- IntNative - 指定的套接字参数值。
异常:
- SocketException - 当
getsockopt返回失败时或参数大小超过 IntNative 的阈值时,抛出异常。
func isClosed()
public func isClosed(): Bool
功能:判断套接字是否通过调用 close 显式关闭。
返回值:
- Bool - 返回套接字是否已经调用
close显示关闭。是则返回true;否则,返回false。
func read(Array<Byte>)
public override func read(buffer: Array<Byte>): Int64
功能:读取报文。超时情况按 readTimeout 决定,详见 readTimeout。
参数:
返回值:
- Int64 - 读取的数据长度。
异常:
- SocketException - 当
buffer大小为 0 或者因系统原因读取失败时,抛出异常。
func setSocketOption(Int32, Int32, CPointer<Unit>, UIntNative)
public func setSocketOption(
level: Int32,
option: Int32,
value: CPointer<Unit>,
valueLength: UIntNative
): Unit
功能:设置指定的套接字参数。
参数:
- level: Int32 - 层级,例如
SOL_SOCKET。 - option: Int32 - 参数,例如
SO_KEEPALIVE。 - value: CPointer<Unit> - 参数值。
- valueLength: UIntNative - 参数值长度。
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionBool(Int32, Int32, Bool)
public func setSocketOptionBool(
level: Int32,
option: Int32,
value: Bool
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func setSocketOptionIntNative(Int32, Int32, IntNative)
public func setSocketOptionIntNative(
level: Int32,
option: Int32,
value: IntNative
): Unit
功能:设置指定的套接字参数。
参数:
异常:
- SocketException - 当
setsockopt返回失败时,抛出异常。
func toString()
public override func toString(): String
功能:返回当前 UnixSocket 的状态信息。
返回值:
- String - 包含当前 UnixSocket 状态信息的字符串。
func write(Array<Byte>)
public override func write(buffer: Array<Byte>): Unit
功能:读取写入。超时情况按 writeTimeout 决定,详见 writeTimeout。
参数:
异常:
- SocketException - 当
buffer大小为 0 时抛出异常,当因系统原因写入失败时,抛出异常。
class UnixSocketAddress
public class UnixSocketAddress <: SocketAddress & Equatable<UnixSocketAddress> {
public init(path: Array<Byte>)
public init(path: String)
}
功能:此类实现了 Unix Domain Socket 地址,Unix Domain Socket 地址封装了Unix Domain Socket 绑定或连接到的文件系统路径,路径长度不可超过 108。
如果路径是空字符串,那么表示它是 unnamed 地址,如果路径以\0 开头,那么它是 abstract 地址。路径中间不可包含 \0。
父类型:
prop family
public prop family: AddressFamily
功能:获取当前 UnixSocketAddress 对象的地址族,总是 AddressFamily.UNIX。
prop size
public prop size: Int64
功能:获取当前 UnixSocketAddress 对象的原始字节长度。
类型:Int64
init(Array<Byte>)
public init(path: Array<Byte>)
功能:根据 Array<Byte> 表示的文件系统路径构造 UnixSocketAddress 地址。
参数:
异常:
- IllegalArgumentException - 如果 address 不合法,抛出异常。
init(String)
public init(path: String)
功能:根据字符串表示的文件系统路径构造 UnixSocketAddress 地址。
参数:
- path: String - 文件系统路径字符串。
异常:
- IllegalArgumentException - 如果 address 不合法,抛出异常。
func getAddressBytes()
public func getAddressBytes(): Array<Byte>
功能:返回此 UnixSocketAddress 对象的原始IP地址,内容布局与 sockaddr_un 形式一致。
返回值:
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let udsa1_1: UnixSocketAddress = UnixSocketAddress("/tmp/server1.sock")
@Assert(udsa1_1.getAddressBytes(), "\u{1}\u{0}/tmp/server1.sock".toArray())
}
func hashCode()
public func hashCode(): Int64
功能:获取 hashcode 值。
返回值:
- Int64 -
hashcode值。
func toString()
public func toString(): String
功能:返回当前 UnixSocketAddress 的文本表示字符串。
返回值:
- String - 当前 UnixSocketAddress 的文本表示字符串,比如
/tmp/socket1。
示例:
import std.net.*
import std.unittest.*
import std.unittest.testmacro.*
main () {
let expect1 = "/tmp/server1.sock"
let expect2 = "\u{0}/tmp/server1.sock"
let udsa1_1: UnixSocketAddress = UnixSocketAddress("/tmp/server1.sock")
let udsa2_1: UnixSocketAddress = UnixSocketAddress("/tmp/server1.sock".toArray())
let udsa2_2: UnixSocketAddress = UnixSocketAddress("/tmp/server1.sock\u{0}\u{0}".toArray())
let udsa3_1: UnixSocketAddress = UnixSocketAddress("\u{0}/tmp/server1.sock")
let udsa4_1: UnixSocketAddress = UnixSocketAddress("\u{0}/tmp/server1.sock".toArray())
let udsa4_2: UnixSocketAddress = UnixSocketAddress("\u{0}/tmp/server1.sock\u{0}\u{0}".toArray())
@Assert(udsa1_1.toString(), expect1)
@Assert(udsa2_1.toString(), expect1)
@Assert(udsa2_2.toString(), expect1)
@Assert(udsa3_1.toString(), expect2)
@Assert(udsa1_1, udsa2_1)
@Assert(udsa1_1, udsa2_2)
@Assert(udsa3_1, udsa4_1)
@Assert(udsa3_1, udsa4_2)
@Assert(udsa4_1.toString(), expect2)
@Assert(udsa4_2.toString(), expect2)
try {
UnixSocketAddress("/tmp/server1\u{0}.sock")
} catch (e: IllegalArgumentException) {
@Assert(true)
}
try {
UnixSocketAddress("/tmp/server1.sock\u{0}\u{0}")
} catch (e: IllegalArgumentException) {
@Assert(true)
}
try {
UnixSocketAddress("\u{0}/tmp/server1.sock\u{0}\u{0}")
} catch (e: IllegalArgumentException) {
@Assert(true)
}
try {
UnixSocketAddress("/tmp/server1\u{0}.sock".toArray())
} catch (e: IllegalArgumentException) {
@Assert(true)
}
return
}
operator func ==(UnixSocketAddress)
public operator func ==(rhs: UnixSocketAddress): Bool
功能:判断两个 UnixSocketAddress 对象是否相等。
参数:
- rhs: UnixSocketAddress - 参与比较的 UnixSocketAddress 对象。
返回值:
- Bool - 如果两个 UnixSocketAddress 对象相等,则返回
true;否则,返回false。
operator func !=(UnixSocketAddress)
public operator func !=(rhs: UnixSocketAddress): Bool
功能:判断两个 UnixSocketAddress 对象是否不等。
参数:
- rhs: UnixSocketAddress - 参与比较的 UnixSocketAddress 对象。
返回值:
- Bool - 如果两个 UnixSocketAddress 对象不等,则返回
true;否则,返回false。
枚举
enum SocketNet
public enum SocketNet <: ToString & Equatable<SocketNet> {
| TCP
| UDP
| UNIX
}
功能:传输层协议类型。
父类型:
TCP
TCP
功能:代表 TCP 协议。
UDP
UDP
功能:代表 UDP 协议。
UNIX
UNIX
功能:代表 UNIX 协议。
func toString()
public func toString(): String
功能:将枚举值转换为字符串。
返回值:
- String - 转换后的字符串。
operator func !=(SocketNet)
public operator func !=(that: SocketNet): Bool
功能:判断两个 SocketNet 是否不相等。
参数:
返回值:
- Bool - 如果不相等,则返回
true;否则,返回false。
operator func ==(SocketNet)
public operator func ==(that: SocketNet): Bool
功能:判断两个 SocketNet 是否相等。
参数:
返回值:
- Bool - 如果相等,则返回
true;否则,返回false。
结构体
struct AddressFamily
public struct AddressFamily <: ToString & Equatable<AddressFamily> {
public static const INET = AddressFamily("INET", 2)
public static const INET6: AddressFamily
public static const NETLINK: AddressFamily
public static const UNIX = AddressFamily("UNIX", 1)
public static const UNSPEC = AddressFamily("UNSPEC", 0)
public let name: String
public let value: Int32
public const init(name: String, value: UInt16)
}
功能:AddressFamily 地址族用于指示 Socket 的寻址方案,常用的有 INET / INET6 / UNIX 地址族。地址族标识符最初在 RFC 2453 中定义。
父类型:
static const INET
public static const INET = AddressFamily("INET", 2)
功能:IPv4 地址族。
static const INET6
public static const INET6: AddressFamily
功能:IPv6 地址族。不同系统下的值分别为:
- macOS: AddressFamily("INET6", 30)
- Windows: AddressFamily("INET6", 23)
- 其他情况:AddressFamily("INET6", 10)
static const NETLINK
public static const NETLINK: AddressFamily
功能:NetLink 地址族,仅 Linux 下支持,其值为:
- Linux: AddressFamily("NETLINK", 16)
static const UNIX
public static const UNIX = AddressFamily("UNIX", 1)
功能:unix domain socket 地址族。
static const UNSPEC
public static const UNSPEC = AddressFamily("UNSPEC", 0)
功能:未指定的地址族。
let name: String
public let name: String
功能:地址族名。
类型:String
let value: UInt16
public let value: UInt16
功能:地址族值。
类型:UInt16
init(String, UInt16)
public const init(name: String, value: UInt16)
功能:常量构造函数,创建 AddressFamily 对象。
参数:
func toString()
public func toString(): String
功能:获取地址族对应的名称。
返回值:
- String - 当前地址族的名称。
operator func ==(AddressFamily)
public operator func ==(rhs: AddressFamily): Bool
功能:比较地址族值是否相等。
参数:
- rhs: AddressFamily - 参与比较的 AddressFamily 对象。
返回值:
- Bool - 如果两个 AddressFamily 对象相等,则返回
true;否则,返回false。
operator func !=(AddressFamily)
public operator func !=(rhs: AddressFamily): Bool
功能:比较地址族值是否不等。
参数:
- rhs: AddressFamily - 参与比较的 AddressFamily 对象。
返回值:
- Bool - 如果两个 AddressFamily 对象不等,则返回
true;否则,返回false。
struct OptionLevel
public struct OptionLevel {
public static const ICMP: Int32 = 1
public static const IP: Int32 = 0
public static const RAW: Int32 = 255
public static const SOCKET: Int32
public static const TCP: Int32 = 6
public static const UDP: Int32 = 17
}
功能:提供了常用的套接字选项级别。
static const ICMP
public static const ICMP: Int32 = 1
功能:控制 ICMP 协议行为的套接字选项级别。
类型:Int32
static const IP
public static const IP: Int32 = 0
功能:控制 IP 协议行为的套接字选项级别。
类型:Int32
static const RAW
public static const RAW: Int32 = 255
功能:控制 RAW 协议行为的套接字选项级别。
类型:Int32
static const SOCKET
public static const SOCKET: Int32
功能:控制基本套接字行为的套接字选项级别。不同系统下的值分别为:
- macOS: 0xFFFF
- Windows: 0xFFFF
- 其他情况:1
类型:Int32
static const TCP
public static const TCP: Int32 = 6
功能:控制 TCP 协议行为的套接字选项级别。
类型:Int32
static const UDP
public static const UDP: Int32 = 17
功能:控制 UDP 协议行为的套接字选项级别。
类型:Int32
struct OptionName
public struct OptionName {
public static const IP_HDRINCL: Int32
public static const IP_TOS: Int32
public static const IP_TTL: Int32
public static const SO_ACCEPTCONN: Int32
public static const SO_BROADCAST: Int32
public static const SO_DEBUG: Int32 = 0x0001
public static const SO_DONTROUTE: Int32
public static const SO_ERROR: Int32
public static const SO_KEEPALIVE: Int32
public static const SO_LINGER: Int32
public static const SO_OOBINLINE: Int32
public static const SO_RCVBUF: Int32
public static const SO_RCVTIMEO: Int32
public static const SO_REUSEADDR: Int32
public static const SO_SNDBUF: Int32
public static const SO_SNDTIMEO: Int32
public static const TCP_KEEPCNT: Int32
public static const TCP_KEEPIDLE: Int32
public static const TCP_KEEPINTVL: Int32
public static const TCP_NODELAY: Int32 = 0x0001
}
功能:提供了常用的套接字选项。
static const IP_HDRINCL
public static const IP_HDRINCL: Int32
功能:用于在发送数据包时指定 IP 头部是否由应用程序提供的套接字选项。不同系统下的值分别为:
- macOS: 0x0002
- Windows: 0x0002
- 其他情况:0x0003
类型:Int32
static const IP_TOS
public static const IP_TOS: Int32
功能:用于指定数据包服务类型和优先级的套接字选项。不同系统下的值分别为:
- macOS: 0x0003
- Windows: 0x0003
- 其他情况:0x0001
类型:Int32
static const IP_TTL
public static const IP_TTL: Int32
功能:用于限制IP数据包在网络中传输最大跳数的套接字选项。不同系统下的值分别为:
- macOS: 0x0004
- Windows: 0x0004
- 其他情况:0x0002
类型:Int32
static const SO_ACCEPTCONN
public static const SO_ACCEPTCONN: Int32
功能:用于查询套接字是否处于监听状态的套接字选项。不同系统下的值分别为:
- macOS: 0x0002
- Windows: 0x0002
- 其他情况:0x001E
类型:Int32
static const SO_BROADCAST
public static const SO_BROADCAST: Int32
功能:用于设置套接字是否允许发送广播消息的套接字选项。不同系统下的值分别为:
- macOS: 0x0020
- Windows: 0x0020
- 其他情况:0x0006
类型:Int32
static const SO_DEBUG
public static const SO_DEBUG: Int32 = 0x0001
功能:用于启用或禁用调试模式的套接字选项。
类型:Int32
static const SO_DONTROUTE
public static const SO_DONTROUTE: Int32
功能:用于在连接套接字时,不路由套接字数据包的套接字选项。不同系统下的值分别为:
- macOS: 0x0010
- Windows: 0x0010
- 其他情况:0x0005
类型:Int32
static const SO_ERROR
public static const SO_ERROR: Int32
功能:获取和清除套接字上错误状态的套接字选项。不同系统下的值分别为:
- macOS: 0x1007
- Windows: 0x1007
- 其他情况:0x0004
类型:Int32
static const SO_KEEPALIVE
public static const SO_KEEPALIVE: Int32
功能:用于检测 TCP 连接是否仍然处于活动状态的套接字选项。不同系统下的值分别为:
- macOS: 0x0008
- Windows: 0x0008
- 其他情况:0x0009
类型:Int32
static const SO_LINGER
public static const SO_LINGER: Int32
功能:用于设置套接字关闭时行为的套接字选项。不同系统下的值分别为:
- macOS: 0x0080
- Windows: 0x0080
- 其他情况:0x000D
类型:Int32
static const SO_OOBINLINE
public static const SO_OOBINLINE: Int32
功能:用于控制接收带外数据方式的套接字选项。不同系统下的值分别为:
- macOS: 0x0100
- Windows: 0x0100
- 其他情况:0x000A
类型:Int32
static const SO_RCVBUF
public static const SO_RCVBUF: Int32
功能:用于设置套接字接收缓冲区大小的套接字选项。不同系统下的值分别为:
- macOS: 0x1002
- Windows: 0x1002
- 其他情况:0x0008
类型:Int32
static const SO_RCVTIMEO
public static const SO_RCVTIMEO: Int32
功能:用于设置套接字接收数据超时时间的套接字选项。不同系统下的值分别为:
- macOS: 0x1006
- Windows: 0x1006
- 其他情况:0x0014
类型:Int32
static const SO_REUSEADDR
public static const SO_REUSEADDR: Int32
功能:用于在套接字关闭后立即释放其绑定端口,以便其他套接字可以立即绑定该端口的套接字选项。不同系统下的值分别为:
- macOS: 0x0004
- Windows: 0x0004
- 其他情况:0x0002
类型:Int32
static const SO_SNDBUF
public static const SO_SNDBUF: Int32
功能:用于设置套接字发送缓冲区大小的套接字选项。不同系统下的值分别为:
- macOS: 0x1001
- Windows: 0x1001
- 其他情况:0x0007
类型:Int32
static const SO_SNDTIMEO
public static const SO_SNDTIMEO: Int32
功能:用于设置套接字发送数据超时时间的套接字选项。不同系统下的值分别为:
- macOS: 0x1005
- Windows: 0x1005
- 其他情况:0x0015
类型:Int32
static const TCP_KEEPCNT
public static const TCP_KEEPCNT: Int32
功能:用于控制 TCP 连接中发送保持存活探测报文次数的套接字选项。不同系统下的值分别为:
- macOS: 0x0102
- Windows: 0x0010
- 其他情况:0x0006
类型:Int32
static const TCP_KEEPIDLE
public static const TCP_KEEPIDLE: Int32
功能:用于设置在没有收到对端确认的情况下,TCP 保持连接最大次数的套接字选项。不同系统下的值分别为:
- macOS: 0x0010
- Windows: 0x0003
- 其他情况:0x0004
类型:Int32
static const TCP_KEEPINTVL
public static const TCP_KEEPINTVL: Int32
功能:用于设置 TCP 保持连接时发送探测报文时间间隔的套接字选项。不同系统下的值分别为:
- macOS: 0x0101
- Windows: 0x0011
- 其他情况:0x0005
类型:Int32
static const TCP_NODELAY
public static const TCP_NODELAY: Int32 = 0x0001
功能:用于控制 TCP 协议延迟行为的套接字选项。
类型:Int32
struct ProtocolType
public struct ProtocolType <: Equatable<ProtocolType> & ToString & Hashable {
public static let ICMP: ProtocolType = ProtocolType(1)
public static let IPV4: ProtocolType = ProtocolType(4)
public static let IPV6: ProtocolType = ProtocolType(41)
public static let RAW: ProtocolType = ProtocolType(255)
public static let TCP: ProtocolType = ProtocolType(6)
public static let UDP: ProtocolType = ProtocolType(17)
public static let Unspecified: ProtocolType = ProtocolType(0)
public init(protocol: Int32)
}
功能:提供了常用的套接字协议,以及通过指定 Int32 值来构建套接字协议的功能。
父类型:
static let ICMP
public static let ICMP: ProtocolType = ProtocolType(1)
功能:指定协议类型为 ICMP。
类型:ProtocolType
static let IPV4
public static let IPV4: ProtocolType = ProtocolType(4)
功能:指定协议类型为 IPv4 。
类型:ProtocolType
static let IPV6
public static let IPV6: ProtocolType = ProtocolType(41)
功能:指定协议类型为 IPv6。
类型:ProtocolType
static let RAW
public static let RAW: ProtocolType = ProtocolType(255)
功能:指定协议类型为 RAW。
类型:ProtocolType
static let TCP
public static let TCP: ProtocolType = ProtocolType(6)
功能:指定协议类型为 TCP。
类型:ProtocolType
static let UDP
public static let UDP: ProtocolType = ProtocolType(17)
功能:指定协议类型为 UDP。
类型:ProtocolType
static let Unspecified
public static let Unspecified: ProtocolType = ProtocolType(0)
功能:不指定协议类型。
类型:ProtocolType
init(Int32)
public init(protocol: Int32)
功能:通过指定套接字协议值创建协议。
参数:
- protocol: Int32 - 套接字协议值。
func hashCode()
public func hashCode(): Int64
功能:返回当前 ProtocolType 实例的哈希值。
返回值:
- Int64 - 当前 ProtocolType 实例的哈希值。
func toString()
public func toString(): String
功能:返回当前 ProtocolType 实例的字符串表示。
返回值:
- String - 当前 ProtocolType 实例的字符串表示。
operator func !=(ProtocolType)
public operator func !=(r: ProtocolType): Bool
功能:判断两个 ProtocolType 实例是否不等。
参数:
- r: ProtocolType - 参与比较的 ProtocolType 实例。
返回值:
operator func ==(ProtocolType)
public operator func ==(r: ProtocolType): Bool
功能:判断两个 ProtocolType 实例是否相等。
参数:
- r: ProtocolType - 参与比较的 ProtocolType 实例。
返回值:
struct RawAddress
public struct RawAddress {
public init(addr: Array<Byte>)
}
功能:提供了 RawSocket 的通信地址创建和获取功能。
prop addr
public prop addr: Array<Byte>
功能:获取地址。
init(Array<Byte>)
public init(addr: Array<Byte>)
功能:根据字节数组创建地址。
参数:
struct SocketDomain
public struct SocketDomain <: Equatable<SocketDomain> & ToString & Hashable {
public static let IPV4: SocketDomain = SocketDomain(2)
public static let IPV6: SocketDomain
public static let NETLINK: SocketDomain = SocketDomain(16)
public static let PACKET: SocketDomain = SocketDomain(17)
public static let UNIX: SocketDomain
public init(domain: Int32)
}
功能:提供了常用的套接字通信域,以及通过指定 Int32 值来构建套接字通信域的功能。
父类型:
static let IPV4
public static let IPV4: SocketDomain = SocketDomain(2)
功能:IPv4 通信域。
类型:SocketDomain
static let IPV6
public static let IPV6: SocketDomain
功能:IPv6 通信域。不同系统下的值分别为:
- macOS: SocketDomain(30)
- Windows: SocketDomain(23)
- 其他情况:SocketDomain(10)
类型:SocketDomain
static let NETLINK
public static let NETLINK: SocketDomain = SocketDomain(16)
功能:内核和用户空间进程之间通信。
注意:
- 该常量在 Windows 和 macOS 平台不提供。
类型:SocketDomain
static let PACKET
public static let PACKET: SocketDomain = SocketDomain(17)
功能:允许用户空间程序直接访问网络数据包。
注意:
- 该常量在 Windows 和 macOS 平台不提供。
类型:SocketDomain
static let UNIX
public static let UNIX: SocketDomain
功能:本机通信。不同系统下的值分别为:
- Windows: SocketDomain(0)
- 其他情况:SocketDomain(1)
类型:SocketDomain
init(Int32)
public init(domain: Int32)
功能:根据指定通信域值创建套接字通信域。
参数:
- domain: Int32 - 通信域值。
func hashCode()
public func hashCode(): Int64
功能:返回当前 SocketDomain 实例的哈希值。
返回值:
- Int64 - 当前 SocketDomain 实例的哈希值。
func toString()
public func toString(): String
功能:返回当前 SocketDomain 实例的字符串表示。
返回值:
- String - 当前 SocketDomain 实例的字符串表示。
operator func !=(SocketDomain)
public operator func !=(r: SocketDomain): Bool
功能:比较两个 SocketDomain 实例是否不等。
参数:
- r: SocketDomain - 参与比较的 SocketDomain 实例。
返回值:
operator func ==(SocketDomain)
public operator func ==(r: SocketDomain): Bool
功能:比较两个 SocketDomain 实例是否相等。
参数:
- r: SocketDomain - 参与比较的 SocketDomain 实例。
返回值:
struct SocketKeepAliveConfig
public struct SocketKeepAliveConfig <: ToString & Equatable<SocketKeepAliveConfig> {
public let count: UInt32
public let idle: Duration
public let interval: Duration
public init(idle!: Duration = Duration.second * 45, interval!: Duration = Duration.second * 5, count!: UInt32 = 5)
}
功能:TCP KeepAlive 属性配置。
父类型:
let count
public let count: UInt32
功能:查询连接是否失效的报文个数。
类型:UInt32
let idle
public let idle: Duration
功能:允许连接空闲的时长,空闲超长将关闭连接。
类型:Duration
let interval
public let interval: Duration
功能:保活报文发送周期。
类型:Duration
init(Duration, Duration, UInt32)
public init(idle!: Duration = Duration.second * 45, interval!: Duration = Duration.second * 5, count!: UInt32 = 5)
功能:初始化 SocketKeepAliveConfig 实例对象。
参数:
- idle!: Duration - 允许空闲的时长,默认 45 秒。
- interval!: Duration - 保活报文发送周期,默认 45 秒。
- count!: UInt32 - 查询连接是否失效的报文个数, 默认 5 个。
异常:
- IllegalArgumentException - 当配置为空闲状态或设置间隔小于 0 时,抛出异常。
func toString()
public override func toString(): String
功能:将 TCP KeepAlive 属性配置转换为字符串。
返回值:
- String - 转换后的字符串。
operator func !=(SocketKeepAliveConfig)
public override operator func !=(other: SocketKeepAliveConfig): Bool
功能:判断两个 SocketKeepAliveConfig 实例是否不等。
参数:
- other: SocketKeepAliveConfig - 参与比较的 SocketKeepAliveConfig 实例。
返回值:
- Bool - 如果不等,则返回
true;否则,返回false。
operator func ==(SocketKeepAliveConfig)
public override operator func ==(other: SocketKeepAliveConfig): Bool
功能:判断两个 SocketKeepAliveConfig 实例是否相等。
参数:
- other: SocketKeepAliveConfig - 参与比较的 SocketKeepAliveConfig 实例。
返回值:
- Bool - 如果相等,则返回
true;否则,返回false。
struct SocketOptions
public struct SocketOptions {
public static const IPPROTO_TCP: Int32 = 6
public static const IPPROTO_UDP: Int32 = 17
public static const SOL_SOCKET: Int32
public static const SO_BINDTODEVICE: Int32
public static const SO_KEEPALIVE: Int32
public static const SO_LINGER: Int32
public static const SO_RCVBUF: Int32
public static const SO_REUSEADDR: Int32
public static const SO_REUSEPORT: Int32
public static const SO_SNDBUF: Int32
public static const TCP_NODELAY: Int32 = 0x0001
public static const TCP_QUICKACK: Int32
}
功能:SocketOptions 存储了设置套接字选项的一些参数常量方便后续调用。
const IPPROTO_TCP (deprecated)
public static const IPPROTO_TCP: Int32 = 6
功能:常数,用于将套接字选项的 level 层级设为 IPPROTO_TCP。
注意:
未来版本即将废弃不再使用,使用 OptionLevel.TCP 替代。
类型:Int32
const IPPROTO_UDP (deprecated)
public static const IPPROTO_UDP: Int32 = 17
功能:常数,用于将套接字选项的 level 层级设为 IPPROTO_UDP。
注意:
未来版本即将废弃不再使用,使用 OptionLevel.UDP 替代。
类型:Int32
const SOL_SOCKET (deprecated)
public static const SOL_SOCKET: Int32
功能:常数,用于将套接字选项的 level 层级设为 SOL_SOCKET。不同系统下的值分别为:
- macOS: 0xFFFF
- Windows: 0xFFFF
- 其他情况:1
注意:
未来版本即将废弃不再使用,使用 OptionLevel.SOCKET 替代。
类型:Int32
const SO_BINDTODEVICE
public static const SO_BINDTODEVICE: Int32
功能:常数,用于将套接字选项的 optname 设为 SO_BINDTODEVICE。不同系统下的值分别为:
- macOS: 0xFFFF
- Windows: 0xFFFF
- 其他情况:0x0019
类型:Int32
const SO_KEEPALIVE
public static const SO_KEEPALIVE: Int32
功能:常数,用于将套接字选项的 optname 设为 SO_KEEPALIVE。不同系统下的值分别为:
- macOS: 0x0008
- Windows: 0x0008
- 其他情况:0x0009
类型:Int32
const SO_LINGER
public static const SO_LINGER: Int32
功能:常数,用于将套接字选项的 optname 设为 SO_LINGER。不同系统下的值分别为:
- macOS: 0x0080
- Windows: 0x0080
- 其他情况:0x000D
类型:Int32
const SO_RCVBUF
public static const SO_RCVBUF: Int32
功能:常数,用于将套接字选项的 optname 设为 SO_RCVBUF。不同系统下的值分别为:
- macOS: 0x1002
- Windows: 0x1002
- 其他情况:0x0008
类型:Int32
const SO_REUSEADDR
public static const SO_REUSEADDR: Int32
功能:常数,用于将套接字选项的 optname 设为 SO_REUSEADDR。不同系统下的值分别为:
- macOS: 0x0004
- Windows: 0x0004
- 其他情况:0x0002
类型:Int32
const SO_REUSEPORT
public static const SO_REUSEPORT: Int32
功能:常数,用于将套接字选项的 optname 设为 SO_REUSEPORT。不同系统下的值分别为:
- macOS: 0x0200
- Windows: 0xFFFF
- 其他情况:0x000F
类型:Int32
const SO_SNDBUF
public static const SO_SNDBUF: Int32
功能:常数,用于将套接字选项的 optname 设为 SO_SNDBUF。不同系统下的值分别为:
- macOS: 0x1001
- Windows: 0x1001
- 其他情况:0x0007
类型:Int32
const TCP_NODELAY
public static const TCP_NODELAY: Int32 = 0x0001
功能:常数,用于将套接字选项的 optname 设为 TCP_NODELAY。
类型:Int32
const TCP_QUICKACK
public static const TCP_QUICKACK: Int32
功能:常数,用于将套接字选项的 optname 设为 TCP_QUICKACK。不同系统下的值分别为:
- macOS: 0xFFFF
- Windows: 0xFFFF
- 其他情况:0x000C
类型:Int32
struct SocketType
public struct SocketType <: Equatable<SocketType> & ToString & Hashable {
public static let DATAGRAM: SocketType = SocketType(2)
public static let RAW: SocketType = SocketType(3)
public static let SEQPACKET: SocketType = SocketType(5)
public static let STREAM: SocketType = SocketType(1)
public init(`type`: Int32)
}
功能:提供了常用的套接字类型,以及通过指定 Int32 值来构建套接字类型的功能。
父类型:
static let DATAGRAM
public static let DATAGRAM: SocketType = SocketType(2)
功能:数据报套接字类型。
类型:SocketType
static let RAW
public static let RAW: SocketType = SocketType(3)
功能:原始套接字类型。
类型:SocketType
static let SEQPACKET
public static let SEQPACKET: SocketType = SocketType(5)
功能:有序数据包套接字类型。
类型:SocketType
static let STREAM
public static let STREAM: SocketType = SocketType(1)
功能:流式套接字类型。
类型:SocketType
init(Int32)
public init(`type`: Int32)
功能:通过指定套接字类型值创建套接字类型。
参数:
- `type`: Int32 - 套接字类型值。
func hashCode()
public func hashCode(): Int64
功能:返回当前 SocketType 实例的哈希值。
返回值:
- Int64 - 当前 SocketType 实例的哈希值。
func toString()
public func toString(): String
功能:返回当前 SocketType 实例的字符串表示。
返回值:
- String - 当前 SocketType 实例的字符串表示。
operator func !=(SocketType)
public operator func !=(r: SocketType): Bool
功能:判断两个 SocketType 实例是否不等。
参数:
- r: SocketType - 参与比较的 SocketType 实例。
返回值:
operator func ==(SocketType)
public operator func ==(r: SocketType): Bool
功能:判断两个 SocketType 实例是否相等。
参数:
- r: SocketType - 参与比较的 SocketType 实例。
返回值:
异常类
class SocketException
public class SocketException <: IOException {
public init()
public init(message: String)
}
功能:提供套接字相关的异常处理。
父类型:
init()
public init()
功能:创建 SocketException 实例。
init(String)
public init(message: String)
功能:根据异常信息创建 SocketException 实例。
参数:
- message: String - 异常提示信息。
class SocketTimeoutException
public class SocketTimeoutException <: Exception {
public init()
public init(message: String)
}
功能:提供套接字操作超时相关的异常处理。
父类型:
init()
public init()
功能:创建 SocketTimeoutException 实例。
init(String)
public init(message: String)
功能:根据异常信息创建 SocketTimeoutException 实例。
参数:
- message: String - 异常提示信息。
属性配置使用用例
属性配置
import std.net.*
import std.time.*
import std.sync.*
main (){
try (tcpSocket = TcpSocket("127.0.0.1", 80)) {
tcpSocket.readTimeout = Duration.second
tcpSocket.noDelay = false
tcpSocket.linger = Duration.minute
tcpSocket.keepAlive = SocketKeepAliveConfig(
interval: Duration.second * 7,
count: 15
)
}
}
增加自定义属性
import std.net.*
extend TcpSocket {
public mut prop customNoDelay: Int64 {
get() {
Int64(getSocketOptionIntNative(OptionLevel.TCP, SocketOptions.TCP_NODELAY))
}
set(value) {
setSocketOptionIntNative(OptionLevel.TCP, SocketOptions.TCP_NODELAY, IntNative(value))
}
}
}
main() {
let socket = TcpSocket("127.0.0.1", 0)
socket.customNoDelay = 1
println(socket.customNoDelay)
}
运行结果:
1
TCP 使用示例
import std.net.*
import std.sync.*
let SERVER_PORT: UInt16 = 33333
let syncCounter = SyncCounter(1)
func runTcpServer() {
try (serverSocket = TcpServerSocket(bindAt: SERVER_PORT)) {
serverSocket.bind()
syncCounter.dec()
try (client = serverSocket.accept()) {
let buf = Array<Byte>(10, repeat: 0)
let count = client.read(buf)
// Server read 3 bytes: [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]
println("Server read ${count} bytes: ${buf}")
}
}
}
main(): Int64 {
let fut = spawn {
runTcpServer()
}
syncCounter.waitUntilZero()
try (socket = TcpSocket("127.0.0.1", SERVER_PORT)) {
socket.connect()
socket.write([1, 2, 3])
}
fut.get()
return 0
}
运行结果:
Server read 3 bytes: [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]
UDP 使用示例
import std.net.*
import std.sync.*
let SERVER_PORT: UInt16 = 33333
let barrier = Barrier(2)
func runUdpServer() {
try (serverSocket = UdpSocket(bindAt: SERVER_PORT)) {
serverSocket.bind()
barrier.wait()
let buf = Array<Byte>(3, repeat: 0)
let (clientAddr, count) = serverSocket.receiveFrom(buf)
let sender = (clientAddr as IPSocketAddress)?.address.toString() ?? ""
// Server receive 3 bytes: [1, 2, 3] from 127.0.0.1
println("Server receive ${count} bytes: ${buf} from ${sender}")
}
}
main(): Int64 {
let fut = spawn {
runUdpServer()
}
barrier.wait()
try (udpSocket = UdpSocket(bindAt: 0)) { // random port
udpSocket.sendTimeout = Duration.second * 2
udpSocket.bind()
udpSocket.sendTo(
IPSocketAddress("127.0.0.1", SERVER_PORT),
[1, 2, 3]
)
}
fut.get()
return 0
}
运行结果:
Server receive 3 bytes: [1, 2, 3] from 127.0.0.1
UNIX 使用示例
import std.net.*
import std.sync.*
import std.fs.*
let SOCKET_PATH = "/tmp/tmpsock"
let barrier = Barrier(2)
func runUnixServer() {
remove(SOCKET_PATH)
try (serverSocket = UnixServerSocket(bindAt: SOCKET_PATH)) {
serverSocket.bind()
barrier.wait()
try (client = serverSocket.accept()) {
client.write("hello".toArray())
}
}
}
main(): Int64 {
let fut = spawn {
runUnixServer()
}
barrier.wait()
try (socket = UnixSocket(SOCKET_PATH)) {
socket.connect()
let buf = Array<Byte>(10, repeat: 0)
socket.read(buf)
println(String.fromUtf8(buf)) // hello
}
fut.get()
return 0
}
运行结果:
hello
UnixDatagram 使用示例
import std.net.*
import std.sync.*
import std.fs.*
import std.random.*
import std.env.*
let barrier = Barrier(2)
func createTempFile(): String {
let tempDir: Path = getTempDirectory()
let index: String = Random().nextUInt64().toString()
return tempDir.join("tmp${index}").toString()
}
func runUnixDatagramServer(serverPath: String, clientPath: String) {
try (serverSocket = UnixDatagramSocket(bindAt: serverPath)) {
serverSocket.bind()
barrier.wait()
let buf = Array<Byte>(3, repeat: 0)
let (clientAddr, read) = serverSocket.receiveFrom(buf)
if (read == 3 && buf == [1, 2, 3]) {
println("server received")
}
if (clientAddr.toString() == clientPath) {
println("client address correct")
}
}
}
main(): Int64 {
let clientPath = createTempFile()
let serverPath = createTempFile()
let fut = spawn {
runUnixDatagramServer(serverPath, clientPath)
}
barrier.wait()
try (unixSocket = UnixDatagramSocket(bindAt: clientPath)) {
unixSocket.sendTimeout = Duration.second * 2
unixSocket.bind()
unixSocket.connect(serverPath)
unixSocket.send([1, 2, 3])
}
fut.get()
return 0
}
运行结果:
server received
client address correct
std.objectpool
功能介绍
objectpool 包提供了对象缓存和复用的功能。
在面向对象语言中,对象的申请和释放普遍实现复杂,耗时较长,很可能成为应用程序的性能瓶颈。仓颉对象的申请和释放也面临同样的问题。对象池通过缓存、复用对象,减少对象的申请和释放,有效提高程序性能。
本包 ObjectPool 类实现了将指定类型的对象进行缓存和复用,调用 put 方法可将使用完毕的对象放入对象池缓存,调用 get 方法可从对象池缓存中取出待使用的对象。
此外,为了减少竞争,进一步提升对象存取的效率,ObjectPool 在实现中根据当前所在仓颉线程的 id 在不同数组中进行对象存取。
注意:
1、由于
ObjectPool在实现中根据仓颉线程id进行存取,将导致存和取分布在不同仓颉线程的情况下,存入的对象难以被取到。因此应该在存和取均匀分布在各个仓颉线程的场景下使用该对象池。2、暂不支持自动缩减容量。
API列表
类
| 类名 | 功能 |
|---|---|
| ObjectPool (deprecated) | 此类提供了一个并发安全的对象缓存类型,该类型可以储存已经分配内存但未使用的对象。 |
类
class ObjectPool<T> where T <: Object (deprecated)
public class ObjectPool<T> where T <: Object {
public init(newFunc: () -> T, resetFunc!: Option<(T) -> T> = None)
}
功能:此类提供了一个并发安全的对象缓存类型,该类型可以储存已经分配内存但未使用的对象。
当一个对象不需要使用时可以将对象存入 ObjectPool,当需要使用对象时再从该 ObjectPool 中取出。
储存在一个 ObjectPool 中的对象只能是同一种类型。
在一个 ObjectPool 对象的生命周期结束前,该 ObjectPool 对象中存储的对象不会被释放。
注意:
未来版本即将废弃。
示例:
import std.objectpool.*
class City {
var id: Int64 = 0
var name: String = ""
}
func resetCity(c: City): City {
let city = c
city.id = 0
city.name = ""
return city
}
main() {
let cityPool = ObjectPool({ => City()}, resetFunc: resetCity)
let cityA = cityPool.get()
cityA.id = 30
cityA.name = "A"
println("id: ${cityA.id}, name: ${cityA.name}")
cityPool.put(cityA)
}
运行结果:
id: 30, name: A
init(() -> T, Option<(T) -> T>)
public init(newFunc: () -> T, resetFunc!: Option<(T) -> T> = None)
功能:创建新的 ObjectPool 对象。
参数:
- newFunc: () ->T - 当调用 get 方法时,若从 ObjectPool 中获取对象失败,则调用 newFn 创建一个新对象, newFunc 应保证并发安全。
- resetFunc!: Option<(T) ->T> - 调用 get 方法时会调用 resetFunc 重置对象状态,resetFunc 为 None 表示不重置, resetFunc 应保证并发安全。
func get()
public func get(): T
功能:尝试从 ObjectPool 中获取对象, 若从 ObjectPool 中获取对象失败,则调用 newFunc 创建新的对象并返回该对象get 的对象不使用之后应该通过 put 归还给 ObjectPool。
返回值:
- T - 从 ObjectPool 中获取到的对象或调用 newFunc 新建的对象。
func put(T)
public func put(item: T): Unit
功能:尝试将对象放入 ObjectPool 中,不保证一定会将对象放入 ObjectPool在对一个对象调用 put 后不应该再对该对象进行任何操作,否则可能导致不可期问题。
参数:
- item: T - 需要放入 ObjectPool 的对象。
std.overflow
功能介绍
overflow 包提供了整数运算溢出时的处理能力。
在整数运算时,若运算结果大于其类型最大值或小于其类型最小值即是溢出。默认情况下,出现溢出时会抛出异常。
overflow 包提供了四种溢出处理策略,并定义了对应的接口,列举如下:
| 策略 | 接口 | 描述 |
|---|---|---|
| 返回 Option | CheckedOp | 当整数运算出现溢出,返回 None。 |
| 饱和 | SaturatingOp | 当计算结果大于目标类型的 MAX 值,返回 MAX 值;当计算结果小于目标类型的 MIN 值,返回 MIN 值。 |
| 抛出异常 | ThrowingOp | 当整数运算出现溢出,抛出异常。 |
| 高位截断 | WrappingOp | 当整数运算出现溢出,将运算结果中超出目标类型位数的高位截断。 |
overflow 包中通过扩展为所有的整数类型提供了这些接口的实现,用户可以用同样的方式为其他类型实现 overflow 接口。
API 列表
接口
| 接口名 | 功能 |
|---|---|
| CarryingOp | 提供返回整数运算是否发生了截断以及运算结果的接口。 |
| CarryingPow | 提供使用 wrapping 策略的幂运算接口。 |
| CheckedOp | 当整数运算出现溢出,返回 None。 |
| CheckedPow | 提供返回 Option 策略的幂运算接口。 |
| SaturatingOp | 当整数运算出现溢出,饱和处理。 |
| SaturatingPow | 提供饱和策略的幂运算接口。 |
| ThrowingOp | 当整数运算出现溢出,抛出异常。 |
| ThrowingPow | 提供使用抛出异常策略的幂运算接口。 |
| WrappingOp | 当整数运算出现溢出,将运算结果中超出目标类型位数的高位截断。 |
| WrappingPow | 提供使用高位截断策略的幂运算接口。 |
异常类
| 类名 | 功能 |
|---|---|
| OvershiftException | 移位运算时移位位数超过操作数位数时抛出的异常。 |
| UndershiftException | 移位运算时移位位数小于 0 时抛出的异常。 |
接口
interface CarryingOp<T>
public interface CarryingOp<T> {
func carryingAdd(y: T): (Bool, T)
func carryingSub(y: T): (Bool, T)
func carryingMul(y: T): (Bool, T)
func carryingDiv(y: T): (Bool, T)
func carryingMod(y: T): (Bool, T)
func carryingInc(): (Bool, T)
func carryingDec(): (Bool, T)
func carryingNeg(): (Bool, T)
func carryingShl(y: UInt64): (Bool, T)
func carryingShr(y: UInt64): (Bool, T)
}
功能:提供返回整数运算是否发生了截断以及运算结果的接口。
func carryingAdd(T)
func carryingAdd(y: T): (Bool, T)
功能:返回一个元组,元组的第一个元素表示加法运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
参数:
- y: T - 加数。
返回值:
- (Bool, T) - 加法运算是否发生截断以及运算的结果。
func carryingDec()
func carryingDec(): (Bool, T)
功能:返回一个元组,元组的第一个元素表示自减运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
返回值:
- (Bool, T) - 自减运算是否发生截断以及运算的结果。
func carryingDiv(T)
func carryingDiv(y: T): (Bool, T)
功能:返回一个元组,元组的第一个元素表示除法运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
参数:
- y: T - 除数。
返回值:
- (Bool, T) - 除法运算是否发生截断以及运算的结果。
func carryingInc()
func carryingInc(): (Bool, T)
功能:返回一个元组,元组的第一个元素表示自增运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
返回值:
- (Bool, T) - 自增运算是否发生截断以及运算的结果。
func carryingMod(T)
func carryingMod(y: T): (Bool, T)
功能:返回一个元组,元组的第一个元素表示取余运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
参数:
- y: T - 除数。
返回值:
- (Bool, T) - 取余运算是否发生截断以及运算的结果。
func carryingMul(T)
func carryingMul(y: T): (Bool, T)
功能:返回一个元组,元组的第一个元素表示乘法运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
参数:
- y: T - 乘数。
返回值:
- (Bool, T) - 乘法运算是否发生截断以及运算的结果。
func carryingNeg()
func carryingNeg(): (Bool, T)
功能:返回一个元组,元组的第一个元素表示负号运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
返回值:
- (Bool, T) - 负号运算是否发生截断以及运算的结果。
func carryingShl(UInt64)
func carryingShl(y: UInt64): (Bool, T)
功能:返回一个元组,元组的第一个元素表示左移运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- (Bool, T) - 左移运算是否发生截断以及运算的结果。
func carryingShr(UInt64)
func carryingShr(y: UInt64): (Bool, T)
功能:返回一个元组,元组的第一个元素表示右移运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- (Bool, T) - 右移运算是否发生截断以及运算的结果。
func carryingSub(T)
func carryingSub(y: T): (Bool, T)
功能:返回一个元组,元组的第一个元素表示减法运算是否发生了截断,发生截断时为 true,元组的第二个元素是运算的结果。
参数:
- y: T - 减数。
返回值:
- (Bool, T) - 减法运算是否发生截断以及运算的结果。
extend Int16 <: CarryingOp<Int16>
extend Int16 <: CarryingOp<Int16>
功能:为 Int16 实现 CarryingOp 接口。
父类型:
func carryingAdd(Int16)
public func carryingAdd(y: Int16): (Bool, Int16)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int16 - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, Int16)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(Int16)
public func carryingDiv(y: Int16): (Bool, Int16)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int16 - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, Int16)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(Int16)
public func carryingMod(y: Int16): (Bool, Int16)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int16 - 除数。
返回值:
func carryingMul(Int16)
public func carryingMul(y: Int16): (Bool, Int16)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int16 - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, Int16)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, Int16)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, Int16)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(Int16)
public func carryingSub(y: Int16): (Bool, Int16)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int16 - 减数。
返回值:
extend Int32 <: CarryingOp<Int32>
extend Int32 <: CarryingOp<Int32>
功能:为 Int32 实现 CarryingOp 接口。
父类型:
func carryingAdd(Int32)
public func carryingAdd(y: Int32): (Bool, Int32)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int32 - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, Int32)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(Int32)
public func carryingDiv(y: Int32): (Bool, Int32)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int32 - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, Int32)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(Int32)
public func carryingMod(y: Int32): (Bool, Int32)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int32 - 除数。
返回值:
func carryingMul(Int32)
public func carryingMul(y: Int32): (Bool, Int32)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int32 - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, Int32)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, Int32)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, Int32)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(Int32)
public func carryingSub(y: Int32): (Bool, Int32)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int32 - 减数。
返回值:
extend Int64 <: CarryingOp<Int64> & CarryingPow
extend Int64 <: CarryingOp<Int64> & CarryingPow
功能:为 Int64 实现 CarryingOp 接口和 CarryingPow 接口。
父类型:
func carryingAdd(Int64)
public func carryingAdd(y: Int64): (Bool, Int64)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int64 - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, Int64)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(Int64)
public func carryingDiv(y: Int64): (Bool, Int64)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int64 - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, Int64)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(Int64)
public func carryingMod(y: Int64): (Bool, Int64)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int64 - 除数。
返回值:
func carryingMul(Int64)
public func carryingMul(y: Int64): (Bool, Int64)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int64 - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, Int64)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingPow(UInt64)
public func carryingPow(y: UInt64): (Bool, Int64)
功能:使用 wrapping 策略的幂运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 指数。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, Int64)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, Int64)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(Int64)
public func carryingSub(y: Int64): (Bool, Int64)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int64 - 减数。
返回值:
extend Int8 <: CarryingOp<Int8>
extend Int8 <: CarryingOp<Int8>
功能:为 Int8 实现 CarryingOp 接口。
父类型:
func carryingAdd(Int8)
public func carryingAdd(y: Int8): (Bool, Int8)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int8 - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, Int8)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(Int8)
public func carryingDiv(y: Int8): (Bool, Int8)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int8 - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, Int8)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(Int8)
public func carryingMod(y: Int8): (Bool, Int8)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int8 - 除数。
返回值:
func carryingMul(Int8)
public func carryingMul(y: Int8): (Bool, Int8)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int8 - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, Int8)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, Int8)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, Int8)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(Int8)
public func carryingSub(y: Int8):(Bool, Int8)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: Int8 - 减数。
返回值:
extend IntNative <: CarryingOp<IntNative>
extend IntNative <: CarryingOp<IntNative>
功能:为 IntNative 实现 CarryingOp 接口。
父类型:
func carryingAdd(IntNative)
public func carryingAdd(y: IntNative): (Bool, IntNative)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: IntNative - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, IntNative)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(IntNative)
public func carryingDiv(y: IntNative): (Bool, IntNative)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: IntNative - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, IntNative)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(IntNative)
public func carryingMod(y: IntNative): (Bool, IntNative)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: IntNative - 除数。
返回值:
func carryingMul(IntNative)
public func carryingMul(y: IntNative): (Bool, IntNative)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: IntNative - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, IntNative)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, IntNative)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, IntNative)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(IntNative)
public func carryingSub(y: IntNative): (Bool, IntNative)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: IntNative - 减数。
返回值:
extend UInt16 <: CarryingOp<UInt16>
extend UInt16 <: CarryingOp<UInt16>
功能:为 UInt16 实现 CarryingOp 接口。
父类型:
func carryingAdd(UInt16)
public func carryingAdd(y: UInt16): (Bool, UInt16)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt16 - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, UInt16)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(UInt16)
public func carryingDiv(y: UInt16): (Bool, UInt16)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt16 - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, UInt16)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(UInt16)
public func carryingMod(y: UInt16): (Bool, UInt16)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt16 - 除数。
返回值:
func carryingMul(UInt16)
public func carryingMul(y: UInt16): (Bool, UInt16)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt16 - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, UInt16)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, UInt16)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, UInt16)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(UInt16)
public func carryingSub(y: UInt16): (Bool, UInt16)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt16 - 减数。
返回值:
extend UInt32 <: CarryingOp<UInt32>
extend UInt32 <: CarryingOp<UInt32>
功能:为 UInt32 实现 CarryingOp 接口。
父类型:
func carryingAdd(UInt32)
public func carryingAdd(y: UInt32): (Bool, UInt32)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt32 - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, UInt32)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(UInt32)
public func carryingDiv(y: UInt32): (Bool, UInt32)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt32 - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, UInt32)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(UInt32)
public func carryingMod(y: UInt32): (Bool, UInt32)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt32 - 除数。
返回值:
func carryingMul(UInt32)
public func carryingMul(y: UInt32): (Bool, UInt32)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt32 - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, UInt32)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, UInt32)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, UInt32)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(UInt32)
public func carryingSub(y: UInt32): (Bool, UInt32)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt32 - 减数。
返回值:
extend UInt64 <: CarryingOp<UInt64>
extend UInt64 <: CarryingOp<UInt64>
功能:为 UInt64 实现 CarryingOp 接口。
父类型:
func carryingAdd(UInt64)
public func carryingAdd(y: UInt64): (Bool, UInt64)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, UInt64)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(UInt64)
public func carryingDiv(y: UInt64): (Bool, UInt64)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, UInt64)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(UInt64)
public func carryingMod(y: UInt64): (Bool, UInt64)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 除数。
返回值:
func carryingMul(UInt64)
public func carryingMul(y: UInt64): (Bool, UInt64)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, UInt64)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, UInt64)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, UInt64)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(UInt64)
public func carryingSub(y: UInt64): (Bool, UInt64)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 减数。
返回值:
extend UInt8 <: CarryingOp<UInt8>
extend UInt8 <: CarryingOp<UInt8>
功能:为 UInt8 实现 CarryingOp 接口。
父类型:
func carryingAdd(UInt8)
public func carryingAdd(y: UInt8): (Bool, UInt8)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt8 - 加数。
返回值:
func carryingDec()
public func carryingDec(): (Bool, UInt8)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingDiv(UInt8)
public func carryingDiv(y: UInt8): (Bool, UInt8)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt8 - 除数。
返回值:
func carryingInc()
public func carryingInc(): (Bool, UInt8)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingMod(UInt8)
public func carryingMod(y: UInt8): (Bool, UInt8)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt8 - 除数。
返回值:
func carryingMul(UInt8)
public func carryingMul(y: UInt8): (Bool, UInt8)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt8 - 乘数。
返回值:
func carryingNeg()
public func carryingNeg(): (Bool, UInt8)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, UInt8)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, UInt8)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
func carryingSub(UInt8)
public func carryingSub(y: UInt8): (Bool, UInt8)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt8 - 减数。
返回值:
extend UIntNative <: CarryingOp<UIntNative>
extend UIntNative <: CarryingOp<UIntNative>
功能:为 UIntNative 实现 CarryingOp 接口。
父类型:
func carryingAdd(UIntNative)
public func carryingAdd(y: UIntNative): (Bool, UIntNative)
功能:使用 wrapping 策略的加法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UIntNative - 加数。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingDec()
public func carryingDec(): (Bool, UIntNative)
功能:使用 wrapping 策略的自减运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingDiv(UIntNative)
public func carryingDiv(y: UIntNative): (Bool, UIntNative)
功能:使用 wrapping 策略的除法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingInc()
public func carryingInc(): (Bool, UIntNative)
功能:使用 wrapping 策略的自增运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingMod(UIntNative)
public func carryingMod(y: UIntNative): (Bool, UIntNative)
功能:使用 wrapping 策略的取余运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingMul(UIntNative)
public func carryingMul(y: UIntNative): (Bool, UIntNative)
功能:使用 wrapping 策略的乘法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UIntNative - 乘数。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingNeg()
public func carryingNeg(): (Bool, UIntNative)
功能:使用 wrapping 策略的负号运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingShl(UInt64)
public func carryingShl(y: UInt64): (Bool, UIntNative)
功能:使用 wrapping 策略的左移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingShr(UInt64)
public func carryingShr(y: UInt64): (Bool, UIntNative)
功能:使用 wrapping 策略的右移运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
func carryingSub(UIntNative)
public func carryingSub(y: UIntNative): (Bool, UIntNative)
功能:使用 wrapping 策略的减法运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UIntNative - 减数。
返回值:
- (Bool, UIntNative) - 返回一个元组,元组的第一个元素表示运算是否发生了截断,发生截断时为
true,元组的第二个元素是运算的结果。
interface CarryingPow
public interface CarryingPow {
func carryingPow(y: UInt64): (Bool, Int64)
}
功能:提供使用 wrapping 策略的幂运算接口。
func carryingPow(UInt64)
func carryingPow(y: UInt64): (Bool, Int64)
功能:使用 wrapping 策略的幂运算。
当运算出现溢出时,返回 true 和运算结果,否则返回 false 和运算结果。
参数:
- y: UInt64 - 指数。
返回值:
interface CheckedOp<T>
public interface CheckedOp<T> {
func checkedAdd(y: T): ?T
func checkedDec(): ?T
func checkedDiv(y: T): ?T
func checkedInc(): ?T
func checkedMod(y: T): ?T
func checkedMul(y: T): ?T
func checkedNeg(): ?T
func checkedShl(y: UInt64): ?T
func checkedShr(y: UInt64): ?T
func checkedSub(y: T): ?T
}
功能:当整数运算出现溢出,返回 None。
func checkedAdd(T)
func checkedAdd(y: T): ?T
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?T.None,否则返回运算结果。
参数:
- y: T - 加数。
返回值:
- ?T - 加法运算结果。
func checkedDec()
func checkedDec(): ?T
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?T.None,否则返回运算结果。
返回值:
- ?T - 自减运算结果。
func checkedDiv(T)
func checkedDiv(y: T): ?T
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?T.None,否则返回运算结果。
参数:
- y: T - 除数。
返回值:
- ?T - 除法运算结果。
func checkedInc()
func checkedInc(): ?T
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?T.None,否则返回运算结果。
返回值:
- ?T - 自增运算结果。
func checkedMod(T)
func checkedMod(y: T): ?T
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?T.None,否则返回运算结果。
参数:
- y: T - 除数。
返回值:
- ?T - 取余运算结果。
func checkedMul(T)
func checkedMul(y: T): ?T
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?T.None,否则返回运算结果。
参数:
- y: T - 乘数。
返回值:
- ?T - 乘法运算结果。
func checkedNeg()
func checkedNeg(): ?T
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?T.None,否则返回运算结果。
返回值:
- ?T - 负号运算结果。
func checkedShl(UInt64)
func checkedShl(y: UInt64): ?T
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?T.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?T - 左移运算结果。
func checkedShr(UInt64)
func checkedShr(y: UInt64): ?T
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?T.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?T - 右移运算结果。
func checkedSub(T)
func checkedSub(y: T): ?T
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?T.None,否则返回运算结果。
参数:
- y: T - 减数。
返回值:
- ?T - 减法运算结果。
extend Int16 <: CheckedOp<Int16>
extend Int16 <: CheckedOp<Int16>
父类型:
func checkedAdd(Int16)
public func checkedAdd(y: Int16): ?Int16
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?Int16.None,否则返回运算结果。
参数:
- y: Int16 - 加数。
返回值:
- ?Int16 - 加法运算结果。
func checkedDec()
public func checkedDec(): ?Int16
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?Int16.None,否则返回运算结果。
返回值:
- ?Int16 - 自减运算结果。
func checkedDiv(Int16)
public func checkedDiv(y: Int16): ?Int16
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?Int16.None,否则返回运算结果。
参数:
- y: Int16 - 除数。
返回值:
- ?Int16 - 除法运算结果。
func checkedInc()
public func checkedInc(): ?Int16
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?Int16.None,否则返回运算结果。
返回值:
- ?Int16 - 自增运算结果。
func checkedMod(Int16)
public func checkedMod(y: Int16): ?Int16
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?Int16.None,否则返回运算结果。
参数:
- y: Int16 - 除数。
返回值:
- ?Int16 - 取余运算结果。
func checkedMul(Int16)
public func checkedMul(y: Int16): ?Int16
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?Int16.None,否则返回运算结果。
参数:
- y: Int16 - 乘数。
返回值:
- ?Int16 - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?Int16
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?Int16.None,否则返回运算结果。
返回值:
- ?Int16 - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?Int16
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?Int16.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?Int16 - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?Int16
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?Int16.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?Int16 - 右移运算结果。
func checkedSub(Int16)
public func checkedSub(y: Int16): ?Int16
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?Int16.None,否则返回运算结果。
参数:
- y: Int16 - 减数。
返回值:
- ?Int16 - 减法运算结果。
extend Int32 <: CheckedOp<Int32>
extend Int32 <: CheckedOp<Int32>
父类型:
func checkedAdd(Int32)
public func checkedAdd(y: Int32): ?Int32
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?Int32.None,否则返回运算结果。
参数:
- y: Int32 - 加数。
返回值:
- ?Int32 - 加法运算结果。
func checkedDec()
public func checkedDec(): ?Int32
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?Int32.None,否则返回运算结果。
返回值:
- ?Int32 - 自减运算结果。
func checkedDiv(Int32)
public func checkedDiv(y: Int32): ?Int32
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?Int32.None,否则返回运算结果。
参数:
- y: Int32 - 除数。
返回值:
- ?Int32 - 除法运算结果。
func checkedInc()
public func checkedInc(): ?Int32
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?Int32.None,否则返回运算结果。
返回值:
- ?Int32 - 自增运算结果。
func checkedMod(Int32)
public func checkedMod(y: Int32): ?Int32
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?Int32.None,否则返回运算结果。
参数:
- y: Int32 - 除数。
返回值:
- ?Int32 - 取余运算结果。
func checkedMul(Int32)
public func checkedMul(y: Int32): ?Int32
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?Int32.None,否则返回运算结果。
参数:
- y: Int32 - 乘数。
返回值:
- ?Int32 - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?Int32
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?Int32.None,否则返回运算结果。
返回值:
- ?Int32 - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?Int32
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?Int32.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?Int32 - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?Int32
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?Int32.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?Int32 - 右移运算结果。
func checkedSub(Int32)
public func checkedSub(y: Int32): ?Int32
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?Int32.None,否则返回运算结果。
参数:
- y: Int32 - 减数。
返回值:
- ?Int32 - 减法运算结果。
extend Int64 <: CheckedOp<Int64> & CheckedPow
extend Int64 <: CheckedOp<Int64> & CheckedPow
功能:为 Int64 实现 CheckedOp 和 CheckedPow 接口。
父类型:
func checkedAdd(Int64)
public func checkedAdd(y: Int64): ?Int64
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: Int64 - 加数。
返回值:
- ?Int64 - 加法运算结果。
func checkedDec()
public func checkedDec(): ?Int64
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
返回值:
- ?Int64 - 自减运算结果。
func checkedDiv(Int64)
public func checkedDiv(y: Int64): ?Int64
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: Int64 - 除数。
返回值:
- ?Int64 - 除法运算结果。
func checkedInc()
public func checkedInc(): ?Int64
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
返回值:
- ?Int64 - 自增运算结果。
func checkedMod(Int64)
public func checkedMod(y: Int64): ?Int64
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: Int64 - 除数。
返回值:
- ?Int64 - 取余运算结果。
func checkedMul(Int64)
public func checkedMul(y: Int64): ?Int64
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: Int64 - 乘数。
返回值:
- ?Int64 - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?Int64
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
返回值:
- ?Int64 - 负号运算结果。
func checkedPow(UInt64)
public func checkedPow(y: UInt64): ?Int64
功能:使用返回 Option 策略的幂运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: UInt64 - 指数。
返回值:
- ?Int64 - 幂运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?Int64
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?Int64 - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?Int64
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?Int64 - 右移运算结果。
func checkedSub(Int64)
public func checkedSub(y: Int64): ?Int64
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: Int64 - 减数。
返回值:
- ?Int64 - 减法运算结果。
extend Int8 <: CheckedOp<Int8>
extend Int8 <: CheckedOp<Int8>
父类型:
func checkedAdd(Int8)
public func checkedAdd(y: Int8): ?Int8
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?Int8.None,否则返回运算结果。
参数:
- y: Int8 - 加数。
返回值:
- ?Int8 - 加法运算结果。
func checkedDec()
public func checkedDec(): ?Int8
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?Int8.None,否则返回运算结果。
返回值:
- ?Int8 - 自减运算结果。
func checkedDiv(Int8)
public func checkedDiv(y: Int8): ?Int8
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?Int8.None,否则返回运算结果。
参数:
- y: Int8 - 除数。
返回值:
- ?Int8 - 除法运算结果。
func checkedInc()
public func checkedInc(): ?Int8
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?Int8.None,否则返回运算结果。
返回值:
- ?Int8 - 自增运算结果。
func checkedMod(Int8)
public func checkedMod(y: Int8): ?Int8
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?Int8.None,否则返回运算结果。
参数:
- y: Int8 - 除数。
返回值:
- ?Int8 - 取余运算结果。
func checkedMul(Int8)
public func checkedMul(y: Int8): ?Int8
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?Int8.None,否则返回运算结果。
参数:
- y: Int8 - 乘数。
返回值:
- ?Int8 - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?Int8
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?Int8.None,否则返回运算结果。
返回值:
- ?Int8 - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?Int8
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?Int8.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?Int8 - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?Int8
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?Int8.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?Int8 - 右移运算结果。
func checkedSub(Int8)
public func checkedSub(y: Int8): ?Int8
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?Int8.None,否则返回运算结果。
参数:
- y: Int8 - 减数。
返回值:
- ?Int8 - 减法运算结果。
extend IntNative <: CheckedOp<IntNative>
extend IntNative <: CheckedOp<IntNative>
功能:为 IntNative 实现 CheckedOp 接口。
父类型:
func checkedAdd(IntNative)
public func checkedAdd(y: IntNative): ?IntNative
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?IntNative.None,否则返回运算结果。
参数:
- y: IntNative - 加数。
返回值:
- ?IntNative - 加法运算结果。
func checkedDec()
public func checkedDec(): ?IntNative
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?IntNative.None,否则返回运算结果。
返回值:
- ?IntNative - 自减运算结果。
func checkedDiv(IntNative)
public func checkedDiv(y: IntNative): ?IntNative
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?IntNative.None,否则返回运算结果。
参数:
- y: IntNative - 除数。
返回值:
- ?IntNative - 除法运算结果。
func checkedInc()
public func checkedInc(): ?IntNative
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?IntNative.None,否则返回运算结果。
返回值:
- ?IntNative - 自增运算结果。
func checkedMod(IntNative)
public func checkedMod(y: IntNative): ?IntNative
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?IntNative.None,否则返回运算结果。
参数:
- y: IntNative - 除数。
返回值:
- ?IntNative - 取余运算结果。
func checkedMul(IntNative)
public func checkedMul(y: IntNative): ?IntNative
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?IntNative.None,否则返回运算结果。
参数:
- y: IntNative - 乘数。
返回值:
- ?IntNative - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?IntNative
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?IntNative.None,否则返回运算结果。
返回值:
- ?IntNative - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?IntNative
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?IntNative.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?IntNative - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?IntNative
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?IntNative.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?IntNative - 右移运算结果。
func checkedSub(IntNative)
public func checkedSub(y: IntNative): ?IntNative
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?IntNative.None,否则返回运算结果。
参数:
- y: IntNative - 减数。
返回值:
- ?IntNative - 减法运算结果。
extend UInt16 <: CheckedOp<UInt16>
extend UInt16 <: CheckedOp<UInt16>
父类型:
func checkedAdd(UInt16)
public func checkedAdd(y: UInt16): ?UInt16
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?UInt16.None,否则返回运算结果。
参数:
- y: UInt16 - 加数。
返回值:
- ?UInt16 - 加法运算结果。
func checkedDec()
public func checkedDec(): ?UInt16
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?UInt16.None,否则返回运算结果。
返回值:
- ?UInt16 - 自减运算结果。
func checkedDiv(UInt16)
public func checkedDiv(y: UInt16): ?UInt16
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?UInt16.None,否则返回运算结果。
参数:
- y: UInt16 - 除数。
返回值:
- ?UInt16 - 除法运算结果。
func checkedInc()
public func checkedInc(): ?UInt16
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?UInt16.None,否则返回运算结果。
返回值:
- ?UInt16 - 自增运算结果。
func checkedMod(UInt16)
public func checkedMod(y: UInt16): ?UInt16
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?UInt16.None,否则返回运算结果。
参数:
- y: UInt16 - 除数。
返回值:
- ?UInt16 - 取余运算结果。
func checkedMul(UInt16)
public func checkedMul(y: UInt16): ?UInt16
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?UInt16.None,否则返回运算结果。
参数:
- y: UInt16 - 乘数。
返回值:
- ?UInt16 - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?UInt16
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?UInt16.None,否则返回运算结果。
返回值:
- ?UInt16 - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?UInt16
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?UInt16.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UInt16 - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?UInt16
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?UInt16.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UInt16 - 右移运算结果。
func checkedSub(UInt16)
public func checkedSub(y: UInt16): ?UInt16
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?UInt16.None,否则返回运算结果。
参数:
- y: UInt16 - 减数。
返回值:
- ?UInt16 - 减法运算结果。
extend UInt32 <: CheckedOp<UInt32>
extend UInt32 <: CheckedOp<UInt32>
父类型:
func checkedAdd(UInt32)
public func checkedAdd(y: UInt32): ?UInt32
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?UInt32.None,否则返回运算结果。
参数:
- y: UInt32 - 加数。
返回值:
- ?UInt32 - 加法运算结果。
func checkedDec()
public func checkedDec(): ?UInt32
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?UInt32.None,否则返回运算结果。
返回值:
- ?UInt32 - 自减运算结果。
func checkedDiv(UInt32)
public func checkedDiv(y: UInt32): ?UInt32
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?UInt32.None,否则返回运算结果。
参数:
- y: UInt32 - 除数。
返回值:
- ?UInt32 - 除法运算结果。
func checkedInc()
public func checkedInc(): ?UInt32
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?UInt32.None,否则返回运算结果。
返回值:
- ?UInt32 - 自增运算结果。
func checkedMod(UInt32)
public func checkedMod(y: UInt32): ?UInt32
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?UInt32.None,否则返回运算结果。
参数:
- y: UInt32 - 除数。
返回值:
- ?UInt32 - 取余运算结果。
func checkedMul(UInt32)
public func checkedMul(y: UInt32): ?UInt32
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?UInt32.None,否则返回运算结果。
参数:
- y: UInt32 - 乘数。
返回值:
- ?UInt32 - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?UInt32
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?UInt32.None,否则返回运算结果。
返回值:
- ?UInt32 - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?UInt32
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?UInt32.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UInt32 - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?UInt32
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?UInt32.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UInt32 - 右移运算结果。
func checkedSub(UInt32)
public func checkedSub(y: UInt32): ?UInt32
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?UInt32.None,否则返回运算结果。
参数:
- y: UInt32 - 减数。
返回值:
- ?UInt32 - 减法运算结果。
extend UInt64 <: CheckedOp<UInt64>
extend UInt64 <: CheckedOp<UInt64>
父类型:
func checkedAdd(UInt64)
public func checkedAdd(y: UInt64): ?UInt64
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?UInt64.None,否则返回运算结果。
参数:
- y: UInt64 - 加数。
返回值:
- ?UInt64 - 加法运算结果。
func checkedDec()
public func checkedDec(): ?UInt64
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?UInt64.None,否则返回运算结果。
返回值:
- ?UInt64 - 自减运算结果。
func checkedDiv(UInt64)
public func checkedDiv(y: UInt64): ?UInt64
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?UInt64.None,否则返回运算结果。
参数:
- y: UInt64 - 除数。
返回值:
- ?UInt64 - 除法运算结果。
func checkedInc()
public func checkedInc(): ?UInt64
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?UInt64.None,否则返回运算结果。
返回值:
- ?UInt64 - 自增运算结果。
func checkedMod(UInt64)
public func checkedMod(y: UInt64): ?UInt64
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?UInt64.None,否则返回运算结果。
参数:
- y: UInt64 - 除数。
返回值:
- ?UInt64 - 取余运算结果。
func checkedMul(UInt64)
public func checkedMul(y: UInt64): ?UInt64
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?UInt64.None,否则返回运算结果。
参数:
- y: UInt64 - 乘数。
返回值:
- ?UInt64 - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?UInt64
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?UInt64.None,否则返回运算结果。
返回值:
- ?UInt64 - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?UInt64
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?UInt64.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UInt64 - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?UInt64
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?UInt64.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UInt64 - 右移运算结果。
func checkedSub(UInt64)
public func checkedSub(y: UInt64): ?UInt64
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?UInt64.None,否则返回运算结果。
参数:
- y: UInt64 - 减数。
返回值:
- ?UInt64 - 减法运算结果。
extend UInt8 <: CheckedOp<UInt8>
extend UInt8 <: CheckedOp<UInt8>
父类型:
func checkedAdd(UInt8)
public func checkedAdd(y: UInt8): ?UInt8
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?UInt8.None,否则返回运算结果。
参数:
- y: UInt8 - 加数。
返回值:
- ?UInt8 - 加法运算结果。
func checkedDec()
public func checkedDec(): ?UInt8
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?UInt8.None,否则返回运算结果。
返回值:
- ?UInt8 - 自减运算结果。
func checkedDiv(UInt8)
public func checkedDiv(y: UInt8): ?UInt8
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?UInt8.None,否则返回运算结果。
参数:
- y: UInt8 - 除数。
返回值:
- ?UInt8 - 除法运算结果。
func checkedInc()
public func checkedInc(): ?UInt8
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?UInt8.None,否则返回运算结果。
返回值:
- ?UInt8 - 自增运算结果。
func checkedMod(UInt8)
public func checkedMod(y: UInt8): ?UInt8
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?UInt8.None,否则返回运算结果。
参数:
- y: UInt8 - 除数。
返回值:
- ?UInt8 - 取余运算结果。
func checkedMul(UInt8)
public func checkedMul(y: UInt8): ?UInt8
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?UInt8.None,否则返回运算结果。
参数:
- y: UInt8 - 乘数。
返回值:
- ?UInt8 - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?UInt8
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?UInt8.None,否则返回运算结果。
返回值:
- ?UInt8 - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?UInt8
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?UInt8.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UInt8 - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?UInt8
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?UInt8.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UInt8 - 右移运算结果。
func checkedSub(UInt8)
public func checkedSub(y: UInt8): ?UInt8
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?UInt8.None,否则返回运算结果。
参数:
- y: UInt8 - 减数。
返回值:
- ?UInt8 - 减法运算结果。
extend UIntNative <: CheckedOp<UIntNative>
extend UIntNative <: CheckedOp<UIntNative>
功能:为 UIntNative 实现 CheckedOp 接口。
父类型:
func checkedAdd(UIntNative)
public func checkedAdd(y: UIntNative): ?UIntNative
功能:使用返回 Option 策略的加法运算。
当运算出现溢出时,返回 ?UIntNative.None,否则返回运算结果。
参数:
- y: UIntNative - 加数。
返回值:
- ?UIntNative - 加法运算结果。
func checkedDec()
public func checkedDec(): ?UIntNative
功能:使用返回 Option 策略的自减运算。
当运算出现溢出时,返回 ?UIntNative.None,否则返回运算结果。
返回值:
- ?UIntNative - 自减运算结果。
func checkedDiv(UIntNative)
public func checkedDiv(y: UIntNative): ?UIntNative
功能:使用返回 Option 策略的除法运算。
当运算出现溢出时,返回 ?UIntNative.None,否则返回运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- ?UIntNative - 除法运算结果。
func checkedInc()
public func checkedInc(): ?UIntNative
功能:使用返回 Option 策略的自增运算。
当运算出现溢出时,返回 ?UIntNative.None,否则返回运算结果。
返回值:
- ?UIntNative - 自增运算结果。
func checkedMod(UIntNative)
public func checkedMod(y: UIntNative): ?UIntNative
功能:使用返回 Option 策略的取余运算。
当运算出现溢出时,返回 ?UIntNative.None,否则返回运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- ?UIntNative - 取余运算结果。
func checkedMul(UIntNative)
public func checkedMul(y: UIntNative): ?UIntNative
功能:使用返回 Option 策略的乘法运算。
当运算出现溢出时,返回 ?UIntNative.None,否则返回运算结果。
参数:
- y: UIntNative - 乘数。
返回值:
- ?UIntNative - 乘法运算结果。
func checkedNeg()
public func checkedNeg(): ?UIntNative
功能:使用返回 Option 策略的负号运算。
当运算出现溢出时,返回 ?UIntNative.None,否则返回运算结果。
返回值:
- ?UIntNative - 负号运算结果。
func checkedShl(UInt64)
public func checkedShl(y: UInt64): ?UIntNative
功能:使用返回 Option 策略的左移运算。
当移位位数大于等于操作数位数时,返回 ?UIntNative.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UIntNative - 左移运算结果。
func checkedShr(UInt64)
public func checkedShr(y: UInt64): ?UIntNative
功能:使用返回 Option 策略的右移运算。
当移位位数大于等于操作数位数时,返回 ?UIntNative.None,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- ?UIntNative - 右移运算结果。
func checkedSub(UIntNative)
public func checkedSub(y: UIntNative): ?UIntNative
功能:使用返回 Option 策略的减法运算。
当运算出现溢出时,返回 ?UIntNative.None,否则返回运算结果。
参数:
- y: UIntNative - 减数。
返回值:
- ?UIntNative - 减法运算结果。
interface CheckedPow
public interface CheckedPow {
func checkedPow(y: UInt64): ?Int64
}
功能:提供返回 Option 策略的幂运算接口。
func checkedPow(UInt64)
func checkedPow(y: UInt64): ?Int64
功能:使用返回 Option 策略的幂运算。
当运算出现溢出时,返回 ?Int64.None,否则返回运算结果。
参数:
- y: UInt64 - 指数。
返回值:
- ?Int64 - 幂运算结果。
interface SaturatingOp<T>
public interface SaturatingOp<T> {
func saturatingAdd(y: T): T
func saturatingDec(): T
func saturatingDiv(y: T): T
func saturatingInc(): T
func saturatingMod(y: T): T
func saturatingMul(y: T): T
func saturatingNeg(): T
func saturatingShl(y: UInt64): T
func saturatingShr(y: UInt64): T
func saturatingSub(y: T): T
}
功能:当整数运算出现溢出,饱和处理。
func saturatingAdd(T)
func saturatingAdd(y: T): T
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: T - 加数。
返回值:
- T - 加法运算结果。
func saturatingDec()
func saturatingDec(): T
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- T - 自减运算结果。
func saturatingDiv(T)
func saturatingDiv(y: T): T
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: T - 除数。
返回值:
- T - 除法运算结果。
func saturatingInc()
func saturatingInc(): T
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- T - 自增运算结果。
func saturatingMod(T)
func saturatingMod(y: T): T
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: T - 除数。
返回值:
- T - 取余运算结果。
func saturatingMul(T)
func saturatingMul(y: T): T
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: T - 乘数。
返回值:
- T - 乘法运算结果。
func saturatingNeg()
func saturatingNeg(): T
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- T - 负号运算结果。
func saturatingShl(UInt64)
func saturatingShl(y: UInt64): T
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- T - 左移运算结果。
func saturatingShr(UInt64)
func saturatingShr(y: UInt64): T
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- T - 右移运算结果。
func saturatingSub(T)
func saturatingSub(y: T): T
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: T - 减数。
返回值:
- T - 减法运算结果。
extend Int16 <: SaturatingOp<Int16>
extend Int16 <: SaturatingOp<Int16>
功能:为 Int16 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(Int16)
public func saturatingAdd(y: Int16): Int16
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int16 - 加数。
返回值:
- Int16 - 加法运算结果。
func saturatingDec()
public func saturatingDec(): Int16
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- Int16 - 自减运算结果。
func saturatingDiv(Int16)
public func saturatingDiv(y: Int16): Int16
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: Int16 - 除数。
返回值:
- Int16 - 除法运算结果。
func saturatingInc()
public func saturatingInc(): Int16
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- Int16 - 自增运算结果。
func saturatingMod(Int16)
public func saturatingMod(y: Int16): Int16
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: Int16 - 除数。
返回值:
- Int16 - 取余运算结果。
func saturatingMul(Int16)
public func saturatingMul(y: Int16): Int16
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int16 - 乘数。
返回值:
- Int16 - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): Int16
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- Int16 - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): Int16
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int16 - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): Int16
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int16 - 右移运算结果。
func saturatingSub(Int16)
public func saturatingSub(y: Int16): Int16
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int16 - 减数。
返回值:
- Int16 - 减法运算结果。
extend Int32 <: SaturatingOp<Int32>
extend Int32 <: SaturatingOp<Int32>
功能:为 Int32 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(Int32)
public func saturatingAdd(y: Int32): Int32
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int32 - 加数。
返回值:
- Int32 - 加法运算结果。
func saturatingDec()
public func saturatingDec(): Int32
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- Int32 - 自减运算结果。
func saturatingDiv(Int32)
public func saturatingDiv(y: Int32): Int32
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: Int32 - 除数。
返回值:
- Int32 - 除法运算结果。
func saturatingInc()
public func saturatingInc(): Int32
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- Int32 - 自增运算结果。
func saturatingMod(Int32)
public func saturatingMod(y: Int32): Int32
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: Int32 - 除数。
返回值:
- Int32 - 取余运算结果。
func saturatingMul(Int32)
public func saturatingMul(y: Int32): Int32
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int32 - 乘数。
返回值:
- Int32 - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): Int32
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- Int32 - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): Int32
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int32 - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): Int32
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int32 - 右移运算结果。
func saturatingSub(Int32)
public func saturatingSub(y: Int32): Int32
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int32 - 减数。
返回值:
- Int32 - 减法运算结果。
extend Int64 <: SaturatingOp<Int64> & SaturatingPow
extend Int64 <: SaturatingOp<Int64> & SaturatingPow
功能:为 Int64 实现 SaturatingOp 和 SaturatingPow 接口。
父类型:
func saturatingAdd(Int64)
public func saturatingAdd(y: Int64): Int64
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int64 - 加数。
返回值:
- Int64 - 加法运算结果。
func saturatingDec()
public func saturatingDec(): Int64
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- Int64 - 自减运算结果。
func saturatingDiv(Int64)
public func saturatingDiv(y: Int64): Int64
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: Int64 - 除数。
返回值:
- Int64 - 除法运算结果。
func saturatingInc()
public func saturatingInc(): Int64
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- Int64 - 自增运算结果。
func saturatingMod(Int64)
public func saturatingMod(y: Int64): Int64
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: Int64 - 除数。
返回值:
- Int64 - 取余运算结果。
func saturatingMul(Int64)
public func saturatingMul(y: Int64): Int64
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int64 - 乘数。
返回值:
- Int64 - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): Int64
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- Int64 - 负号运算结果。
func saturatingPow(UInt64)
public func saturatingPow(y: UInt64): Int64
功能:使用饱和策略的幂运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt64 - 指数。
返回值:
- Int64 - 幂运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): Int64
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int64 - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): Int64
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int64 - 右移运算结果。
func saturatingSub(Int64)
public func saturatingSub(y: Int64): Int64
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int64 - 减数。
返回值:
- Int64 - 减法运算结果。
extend Int8 <: SaturatingOp<Int8>
extend Int8 <: SaturatingOp<Int8>
功能:为 Int8 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(Int8)
public func saturatingAdd(y: Int8): Int8
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int8 - 加数。
返回值:
- Int8 - 加法运算结果。
func saturatingDec()
public func saturatingDec(): Int8
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- Int8 - 自减运算结果。
func saturatingDiv(Int8)
public func saturatingDiv(y: Int8): Int8
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: Int8 - 除数。
返回值:
- Int8 - 除法运算结果。
func saturatingInc()
public func saturatingInc(): Int8
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- Int8 - 自增运算结果。
func saturatingMod(Int8)
public func saturatingMod(y: Int8): Int8
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: Int8 - 除数。
返回值:
- Int8 - 取余运算结果。
func saturatingMul(Int8)
public func saturatingMul(y: Int8): Int8
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int8 - 乘数。
返回值:
- Int8 - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): Int8
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- Int8 - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): Int8
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int8 - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): Int8
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int8 - 右移运算结果。
func saturatingSub(Int8)
public func saturatingSub(y: Int8): Int8
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: Int8 - 减数。
返回值:
- Int8 - 减法运算结果。
extend IntNative <: SaturatingOp<IntNative>
extend IntNative <: SaturatingOp<IntNative>
功能:为 IntNative 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(IntNative)
public func saturatingAdd(y: IntNative): IntNative
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: IntNative - 加数。
返回值:
- IntNative - 加法运算结果。
func saturatingDec()
public func saturatingDec(): IntNative
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- IntNative - 自减运算结果。
func saturatingDiv(IntNative)
public func saturatingDiv(y: IntNative): IntNative
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: IntNative - 除数。
返回值:
- IntNative - 除法运算结果。
func saturatingInc()
public func saturatingInc(): IntNative
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- IntNative - 自增运算结果。
func saturatingMod(IntNative)
public func saturatingMod(y: IntNative): IntNative
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: IntNative - 除数。
返回值:
- IntNative - 取余运算结果。
func saturatingMul(IntNative)
public func saturatingMul(y: IntNative): IntNative
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: IntNative - 乘数。
返回值:
- IntNative - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): IntNative
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- IntNative - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): IntNative
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- IntNative - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): IntNative
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- IntNative - 右移运算结果。
func saturatingSub(IntNative)
public func saturatingSub(y: IntNative): IntNative
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: IntNative - 减数。
返回值:
- IntNative - 减法运算结果。
extend UInt16 <: SaturatingOp<UInt16>
extend UInt16 <: SaturatingOp<UInt16>
功能:为 UInt16 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(UInt16)
public func saturatingAdd(y: UInt16): UInt16
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt16 - 加数。
返回值:
- UInt16 - 加法运算结果。
func saturatingDec()
public func saturatingDec(): UInt16
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UInt16 - 自减运算结果。
func saturatingDiv(UInt16)
public func saturatingDiv(y: UInt16): UInt16
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UInt16 - 除数。
返回值:
- UInt16 - 除法运算结果。
func saturatingInc()
public func saturatingInc(): UInt16
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- UInt16 - 自增运算结果。
func saturatingMod(UInt16)
public func saturatingMod(y: UInt16): UInt16
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UInt16 - 除数。
返回值:
- UInt16 - 取余运算结果。
func saturatingMul(UInt16)
public func saturatingMul(y: UInt16): UInt16
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt16 - 乘数。
返回值:
- UInt16 - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): UInt16
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UInt16 - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): UInt16
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt16 - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): UInt16
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt16 - 右移运算结果。
func saturatingSub(UInt16)
public func saturatingSub(y: UInt16): UInt16
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt16 - 减数。
返回值:
- UInt16 - 减法运算结果。
extend UInt32 <: SaturatingOp<UInt32>
extend UInt32 <: SaturatingOp<UInt32>
功能:为 UInt32 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(UInt32)
public func saturatingAdd(y: UInt32): UInt32
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt32 - 加数。
返回值:
- UInt32 - 加法运算结果。
func saturatingDec()
public func saturatingDec(): UInt32
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UInt32 - 自减运算结果。
func saturatingDiv(UInt32)
public func saturatingDiv(y: UInt32): UInt32
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UInt32 - 除数。
返回值:
- UInt32 - 除法运算结果。
func saturatingInc()
public func saturatingInc(): UInt32
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- UInt32 - 自增运算结果。
func saturatingMod(UInt32)
public func saturatingMod(y: UInt32): UInt32
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UInt32 - 除数。
返回值:
- UInt32 - 取余运算结果。
func saturatingMul(UInt32)
public func saturatingMul(y: UInt32): UInt32
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt32 - 乘数。
返回值:
- UInt32 - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): UInt32
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UInt32 - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): UInt32
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt32 - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): UInt32
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt32 - 右移运算结果。
func saturatingSub(UInt32)
public func saturatingSub(y: UInt32): UInt32
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt32 - 减数。
返回值:
- UInt32 - 减法运算结果。
extend UInt64 <: SaturatingOp<UInt64>
extend UInt64 <: SaturatingOp<UInt64>
功能:为 UInt64 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(UInt64)
public func saturatingAdd(y: UInt64): UInt64
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt64 - 加数。
返回值:
- UInt64 - 加法运算结果。
func saturatingDec()
public func saturatingDec(): UInt64
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UInt64 - 自减运算结果。
func saturatingDiv(UInt64)
public func saturatingDiv(y: UInt64): UInt64
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UInt64 - 除数。
返回值:
- UInt64 - 除法运算结果。
func saturatingInc()
public func saturatingInc(): UInt64
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- UInt64 - 自增运算结果。
func saturatingMod(UInt64)
public func saturatingMod(y: UInt64): UInt64
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UInt64 - 除数。
返回值:
- UInt64 - 取余运算结果。
func saturatingMul(UInt64)
public func saturatingMul(y: UInt64): UInt64
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt64 - 乘数。
返回值:
- UInt64 - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): UInt64
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UInt64 - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): UInt64
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt64 - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): UInt64
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt64 - 右移运算结果。
func saturatingSub(UInt64)
public func saturatingSub(y: UInt64): UInt64
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt64 - 减数。
返回值:
- UInt64 - 减法运算结果。
extend UInt8 <: SaturatingOp<UInt8>
extend UInt8 <: SaturatingOp<UInt8>
功能:为 UInt8 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(UInt8)
public func saturatingAdd(y: UInt8): UInt8
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt8 - 加数。
返回值:
- UInt8 - 加法运算结果。
func saturatingDec()
public func saturatingDec(): UInt8
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UInt8 - 自减运算结果。
func saturatingDiv(UInt8)
public func saturatingDiv(y: UInt8): UInt8
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UInt8 - 除数。
返回值:
- UInt8 - 除法运算结果。
func saturatingInc()
public func saturatingInc(): UInt8
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- UInt8 - 自增运算结果。
func saturatingMod(UInt8)
public func saturatingMod(y: UInt8): UInt8
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UInt8 - 除数。
返回值:
- UInt8 - 取余运算结果。
func saturatingMul(UInt8)
public func saturatingMul(y: UInt8): UInt8
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt8 - 乘数。
返回值:
- UInt8 - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): UInt8
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UInt8 - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): UInt8
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt8 - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): UInt8
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt8 - 右移运算结果。
func saturatingSub(UInt8)
public func saturatingSub(y: UInt8): UInt8
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt8 - 减数。
返回值:
- UInt8 - 减法运算结果。
extend UIntNative <: SaturatingOp<UIntNative>
extend UIntNative <: SaturatingOp<UIntNative>
功能:为 UIntNative 实现 SaturatingOp 接口。
父类型:
func saturatingAdd(UIntNative)
public func saturatingAdd(y: UIntNative): UIntNative
功能:使用饱和策略的加法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UIntNative - 加数。
返回值:
- UIntNative - 加法运算结果。
func saturatingDec()
public func saturatingDec(): UIntNative
功能:使用饱和策略的自减运算。
当运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UIntNative - 自减运算结果。
func saturatingDiv(UIntNative)
public func saturatingDiv(y: UIntNative): UIntNative
功能:使用饱和策略的除法运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- UIntNative - 除法运算结果。
func saturatingInc()
public func saturatingInc(): UIntNative
功能:使用饱和策略的自增运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
返回值:
- UIntNative - 自增运算结果。
func saturatingMod(UIntNative)
public func saturatingMod(y: UIntNative): UIntNative
功能:使用饱和策略的取余运算。
当运算出现上溢时,返回操作数类型的最大值,否则返回运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- UIntNative - 取余运算结果。
func saturatingMul(UIntNative)
public func saturatingMul(y: UIntNative): UIntNative
功能:使用饱和策略的乘法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UIntNative - 乘数。
返回值:
- UIntNative - 乘法运算结果。
func saturatingNeg()
public func saturatingNeg(): UIntNative
功能:使用饱和策略的负号运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
返回值:
- UIntNative - 负号运算结果。
func saturatingShl(UInt64)
public func saturatingShl(y: UInt64): UIntNative
功能:使用饱和策略的左移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UIntNative - 左移运算结果。
func saturatingShr(UInt64)
public func saturatingShr(y: UInt64): UIntNative
功能:使用饱和策略的右移运算。
当移位位数大于等于操作数位数时,将移位位数置为操作数位数 - 1,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UIntNative - 右移运算结果。
func saturatingSub(UIntNative)
public func saturatingSub(y: UIntNative): UIntNative
功能:使用饱和策略的减法运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UIntNative - 减数。
返回值:
- UIntNative - 减法运算结果。
interface SaturatingPow
public interface SaturatingPow {
public func saturatingPow(y: UInt64): Int64
}
功能:提供饱和策略的幂运算接口。
func saturatingPow(UInt64)
public func saturatingPow(y: UInt64): Int64
功能:使用饱和策略的幂运算。
当运算出现上溢时,返回操作数类型的最大值,运算出现下溢时,返回操作数类型的最小值,否则返回运算结果。
参数:
- y: UInt64 - 指数。
返回值:
- Int64 - 幂运算结果。
interface ThrowingOp<T>
public interface ThrowingOp<T> {
func throwingAdd(y: T): T
func throwingSub(y: T): T
func throwingMul(y: T): T
func throwingDiv(y: T): T
func throwingMod(y: T): T
func throwingInc(): T
func throwingDec(): T
func throwingNeg(): T
func throwingShl(y: UInt64): T
func throwingShr(y: UInt64): T
}
功能:当整数运算出现溢出,抛出异常。
func throwingAdd(T)
func throwingAdd(y: T): T
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: T - 加数。
返回值:
- T - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
func throwingDec(): T
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- T - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(T)
func throwingDiv(y: T): T
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: T - 除数。
返回值:
- T - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
func throwingInc(): T
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- T - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(T)
func throwingMod(y: T): T
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: T - 除数。
返回值:
- T - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(T)
func throwingMul(y: T): T
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: T - 乘数。
返回值:
- T - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
func throwingNeg(): T
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- T - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
func throwingShl(y: UInt64): T
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- T - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
func throwingShr(y: UInt64): T
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- T - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(T)
func throwingSub(y: T): T
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: T - 减数。
返回值:
- T - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend Int16 <: ThrowingOp<Int16>
extend Int16 <: ThrowingOp<Int16>
功能:为 Int16 实现 ThrowingOp 接口。
父类型:
func throwingAdd(Int16)
public func throwingAdd(y: Int16): Int16
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int16 - 加数。
返回值:
- Int16 - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): Int16
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int16 - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(Int16)
public func throwingDiv(y: Int16): Int16
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int16 - 除数。
返回值:
- Int16 - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): Int16
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int16 - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(Int16)
public func throwingMod(y: Int16): Int16
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int16 - 除数。
返回值:
- Int16 - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(Int16)
public func throwingMul(y: Int16): Int16
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int16 - 乘数。
返回值:
- Int16 - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): Int16
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int16 - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): Int16
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int16 - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): Int16
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int16 - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(Int16)
public func throwingSub(y: Int16): Int16
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int16 - 减数。
返回值:
- Int16 - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend Int32 <: ThrowingOp<Int32>
extend Int32 <: ThrowingOp<Int32>
功能:为 Int32 实现 ThrowingOp 接口。
父类型:
func throwingAdd(Int32)
public func throwingAdd(y: Int32): Int32
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int32 - 加数。
返回值:
- Int32 - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): Int32
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int32 - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(Int32)
public func throwingDiv(y: Int32): Int32
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int32 - 除数。
返回值:
- Int32 - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): Int32
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int32 - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(Int32)
public func throwingMod(y: Int32): Int32
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int32 - 除数。
返回值:
- Int32 - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(Int32)
public func throwingMul(y: Int32): Int32
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int32 - 乘数。
返回值:
- Int32 - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): Int32
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int32 - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): Int32
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int32 - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): Int32
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int32 - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(Int32)
public func throwingSub(y: Int32): Int32
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int32 - 减数。
返回值:
- Int32 - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend Int64 <: ThrowingOp<Int64> & ThrowingPow
extend Int64 <: ThrowingOp<Int64> & ThrowingPow
功能:为 Int64 实现 ThrowingOp 和 ThrowingPow 接口。
父类型:
func throwingAdd(Int64)
public func throwingAdd(y: Int64): Int64
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int64 - 加数。
返回值:
- Int64 - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): Int64
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int64 - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(Int64)
public func throwingDiv(y: Int64): Int64
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int64 - 除数。
返回值:
- Int64 - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): Int64
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int64 - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(Int64)
public func throwingMod(y: Int64): Int64
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int64 - 除数。
返回值:
- Int64 - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(Int64)
public func throwingMul(y: Int64): Int64
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int64 - 乘数。
返回值:
- Int64 - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): Int64
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int64 - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingPow(UInt64)
public func throwingPow(y: UInt64): Int64
功能:使用抛出异常策略的幂运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 指数。
返回值:
- Int64 - 幂运算结果。
异常:
- OverflowException - 当幂运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): Int64
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int64 - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): Int64
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int64 - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(Int64)
public func throwingSub(y: Int64): Int64
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int64 - 减数。
返回值:
- Int64 - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend Int8 <: ThrowingOp<Int8>
extend Int8 <: ThrowingOp<Int8>
功能:为 Int8 实现 ThrowingOp 接口。
父类型:
func throwingAdd(Int8)
public func throwingAdd(y: Int8): Int8
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int8 - 加数。
返回值:
- Int8 - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): Int8
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int8 - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(Int8)
public func throwingDiv(y: Int8): Int8
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int8 - 除数。
返回值:
- Int8 - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): Int8
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int8 - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(Int8)
public func throwingMod(y: Int8): Int8
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int8 - 除数。
返回值:
- Int8 - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(Int8)
public func throwingMul(y: Int8): Int8
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int8 - 乘数。
返回值:
- Int8 - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): Int8
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- Int8 - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): Int8
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int8 - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): Int8
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int8 - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(Int8)
public func throwingSub(y: Int8): Int8
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: Int8 - 减数。
返回值:
- Int8 - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend IntNative <: ThrowingOp<IntNative>
extend IntNative <: ThrowingOp<IntNative>
功能:为 IntNative 实现 ThrowingOp 接口。
父类型:
func throwingAdd(IntNative)
public func throwingAdd(y: IntNative): IntNative
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: IntNative - 加数。
返回值:
- IntNative - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): IntNative
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- IntNative - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(IntNative)
public func throwingDiv(y: IntNative): IntNative
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: IntNative - 除数。
返回值:
- IntNative - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): IntNative
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- IntNative - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(IntNative)
public func throwingMod(y: IntNative): IntNative
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: IntNative - 除数。
返回值:
- IntNative - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(IntNative)
public func throwingMul(y: IntNative): IntNative
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: IntNative - 乘数。
返回值:
- IntNative - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): IntNative
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- IntNative - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): IntNative
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- IntNative - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): IntNative
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- IntNative - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(IntNative)
public func throwingSub(y: IntNative): IntNative
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: IntNative - 减数。
返回值:
- IntNative - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend UInt16 <: ThrowingOp<UInt16>
extend UInt16 <: ThrowingOp<UInt16>
功能:为 UInt16 实现 ThrowingOp 接口。
父类型:
func throwingAdd(UInt16)
public func throwingAdd(y: UInt16): UInt16
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt16 - 加数。
返回值:
- UInt16 - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): UInt16
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt16 - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(UInt16)
public func throwingDiv(y: UInt16): UInt16
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt16 - 除数。
返回值:
- UInt16 - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): UInt16
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt16 - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(UInt16)
public func throwingMod(y: UInt16): UInt16
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt16 - 除数。
返回值:
- UInt16 - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(UInt16)
public func throwingMul(y: UInt16): UInt16
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt16 - 乘数。
返回值:
- UInt16 - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): UInt16
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt16 - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): UInt16
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt16 - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): UInt16
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt16 - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(UInt16)
public func throwingSub(y: UInt16): UInt16
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt16 - 减数。
返回值:
- UInt16 - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend UInt32 <: ThrowingOp<UInt32>
extend UInt32 <: ThrowingOp<UInt32>
功能:为 UInt32 实现 ThrowingOp 接口。
父类型:
func throwingAdd(UInt32)
public func throwingAdd(y: UInt32): UInt32
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt32 - 加数。
返回值:
- UInt32 - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): UInt32
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt32 - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(UInt32)
public func throwingDiv(y: UInt32): UInt32
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt32 - 除数。
返回值:
- UInt32 - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): UInt32
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt32 - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(UInt32)
public func throwingMod(y: UInt32): UInt32
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt32 - 除数。
返回值:
- UInt32 - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(UInt32)
public func throwingMul(y: UInt32): UInt32
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt32 - 乘数。
返回值:
- UInt32 - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): UInt32
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt32 - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): UInt32
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt32 - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): UInt32
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt32 - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(UInt32)
public func throwingSub(y: UInt32): UInt32
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt32 - 减数。
返回值:
- UInt32 - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend UInt64 <: ThrowingOp<UInt64>
extend UInt64 <: ThrowingOp<UInt64>
功能:为 UInt64 实现 ThrowingOp 接口。
父类型:
func throwingAdd(UInt64)
public func throwingAdd(y: UInt64): UInt64
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 加数。
返回值:
- UInt64 - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): UInt64
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt64 - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(UInt64)
public func throwingDiv(y: UInt64): UInt64
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 除数。
返回值:
- UInt64 - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): UInt64
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt64 - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(UInt64)
public func throwingMod(y: UInt64): UInt64
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 除数。
返回值:
- UInt64 - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(UInt64)
public func throwingMul(y: UInt64): UInt64
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 乘数。
返回值:
- UInt64 - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): UInt64
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt64 - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): UInt64
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt64 - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): UInt64
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt64 - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(UInt64)
public func throwingSub(y: UInt64): UInt64
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 减数。
返回值:
- UInt64 - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend UInt8 <: ThrowingOp<UInt8>
extend UInt8 <: ThrowingOp<UInt8>
功能:为 UInt8 实现 ThrowingOp 接口。
父类型:
func throwingAdd(UInt8)
public func throwingAdd(y: UInt8): UInt8
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt8 - 加数。
返回值:
- UInt8 - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): UInt8
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt8 - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(UInt8)
public func throwingDiv(y: UInt8): UInt8
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt8 - 除数。
返回值:
- UInt8 - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): UInt8
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt8 - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(UInt8)
public func throwingMod(y: UInt8): UInt8
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt8 - 除数。
返回值:
- UInt8 - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(UInt8)
public func throwingMul(y: UInt8): UInt8
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt8 - 乘数。
返回值:
- UInt8 - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): UInt8
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UInt8 - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): UInt8
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt8 - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): UInt8
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt8 - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(UInt8)
public func throwingSub(y: UInt8): UInt8
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt8 - 减数。
返回值:
- UInt8 - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
extend UIntNative <: ThrowingOp<UIntNative>
extend UIntNative <: ThrowingOp<UIntNative>
功能:为 UIntNative 实现 ThrowingOp 接口。
父类型:
func throwingAdd(UIntNative)
public func throwingAdd(y: UIntNative): UIntNative
功能:使用抛出异常策略的加法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UIntNative - 加数。
返回值:
- UIntNative - 加法运算结果。
异常:
- OverflowException - 当加法运算出现溢出时,抛出异常。
func throwingDec()
public func throwingDec(): UIntNative
功能:使用抛出异常策略的自减运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UIntNative - 自减运算结果。
异常:
- OverflowException - 当自减运算出现溢出时,抛出异常。
func throwingDiv(UIntNative)
public func throwingDiv(y: UIntNative): UIntNative
功能:使用抛出异常策略的除法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- UIntNative - 除法运算结果。
异常:
- OverflowException - 当除法运算出现溢出时,抛出异常。
func throwingInc()
public func throwingInc(): UIntNative
功能:使用抛出异常策略的自增运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UIntNative - 自增运算结果。
异常:
- OverflowException - 当自增运算出现溢出时,抛出异常。
func throwingMod(UIntNative)
public func throwingMod(y: UIntNative): UIntNative
功能:使用抛出异常策略的取余运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- UIntNative - 取余运算结果。
异常:
- OverflowException - 当取余运算出现溢出时,抛出异常。
func throwingMul(UIntNative)
public func throwingMul(y: UIntNative): UIntNative
功能:使用抛出异常策略的乘法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UIntNative - 乘数。
返回值:
- UIntNative - 乘法运算结果。
异常:
- OverflowException - 当乘法运算出现溢出时,抛出异常。
func throwingNeg()
public func throwingNeg(): UIntNative
功能:使用抛出异常策略的负号运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
返回值:
- UIntNative - 负号运算结果。
异常:
- OverflowException - 当负号运算出现溢出时,抛出异常。
func throwingShl(UInt64)
public func throwingShl(y: UInt64): UIntNative
功能:使用抛出异常策略的左移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UIntNative - 左移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingShr(UInt64)
public func throwingShr(y: UInt64): UIntNative
功能:右移运算。
当移位位数大于等于操作数位数时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 移位位数。
返回值:
- UIntNative - 右移运算结果。
异常:
- OvershiftException - 当移位位数大于等于操作数位数时,抛出异常。
func throwingSub(UIntNative)
public func throwingSub(y: UIntNative): UIntNative
功能:使用抛出异常策略的减法运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UIntNative - 减数。
返回值:
- UIntNative - 减法运算结果。
异常:
- OverflowException - 当减法运算出现溢出时,抛出异常。
interface ThrowingPow
public interface ThrowingPow {
public func throwingPow(y: UInt64): Int64
}
功能:提供使用抛出异常策略的幂运算接口。
func throwingPow(UInt64)
public func throwingPow(y: UInt64): Int64
功能:使用抛出异常策略的幂运算。
当运算出现溢出时,抛出异常,否则返回运算结果。
参数:
- y: UInt64 - 指数。
返回值:
- Int64 - 幂运算结果。
异常:
- OverflowException - 当幂运算出现溢出时,抛出异常。
interface WrappingOp<T>
public interface WrappingOp<T> {
func wrappingAdd(y: T): T
func wrappingDec(): T
func wrappingDiv(y: T): T
func wrappingInc(): T
func wrappingMod(y: T): T
func wrappingMul(y: T): T
func wrappingNeg(): T
func wrappingShl(y: UInt64): T
func wrappingShr(y: UInt64): T
func wrappingSub(y: T): T
}
功能:当整数运算出现溢出,高位截断。
func wrappingAdd(T)
func wrappingAdd(y: T): T
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: T - 加数。
返回值:
- T - 加法运算结果。
func wrappingDec()
func wrappingDec(): T
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- T - 自减运算结果。
func wrappingDiv(T)
func wrappingDiv(y: T): T
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: T - 除数。
返回值:
- T - 除法运算结果。
func wrappingInc()
func wrappingInc(): T
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- T - 自增运算结果。
func wrappingMod(T)
func wrappingMod(y: T): T
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: T - 除数。
返回值:
- T - 取余运算结果。
func wrappingMul(T)
func wrappingMul(y: T): T
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: T - 乘数。
返回值:
- T - 乘法运算结果。
func wrappingNeg()
func wrappingNeg(): T
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- T - 负号运算结果。
func wrappingShl(UInt64)
func wrappingShl(y: UInt64): T
功能:使用高位截断策略的左移运算。
当移位位数大于等于操作数位数时,高位截断。例如,对 Int8 类型的数进行移位,当 y (移位位数)超大于等于 8时,仅取 y 的低 3 位作为移位位数,以此保证移位位数在 0 到 7 之间。
参数:
- y: UInt64 - 移位位数。
返回值:
- T - 左移运算结果。
func wrappingShr(UInt64)
func wrappingShr(y: UInt64): T
功能:使用高位截断策略的右移运算。
当移位位数大于等于操作数位数时,高位截断。例如,对 Int8 类型的数进行移位,当 y (移位位数)超大于等于 8时,仅取 y 的低 3 位作为移位位数,以此保证移位位数在 0 到 7 之间。
参数:
- y: UInt64 - 移位位数。
返回值:
- T - 右移运算结果。
func wrappingSub(T)
func wrappingSub(y: T): T
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: T - 减数。
返回值:
- T - 减法运算结果。
extend Int16 <: WrappingOp<Int16>
extend Int16 <: WrappingOp<Int16>
功能:为 Int16 实现 WrappingOp 接口。
父类型:
func wrappingAdd(Int16)
public func wrappingAdd(y: Int16): Int16
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int16 - 加数。
返回值:
- Int16 - 加法运算结果。
func wrappingDec()
public func wrappingDec(): Int16
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int16 - 自减运算结果。
func wrappingDiv(Int16)
public func wrappingDiv(y: Int16): Int16
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int16 - 除数。
返回值:
- Int16 - 除法运算结果。
func wrappingInc()
public func wrappingInc(): Int16
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int16 - 自增运算结果。
func wrappingMod(Int16)
public func wrappingMod(y: Int16): Int16
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int16 - 除数。
返回值:
- Int16 - 取余运算结果。
func wrappingMul(Int16)
public func wrappingMul(y: Int16): Int16
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int16 - 乘数。
返回值:
- Int16 - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): Int16
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int16 - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): Int16
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 4 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int16 - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): Int16
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 4 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int16 - 右移运算结果。
func wrappingSub(Int16)
public func wrappingSub(y: Int16): Int16
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int16 - 减数。
返回值:
- Int16 - 减法运算结果。
extend Int32 <: WrappingOp<Int32>
extend Int32 <: WrappingOp<Int32>
功能:为 Int32 实现 WrappingOp 接口。
父类型:
func wrappingAdd(Int32)
public func wrappingAdd(y: Int32): Int32
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int32 - 加数。
返回值:
- Int32 - 加法运算结果。
func wrappingDec()
public func wrappingDec(): Int32
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int32 - 自减运算结果。
func wrappingDiv(Int32)
public func wrappingDiv(y: Int32): Int32
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int32 - 除数。
返回值:
- Int32 - 除法运算结果。
func wrappingInc()
public func wrappingInc(): Int32
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int32 - 自增运算结果。
func wrappingMod(Int32)
public func wrappingMod(y: Int32): Int32
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int32 - 除数。
返回值:
- Int32 - 取余运算结果。
func wrappingMul(Int32)
public func wrappingMul(y: Int32): Int32
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int32 - 乘数。
返回值:
- Int32 - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): Int32
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int32 - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): Int32
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 5 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int32 - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): Int32
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 5 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int32 - 右移运算结果。
func wrappingSub(Int32)
public func wrappingSub(y: Int32): Int32
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int32 - 减数。
返回值:
- Int32 - 减法运算结果。
extend Int64 <: WrappingOp<Int64> & WrappingPow
extend Int64 <: WrappingOp<Int64> & WrappingPow
功能:为 Int64 实现 WrappingOp 和 WrappingPow 接口。
父类型:
func wrappingAdd(Int64)
public func wrappingAdd(y: Int64): Int64
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int64 - 加数。
返回值:
- Int64 - 加法运算结果。
func wrappingDec()
public func wrappingDec(): Int64
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int64 - 自减运算结果。
func wrappingDiv(Int64)
public func wrappingDiv(y: Int64): Int64
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int64 - 除数。
返回值:
- Int64 - 除法运算结果。
func wrappingInc()
public func wrappingInc(): Int64
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int64 - 自增运算结果。
func wrappingMod(Int64)
public func wrappingMod(y: Int64): Int64
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int64 - 除数。
返回值:
- Int64 - 取余运算结果。
func wrappingMul(Int64)
public func wrappingMul(y: Int64): Int64
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int64 - 乘数。
返回值:
- Int64 - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): Int64
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int64 - 负号运算结果。
func wrappingPow(UInt64)
public func wrappingPow(y: UInt64): Int64
功能:使用高位截断策略的幂运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt64 - 指数。
返回值:
- Int64 - 幂运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): Int64
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 6 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int64 - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): Int64
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 6 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int64 - 右移运算结果。
func wrappingSub(Int64)
public func wrappingSub(y: Int64): Int64
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int64 - 减数。
返回值:
- Int64 - 减法运算结果。
extend Int8 <: WrappingOp<Int8>
extend Int8 <: WrappingOp<Int8>
功能:为 Int8 实现 WrappingOp 接口。
父类型:
func wrappingAdd(Int8)
public func wrappingAdd(y: Int8): Int8
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int8 - 加数。
返回值:
- Int8 - 加法运算结果。
func wrappingDec()
public func wrappingDec(): Int8
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int8 - 自减运算结果。
func wrappingDiv(Int8)
public func wrappingDiv(y: Int8): Int8
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int8 - 除数。
返回值:
- Int8 - 除法运算结果。
func wrappingInc()
public func wrappingInc(): Int8
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int8 - 自增运算结果。
func wrappingMod(Int8)
public func wrappingMod(y: Int8): Int8
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int8 - 除数。
返回值:
- Int8 - 取余运算结果。
func wrappingMul(Int8)
public func wrappingMul(y: Int8): Int8
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int8 - 乘数。
返回值:
- Int8 - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): Int8
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- Int8 - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): Int8
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 3 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int8 - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): Int8
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 3 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- Int8 - 右移运算结果。
func wrappingSub(Int8)
public func wrappingSub(y: Int8): Int8
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: Int8 - 减数。
返回值:
- Int8 - 减法运算结果。
extend IntNative <: WrappingOp<IntNative>
extend IntNative <: WrappingOp<IntNative>
功能:为 IntNative 实现 WrappingOp 接口。
父类型:
func wrappingAdd(IntNative)
public func wrappingAdd(y: IntNative): IntNative
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: IntNative - 加数。
返回值:
- IntNative - 加法运算结果。
func wrappingDec()
public func wrappingDec(): IntNative
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- IntNative - 自减运算结果。
func wrappingDiv(IntNative)
public func wrappingDiv(y: IntNative): IntNative
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: IntNative - 除数。
返回值:
- IntNative - 除法运算结果。
func wrappingInc()
public func wrappingInc(): IntNative
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- IntNative - 自增运算结果。
func wrappingMod(IntNative)
public func wrappingMod(y: IntNative): IntNative
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: IntNative - 除数。
返回值:
- IntNative - 取余运算结果。
func wrappingMul(IntNative)
public func wrappingMul(y: IntNative): IntNative
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: IntNative - 乘数。
返回值:
- IntNative - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): IntNative
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- IntNative - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): IntNative
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低位作为移位位数,具体取的位数取决于当前系统下 IntNative 的位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- IntNative - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): IntNative
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低位作为移位位数,具体取的位数取决于当前系统下 IntNative 的位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- IntNative - 右移运算结果。
func wrappingSub(IntNative)
public func wrappingSub(y: IntNative): IntNative
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: IntNative - 减数。
返回值:
- IntNative - 减法运算结果。
extend UInt16 <: WrappingOp<UInt16>
extend UInt16 <: WrappingOp<UInt16>
功能:为 UInt16 实现 WrappingOp 接口。
父类型:
func wrappingAdd(UInt16)
public func wrappingAdd(y: UInt16): UInt16
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt16 - 加数。
返回值:
- UInt16 - 加法运算结果。
func wrappingDec()
public func wrappingDec(): UInt16
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt16 - 自减运算结果。
func wrappingDiv(UInt16)
public func wrappingDiv(y: UInt16): UInt16
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt16 - 除数。
返回值:
- UInt16 - 除法运算结果。
func wrappingInc()
public func wrappingInc(): UInt16
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt16 - 自增运算结果。
func wrappingMod(UInt16)
public func wrappingMod(y: UInt16): UInt16
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt16 - 除数。
返回值:
- UInt16 - 取余运算结果。
func wrappingMul(UInt16)
public func wrappingMul(y: UInt16): UInt16
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt16 - 乘数。
返回值:
- UInt16 - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): UInt16
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt16 - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): UInt16
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 4 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt16 - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): UInt16
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 4 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt16 - 右移运算结果。
func wrappingSub(UInt16)
public func wrappingSub(y: UInt16): UInt16
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt16 - 减数。
返回值:
- UInt16 - 减法运算结果。
extend UInt32 <: WrappingOp<UInt32>
extend UInt32 <: WrappingOp<UInt32>
功能:为 UInt32 实现 WrappingOp 接口。
父类型:
func wrappingAdd(UInt32)
public func wrappingAdd(y: UInt32): UInt32
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt32 - 加数。
返回值:
- UInt32 - 加法运算结果。
func wrappingDec()
public func wrappingDec(): UInt32
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt32 - 自减运算结果。
func wrappingDiv(UInt32)
public func wrappingDiv(y: UInt32): UInt32
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt32 - 除数。
返回值:
- UInt32 - 除法运算结果。
func wrappingInc()
public func wrappingInc(): UInt32
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt32 - 自增运算结果。
func wrappingMod(UInt32)
public func wrappingMod(y: UInt32): UInt32
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt32 - 除数。
返回值:
- UInt32 - 取余运算结果。
func wrappingMul(UInt32)
public func wrappingMul(y: UInt32): UInt32
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt32 - 乘数。
返回值:
- UInt32 - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): UInt32
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt32 - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): UInt32
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 5 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt32 - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): UInt32
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 5 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt32 - 右移运算结果。
func wrappingSub(UInt32)
public func wrappingSub(y: UInt32): UInt32
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt32 - 减数。
返回值:
- UInt32 - 减法运算结果。
extend UInt64 <: WrappingOp<UInt64>
extend UInt64 <: WrappingOp<UInt64>
功能:为 UInt64 实现 WrappingOp 接口。
父类型:
func wrappingAdd(UInt64)
public func wrappingAdd(y: UInt64): UInt64
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt64 - 加数。
返回值:
- UInt64 - 加法运算结果。
func wrappingDec()
public func wrappingDec(): UInt64
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt64 - 自减运算结果。
func wrappingDiv(UInt64)
public func wrappingDiv(y: UInt64): UInt64
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt64 - 除数。
返回值:
- UInt64 - 除法运算结果。
func wrappingInc()
public func wrappingInc(): UInt64
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt64 - 自增运算结果。
func wrappingMod(UInt64)
public func wrappingMod(y: UInt64): UInt64
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt64 - 除数。
返回值:
- UInt64 - 取余运算结果。
func wrappingMul(UInt64)
public func wrappingMul(y: UInt64): UInt64
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt64 - 乘数。
返回值:
- UInt64 - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): UInt64
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt64 - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): UInt64
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 6 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt64 - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): UInt64
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 6 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt64 - 右移运算结果。
func wrappingSub(UInt64)
public func wrappingSub(y: UInt64): UInt64
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt64 - 减数。
返回值:
- UInt64 - 减法运算结果。
extend UInt8 <: WrappingOp<UInt8>
extend UInt8 <: WrappingOp<UInt8>
功能:为 UInt8 实现 WrappingOp 接口。
父类型:
func wrappingAdd(UInt8)
public func wrappingAdd(y: UInt8): UInt8
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt8 - 加数。
返回值:
- UInt8 - 加法运算结果。
func wrappingDec()
public func wrappingDec(): UInt8
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt8 - 自减运算结果。
func wrappingDiv(UInt8)
public func wrappingDiv(y: UInt8): UInt8
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt8 - 除数。
返回值:
- UInt8 - 除法运算结果。
func wrappingInc()
public func wrappingInc(): UInt8
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt8 - 自增运算结果。
func wrappingMod(UInt8)
public func wrappingMod(y: UInt8): UInt8
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt8 - 除数。
返回值:
- UInt8 - 取余运算结果。
func wrappingMul(UInt8)
public func wrappingMul(y: UInt8): UInt8
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt8 - 乘数。
返回值:
- UInt8 - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): UInt8
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UInt8 - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): UInt8
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 3 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt8 - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): UInt8
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低 3 位作为移位位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UInt8 - 右移运算结果。
func wrappingSub(UInt8)
public func wrappingSub(y: UInt8): UInt8
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt8 - 减数。
返回值:
- UInt8 - 减法运算结果。
extend UIntNative <: WrappingOp<UIntNative>
extend UIntNative <: WrappingOp<UIntNative>
功能:为 UIntNative 实现 WrappingOp 接口。
父类型:
func wrappingAdd(UIntNative)
public func wrappingAdd(y: UIntNative): UIntNative
功能:使用高位截断策略的加法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UIntNative - 加数。
返回值:
- UIntNative - 加法运算结果。
func wrappingDec()
public func wrappingDec(): UIntNative
功能:使用高位截断策略的自减运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UIntNative - 自减运算结果。
func wrappingDiv(UIntNative)
public func wrappingDiv(y: UIntNative): UIntNative
功能:使用高位截断策略的除法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- UIntNative - 除法运算结果。
func wrappingInc()
public func wrappingInc(): UIntNative
功能:使用高位截断策略的自增运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UIntNative - 自增运算结果。
func wrappingMod(UIntNative)
public func wrappingMod(y: UIntNative): UIntNative
功能:使用高位截断策略的取余运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UIntNative - 除数。
返回值:
- UIntNative - 取余运算结果。
func wrappingMul(UIntNative)
public func wrappingMul(y: UIntNative): UIntNative
功能:使用高位截断策略的乘法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UIntNative - 乘数。
返回值:
- UIntNative - 乘法运算结果。
func wrappingNeg()
public func wrappingNeg(): UIntNative
功能:使用高位截断策略的负号运算。
当运算出现溢出时,高位截断,否则返回运算结果。
返回值:
- UIntNative - 负号运算结果。
func wrappingShl(UInt64)
public func wrappingShl(y: UInt64): UIntNative
功能:使用高位截断策略的左移运算。
当右操作数大于等于左操作数位数时,取右操作数的低位作为移位位数,具体取的位数取决于当前系统下 UIntNative 的位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UIntNative - 左移运算结果。
func wrappingShr(UInt64)
public func wrappingShr(y: UInt64): UIntNative
功能:使用高位截断策略的右移运算。
当右操作数大于等于左操作数位数时,取右操作数的低位作为移位位数,具体取的位数取决于当前系统下 UIntNative 的位数。
参数:
- y: UInt64 - 移位位数。
返回值:
- UIntNative - 右移运算结果。
func wrappingSub(UIntNative)
public func wrappingSub(y: UIntNative): UIntNative
功能:使用高位截断策略的减法运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UIntNative - 减数。
返回值:
- UIntNative - 减法运算结果。
interface WrappingPow
public interface WrappingPow {
public func wrappingPow(y: UInt64): Int64
}
功能:提供使用高位截断策略的幂运算接口。
func wrappingPow(UInt64)
public func wrappingPow(y: UInt64): Int64
功能:使用高位截断策略的幂运算。
当运算出现溢出时,高位截断,否则返回运算结果。
参数:
- y: UInt64 - 指数。
返回值:
- Int64 - 幂运算结果。
异常类
class OvershiftException
public class OvershiftException <: Exception {
public init()
public init(message: String)
}
功能:移位运算中,当移位位数超过操作数位数时抛出的异常。
父类型:
init()
public init()
功能:创建 OvershiftException 实例。
init(String)
public init(message: String)
功能:创建带有异常信息 message 的 OvershiftException 实例。
参数:
- message: String - 异常信息。
class UndershiftException
public class UndershiftException <: Exception {
public init()
public init(message: String)
}
功能:移位运算中,当移位位数小于 0 时抛出的异常。
父类型:
init()
public init()
功能:创建 UndershiftException 实例。
init(String)
public init(message: String)
功能:创建带有异常信息 message 的 UndershiftException 实例。
参数:
- message: String - 异常信息。
返回 Option 策略的示例
下面是返回 Option 策略的示例,示例中尝试运算 Int64.Max 的平方,发生溢出,返回 None。
import std.overflow.*
import std.math.*
main() {
let a: Int64 = Int64.Max
println(a.checkedPow(UInt64(2)))
}
运行结果:
None
饱和策略的示例
下面是饱和策略的示例,示例中尝试运算 UInt16.Max 乘 16,运算结果超过 UInt16 的最大值,发生上溢,故返回 UInt16 的最大值。
import std.overflow.*
import std.math.*
main() {
let a: UInt16 = UInt16.Max
println(a.saturatingMul(16))
}
运行结果:
65535
抛出异常策略的示例
下面是抛出异常策略的示例,示例中尝试运算 Int64.Max + 1,发生溢出,抛出 OverflowException。
import std.overflow.*
import std.math.*
main() {
let a: Int64 = Int64.Max
println(a.throwingAdd(1))
}
运行结果:
An exception has occurred:
OverflowException: add
高位截断策略的示例
下面是高位截断策略的示例,示例中尝试运算 UInt8.Max + 1,UInt8.Max 二进制表示为 0b11111111,UInt8.Max + 1 为 0b100000000,由于 UInt8 只能储存 8 位,高位截断后结果为 0。
import std.overflow.*
import std.math.*
main() {
let a: UInt8 = UInt8.Max
println(a.wrappingAdd(1))
}
运行结果:
0
std.posix
功能介绍
posix 包封装 POSIX 系统调用,提供跨平台的系统操作接口。
本包提供多平台统一操控能力,目前支持 Linux 平台,macOS 平台与Windows 平台。
注意:
未来版本即将废弃本包全部内容。
API 列表
函数
| 函数名 | 功能 | 支持平台 |
|---|---|---|
| open(String, Int32) (deprecated) | 打开文件并为其返回新的文件描述符,或在失败时返回 -1。 | Linux Windows macOS |
| open(String, Int32, UInt32) (deprecated) | 打开文件并为其返回新的文件描述符,或在失败时返回 -1。 | Linux Windows macOS |
| access(String, Int32) (deprecated) | 判断某个文件是否具有某种权限,具有返回 0,否则返回 -1。 | Linux Windows macOS |
| chdir(String) (deprecated) | 通过指定路径的方式,更改调用进程的当前工作目录。 | Linux Windows macOS |
| chmod(String, UInt32) (deprecated) | 修改文件访问权限。 | Linux Windows macOS |
| chown(String, UInt32, UInt32) (deprecated) | 修改文件所有者和文件所有者所属组。 | Linux macOS |
| close(Int32) (deprecated) | 关闭文件,close 将会触发数据写回磁盘,并释放文件占用的资源。 | Linux Windows macOS |
| creat(String, UInt32) (deprecated) | 创建文件并为其返回文件描述符,或在失败时返回 -1。 | Linux Windows macOS |
| dup(Int32) (deprecated) | 用于复制旧 fd 参数指定的文件描述符并返回。 | Linux Windows macOS |
| dup2(Int32, Int32) (deprecated) | 用于复制 oldfd 参数指定的文件描述符,并将其返回到 newfd 参数。 | Linux Windows macOS |
| faccessat(Int32, String, Int32, Int32) (deprecated) | 判断 fd 对应的文件是否具有某种权限,具有返回 0,否则返回 -1。 | Linux macOS |
| fchdir(Int32) (deprecated) | 通过指定文件路径的描述符,更改调用进程的当前工作目录。 | Linux macOS |
| fchmod(Int32, UInt32) (deprecated) | 修改文件描述符对应的文件访问权限。 | Linux Windows macOS |
| fchmodat(Int32, String, UInt32, Int32) (deprecated) | 修改文件描述符对应的文件访问权限。 | Linux Windows macOS |
| fchown(Int32, UInt32, UInt32) (deprecated) | 修改 fd 对应的文件所有者和文件所有者所属组。 | Linux macOS |
| fchownat(Int32, String, UInt32, UInt32, Int32) (deprecated) | 修改文件描述符对应的文件所有者和文件所有者所属组。 | Linux macOS |
| getcwd() (deprecated) | 获取当前执行进程工作目录的绝对路径。 | Linux Windows macOS |
| getgid() (deprecated) | 获取用户组 ID。 | Linux macOS |
| getgroups(Int32, CPointer<UInt32>) (deprecated) | 获取当前用户所属组的代码。 | Linux macOS |
| gethostname() (deprecated) | 获取主机名称,此名称通常是 TCP/IP 网络上主机的名称。 | Linux macOS |
| getlogin() (deprecated) | 获取当前登录名。 | Linux macOS |
| getos() (deprecated) | 从 /proc/version 文件中获取 Linux 系统的信息。 | Linux |
| getpgid(Int32) (deprecated) | 获取 pid 指定的进程的 PGID,如果 pid 为零,返回调用进程的进程 ID。 | Linux macOS |
| getpgrp() (deprecated) | 获取调用进程的父进程 ID。 | Linux macOS |
| getpid() (deprecated) | 获取调用进程的进程 ID(PID)。 | Linux Windows macOS |
| getppid() (deprecated) | 获取调用进程的父进程 ID。 | Linux macOS |
| getuid() (deprecated) | 获取调用进程的真实用户 ID。 | Linux macOS |
| isBlk(String) (deprecated) | 检查传入对象是否为块设备,并返回布尔类型。 | Linux Windows macOS |
| isChr(String) (deprecated) | 检查传入对象是否为字符设备,返回布尔类型。 | Linux Windows macOS |
| isDir(String) (deprecated) | 检查传入对象是否为文件夹,返回布尔类型。 | Linux Windows macOS |
| isFIFO(String) (deprecated) | 检查传入对象是否为 FIFO 文件,返回布尔类型。 | Linux macOS |
| isLnk(String) (deprecated) | 检查传入对象是否为软链路,返回布尔类型。 | Linux macOS |
| isReg(String) (deprecated) | 检查传入对象是否为普通文件,返回布尔类型。 | Linux Windows macOS |
| isSock(String) (deprecated) | 检查传入对象是否为套接字文件,返回布尔类型。 | Linux macOS |
| isType(String, UInt32) (deprecated) | 检查文件是否为指定模式的文件。 | Linux macOS |
| isatty(Int32) (deprecated) | 用于测试文件描述符是否引用终端,成功时返回 true,否则返回 false。 | Linux Windows macOS |
| kill(Int32, Int32) (deprecated) | 系统调用可用于向任何进程组或进程发送任何信号。 | Linux macOS |
| killpg(Int32, Int32) (deprecated) | 将信号 sig 发送到进程组 pgrp,如果 pgrp 为 0,则 killpg() 将信号发送到调用进程的进程组。 | Linux macOS |
| lchown(String, UInt32, UInt32) (deprecated) | 修改文件链接本身所有者和所有者所属组。 | Linux macOS |
| link(String, String) (deprecated) | 为存在的文件创建链接,一个文件可以有多个指向其 i-node 的目录条目。 | Linux macOS |
| linkat(Int32, String, Int32, String, Int32) (deprecated) | 创建相对于目录文件描述符的文件链接。 | Linux macOS |
| lseek(Int32, Int64, Int32) (deprecated) | 当文件进行读或写时,读或写位置相应增加。 | Linux Windows macOS |
| nice(Int32) (deprecated) | 更改当前线程的优先级。 | Linux macOS |
| open64(String, Int32) (deprecated) | 打开文件并为其返回新的文件描述符,或在失败时返回 -1。 | Linux |
| open64(String, Int32, UInt32) (deprecated) | 打开文件并为其返回新的文件描述符,或在失败时返回 -1。 | Linux |
| openat(Int32, String, Int32) (deprecated) | 打开文件并为其返回新的文件描述符,或在失败时返回 -1。 | Linux macOS |
| openat(Int32, String, Int32, UInt32) (deprecated) | 打开文件并为其返回新的文件描述符,或在失败时返回 -1。 | Linux macOS |
| openat64(Int32, String, Int32) (deprecated) | 打开文件并为其返回新的文件描述符,或在失败时返回 -1。 | Linux macOS |
| openat64(Int32, String, Int32, UInt32) (deprecated) | 打开文件并为其返回新的文件描述符,或在失败时返回 -1。 | Linux macOS |
| pread(Int32, CPointer<UInt8>, UIntNative, Int32) (deprecated) | 将 fd 指向的文件的 nbyte 字节传输到 buffer 指向的内存中。 | Linux macOS |
| pwrite(Int32, CPointer<UInt8>, UIntNative, Int32) (deprecated) | 将 buffer 指向的内存中 nbyte 字节从指定偏移位置开始写入到 fd 指向的文件。 | Linux macOS |
| read(Int32, CPointer<UInt8>, UIntNative) (deprecated) | 将 fd 指向的文件的 nbyte 字节传输到 buffer 指向的内存中。 | Linux Windows macOS |
| remove(String) (deprecated) | 删除文件或目录。 | Linux Windows macOS |
| rename(String, String) (deprecated) | 重命名文件,如果需要将会移动文件所在目录。 | Linux Windows macOS |
| renameat(Int32, String, Int32, String) (deprecated) | 重命名文件,如果需要将会移动文件所在目录。 | Linux macOS |
| setgid(UInt32) (deprecated) | 设置调用进程的有效组 ID,需要适当的权限。 | Linux macOS |
| sethostname(String) (deprecated) | 设置主机名,仅超级用户可以调用。 | Linux macOS |
| setpgid(Int32, Int32) (deprecated) | 此函数将参数 pid 指定的组 ID 设置为参数 pgrp 指定的组 ID。 | Linux macOS |
| setpgrp() (deprecated) | 将当前进程所属的组 ID 设置为当前进程的进程 ID,此函数等同于调用 setpgid(0, 0)。 | Linux macOS |
| setuid(UInt32) (deprecated) | 设置调用进程的有效用户 ID,需要适当的权限。 | Linux macOS |
| symlink(String, String) (deprecated) | 创建一个名为 symPath 链接到 path 所指定的文件。 | Linux macOS |
| symlinkat(String, Int32, String) (deprecated) | 创建一个名为 symPath 链接到 path 与 fd 所指定的文件。 | Linux macOS |
| ttyname(Int32) (deprecated) | 返回终端名称。 | Linux Windows macOS |
| umask(UInt32) (deprecated) | 设置权限掩码。 | Linux Windows macOS |
| unlink(String) (deprecated) | 从文件系统中删除文件。 | Linux macOS |
| unlinkat(Int32, String, Int32) (deprecated) | 从文件系统中删除文件。 | Linux macOS |
| write(Int32, CPointer<UInt8>, UIntNative) (deprecated) | 将 buffer 指向的内存中 nbyte 字节写入到 fd 指向的文件。 | Linux Windows macOS |
常量
| 常量名 | 功能 | 支持平台 |
|---|---|---|
| AT_EMPTY_PATH (deprecated) | 表示在文件系统中空路径(即没有指定任何文件或目录)时返回的文件描述符,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows |
| AT_FDCWD (deprecated) | 表示在文件系统中相对路径操作的特殊文件描述符常量,用于在使用 *at() 系列系统调用时指定相对路径的解析起点。主要用于 fchmodat、fchownat、linkat、renameat、symlinkat、unlinkat等函数,所属函数参数 fd。 | Linux Windows |
| AT_REMOVEDIR (deprecated) | 如果指定了 AT_REMOVEDIR 标志,则对 pathname 执行等效于 rmdir(2) 的操作,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows macOS |
| AT_SYMLINK_FOLLOW (deprecated) | 表示一个用于控制符号链接解析行为的标志,指定在操作符号链接时是否跟随链接指向的目标文件。通常与 AT_FDCWD 结合使用。若无该标志,大多数系统调用会直接操作符号链接本身(如读取链接路径)。使用该标志后,系统调用会先解析符号链接,然后操作其指向的目标文件。主要用于 linkat、unlinkat 等函数,所属函数参数 fd。 | Linux Windows macOS |
| O_CLOEXEC (deprecated) | 在某些多线程程序中,使用此标志是必不可少的。因为在一个线程同时打开文件描述符,而另一个线程执行 fork(2) 加 execve(2) 场景下使用单独的 fcntl(2) F_SETFD 操作设置 FD_CLOEXEC 标志并不足以避免竞争条件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux macOS |
| O_DIRECTORY (deprecated) | 如果 pathname 指定的文件不是目录,则打开文件失败,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux macOS |
| O_CREAT (deprecated) | 如果要打开的文件不存在,则自动创建该文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows macOS |
| O_DSYNC (deprecated) | 每次写入都会等待物理 I/O 完成,但如果写操作不影响读取刚写入的数据,则不等待文件属性更新,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux macOS |
| O_EXCL (deprecated) | 如同时设置 O_CREAT,则此指令检查文件是否存在。如果文件不存在,则创建文件。否则,打开文件出错。此外,如果同时设置了 O_CREAT 和 O_EXCL,并且要打开的文件是符号链接,则打开文件失败,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows macOS |
| O_NOCTTY (deprecated) | 如要打开的文件是终端设备,则该文件不会成为这个进程的控制终端,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux macOS |
| O_NOFOLLOW (deprecated) | 如 pathname 指定的文件是单符号链接,则打开文件失败,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux macOS |
| O_NONBLOCK (deprecated) | 以非阻塞的方式打开文件,即 I/O 操作不会导致调用进程等待,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux macOS |
| O_SYNC (deprecated) | 同步打开文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux macOS |
| O_RDONLY (deprecated) | 以只读方式打开文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows macOS |
| O_RDWR (deprecated) | 以读写模式打开文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows macOS |
| O_WRONLY (deprecated) | 以只写方式打开文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows macOS |
| O_APPEND (deprecated) | 读取或写入文件时,数据将从文件末尾移动。即写入的数据将附加到文件的末尾,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows macOS |
| O_RSYNC (deprecated) | 此标志仅影响读取操作,必须与 O_SYNC 或 O_DSYNC 结合使用。如果有必要,它将导致读取调用阻塞,直到正在读取的数据(可能还有元数据)刷新到磁盘,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux |
| O_TRUNC (deprecated) | 如果文件存在且打开可写,则此标志将文件长度清除为 0,文件中以前存储的数据消失,适用函数 open、open64、openat、openat64,所属函数参数 oflag。 | Linux Windows macOS |
| R_OK (deprecated) | 测试文件读权限,适用函数 access,faccessat,所属函数参数 mode。 | Linux Windows macOS |
| W_OK (deprecated) | 测试文件写权限,适用函数 access,faccessat,所属函数参数 mode。 | Linux Windows macOS |
| X_OK (deprecated) | 测试文件执行权限,适用函数 access,faccessat,所属函数参数 mode。 | Linux Windows macOS |
| F_OK (deprecated) | 测试文件是否存在,适用函数 access,faccessat,所属函数参数 mode。 | Linux Windows macOS |
| SEEK_SET (deprecated) | 偏移参数表示新的读写位置,适用函数 lseek,所属函数参数 whence。 | Linux Windows macOS |
| SEEK_CUR (deprecated) | 向当前读或写位置添加偏移量,适用函数 lseek,所属函数参数 whence。 | Linux Windows macOS |
| SEEK_END (deprecated) | 将读写位置设置为文件末尾,并添加偏移量,适用函数 lseek,所属函数参数 whence。 | Linux Windows macOS |
| SIGABRT (deprecated) | 异常终止,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGBUS (deprecated) | 硬件故障,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGFPE (deprecated) | 算术错误,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGKILL (deprecated) | 终止,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGCONT (deprecated) | 暂停过程的继续,默认操作继续或忽略,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGHUP (deprecated) | 连接已断开,默认操作已终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGINT (deprecated) | 终端中断字符,默认动作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGQUIT (deprecated) | 终端退出字符,默认动作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGILL (deprecated) | 硬件指令无效,默认动作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGTRAP (deprecated) | 硬件故障,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGIOT (deprecated) | 硬件故障,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGIO (deprecated) | 异步 IO,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGPIPE (deprecated) | 写入未读进程的管道,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGALRM (deprecated) | 计时器到期,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGPWR (deprecated) | 电源故障或重启,系统调用无效,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows |
| SIGSEGV (deprecated) | 内存引用无效,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGSTOP (deprecated) | 停止,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGSYS (deprecated) | 终止,默认操作终止进程并生成核心转储文件(core dump),用于调试分析,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGTERM (deprecated) | 终止,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGSTKFLT (deprecated) | 协处理器堆栈故障,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows |
| SIGCHLD (deprecated) | 子进程状态更改,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGTSTP (deprecated) | 终端停止符号,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGTTIN (deprecated) | 后台读取控件 tty,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGTTOU (deprecated) | 后台写控制 tty,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGURG (deprecated) | 紧急情况(套接字),忽略默认操作,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGUSR1 (deprecated) | 用户定义的信号,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGUSR2 (deprecated) | 用户定义的信号,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGVTALRM (deprecated) | 虚拟时间警报,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGPROF (deprecated) | 摘要超时,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGWINCH (deprecated) | 终端窗口大小更改,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGXCPU (deprecated) | CPU 占用率超过上限,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| SIGXFSZ (deprecated) | 文件长度超过上限,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。 | Linux Windows macOS |
| S_IRUSR (deprecated) | 表示文件所有者具有读权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IWUSR (deprecated) | 表示文件所有者具有写权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IRGRP (deprecated) | 表示文件用户组具有读权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IWGRP (deprecated) | 表示文件用户组具有写权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IFREG (deprecated) | 文件类型为一般文件,适用函数 isType, 所属函数参数 mode。 | Linux Windows macOS |
| S_IFBLK (deprecated) | 文件类型为块设备,适用函数 isType, 所属函数参数 mode。 | Linux Windows macOS |
| S_IFDIR (deprecated) | 文件类型为目录,适用函数 isType, 所属函数参数 mode。 | Linux Windows macOS |
| S_IFCHR (deprecated) | 文件类型为字符设备,适用函数 isType, 所属函数参数 mode。 | Linux Windows macOS |
| S_IFIFO (deprecated) | 文件类型为 FIFO 文件,适用函数 isType, 所属函数参数 mode。 | Linux Windows macOS |
| S_IFLNK (deprecated) | 文件类型为软连接,适用函数 isType, 所属函数参数 mode。 | Linux Windows macOS |
| S_IFSOCK (deprecated) | 文件类型为套接字文件,适用函数 isType, 所属函数参数 mode。 | Linux Windows macOS |
| S_IROTH (deprecated) | 表示其他用户对文件具有读权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IRWXG (deprecated) | 表示文件用户组具有读、写、执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IRWXU (deprecated) | 表示文件所有者具有读、写和执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IWOTH (deprecated) | 表示其他用户对文件具有写权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IXOTH (deprecated) | 表示其他用户对文件具有执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IRWXO (deprecated) | 表示其他用户对文件具有读、写和执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IXGRP (deprecated) | 表示文件用户组具有执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
| S_IXUSR (deprecated) | 表示文件所有者具有执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。 | Linux Windows macOS |
常量&变量
const AT_EMPTY_PATH (deprecated)
public const AT_EMPTY_PATH: Int32 = 0x1000
功能:表示在文件系统中空路径(即没有指定任何文件或目录)时返回的文件描述符,适用函数 open、open64、openat、openat64,所属函数参数 oflag。
注意:
未来版本即将废弃。
类型:Int32
const AT_FDCWD (deprecated)
public const AT_FDCWD: Int32
功能:表示在文件系统中相对路径操作的特殊文件描述符常量,用于在使用 *at() 系列系统调用时指定相对路径的解析起点。主要用于 fchmodat、fchownat、linkat、renameat、symlinkat、unlinkat等函数,所属函数参数 fd。不同系统下的值分别为:
- macOS:-0x2
- 其他情况:-0x64
注意
未来版本即将废弃。
类型:Int32
const AT_REMOVEDIR (deprecated)
public const AT_REMOVEDIR: Int32 = 0x200
功能:如果指定了 AT_REMOVEDIR 标志,则对 pathname 执行等效于 rmdir(2) 的操作,适用函数 open、open64、openat、openat64,所属函数参数 oflag。
注意:
未来版本即将废弃。
类型:Int32
const AT_SYMLINK_FOLLOW (deprecated)
public const AT_SYMLINK_FOLLOW: Int32
功能:表示一个用于控制符号链接解析行为的标志,指定在操作符号链接时是否跟随链接指向的目标文件。通常与 AT_FDCWD 结合使用。若无该标志,大多数系统调用会直接操作符号链接本身(如读取链接路径)。使用该标志后,系统调用会先解析符号链接,然后操作其指向的目标文件。主要用于 linkat、unlinkat 等函数,所属函数参数 fd。不同系统下的值分别为:
- macOS:0x040
- 其他情况:0x400
注意
未来版本即将废弃。
类型:Int32
const F_OK (deprecated)
public const F_OK: Int32 = 0x0
功能:测试文件是否存在,适用函数 access,faccessat,所属函数参数 mode。
注意:
未来版本即将废弃。
类型:Int32
const O_APPEND (deprecated)
public const O_APPEND: Int32
功能:读取或写入文件时,数据将从文件末尾移动。即写入的数据将附加到文件的末尾,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x00000008
- Windows: 0x8
- 其他情况:0x400
注意:
未来版本即将废弃。
类型:Int32
const O_CLOEXEC (deprecated)
public const O_CLOEXEC: Int32
功能:在某些多线程程序中,使用此标志是必不可少的。因为在一个线程同时打开文件描述符,而另一个线程执行 fork(2) 加 execve(2) 场景下使用单独的 fcntl(2) F_SETFD 操作设置 FD_CLOEXEC 标志并不足以避免竞争条件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x01000000
- 其他情况:0x80000
注意:
未来版本即将废弃。
类型:Int32
const O_CREAT (deprecated)
public const O_CREAT: Int32
功能:如果要打开的文件不存在,则自动创建该文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x00000200
- Windows: 0x100
- 其他情况:0x40
注意:
未来版本即将废弃。
类型:Int32
const O_DIRECTORY (deprecated)
public const O_DIRECTORY: Int32
功能:如果 pathname 指定的文件不是目录,则打开文件失败,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x00100000
- 其他情况:0x80000
注意:
未来版本即将废弃。
类型:Int32
const O_DSYNC (deprecated)
public const O_DSYNC: Int32
功能:每次写入都会等待物理 I/O 完成,但如果写操作不影响读取刚写入的数据,则不等待文件属性更新,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x400000
- 其他情况:0x1000
注意:
未来版本即将废弃。
类型:Int32
const O_EXCL (deprecated)
public const O_EXCL: Int32
功能:如同时设置 O_CREAT,则此指令检查文件是否存在。如果文件不存在,则创建文件。否则,打开文件出错。此外,如果同时设置了 O_CREAT 和 O_EXCL,并且要打开的文件是符号链接,则打开文件失败,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x00000800
- Windows: 0x400
- 其他情况:0x80
注意:
未来版本即将废弃。
类型:Int32
const O_NOCTTY (deprecated)
public const O_NOCTTY: Int32
功能:如要打开的文件是终端设备,则该文件不会成为这个进程的控制终端,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x00020000
- 其他情况:0x100
注意:
未来版本即将废弃。
类型:Int32
const O_NOFOLLOW (deprecated)
public const O_NOFOLLOW: Int32
功能:如 pathname 指定的文件是单符号连接,则打开文件失败,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x00000100
- 其他情况:0x20000
注意:
未来版本即将废弃。
类型:Int32
const O_NONBLOCK (deprecated)
public const O_NONBLOCK: Int32
功能:以非阻塞的方式打开文件,即 I/O 操作不会导致调用进程等待,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x00000004
- 其他情况:0x800
注意:
未来版本即将废弃。
类型:Int32
const O_RDONLY (deprecated)
public const O_RDONLY: Int32 = 0x0
功能:以只读方式打开文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。
注意:
未来版本即将废弃。
类型:Int32
const O_RDWR (deprecated)
public const O_RDWR: Int32 = 0x2
功能:以读写模式打开文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。
注意:
未来版本即将废弃。
类型:Int32
const O_RSYNC (deprecated)
public const O_RSYNC: Int32 = 0x101000
功能:此标志仅影响读取操作,必须与 O_SYNC 或 O_DSYNC 结合使用。如果有必要,它将导致读取调用阻塞,直到正在读取的数据(可能还有元数据)刷新到磁盘,适用函数 open、open64、openat、openat64,所属函数参数 oflag。
注意:
未来版本即将废弃。
类型:Int32
const O_SYNC (deprecated)
public const O_SYNC: Int32
功能:同步打开文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x0080
- 其他情况:0x101000
注意:
未来版本即将废弃。
类型:Int32
const O_TRUNC (deprecated)
public const O_TRUNC: Int32
功能:如果文件存在且打开可写,则此标志将文件长度清除为 0,文件中以前存储的数据消失,适用函数 open、open64、openat、openat64,所属函数参数 oflag。不同系统下的值分别为:
- macOS: 0x00000400
- 其他情况:0x200
注意:
未来版本即将废弃。
类型:Int32
const O_WRONLY (deprecated)
public const O_WRONLY: Int32 = 0x1
功能:以只写方式打开文件,适用函数 open、open64、openat、openat64,所属函数参数 oflag。
注意:
未来版本即将废弃。
类型:Int32
const R_OK (deprecated)
public const R_OK: Int32 = 0x4
功能:测试文件读权限,适用函数 access,faccessat,所属函数参数 mode。
注意:
未来版本即将废弃。
类型:Int32
const SEEK_CUR (deprecated)
public const SEEK_CUR: Int32 = 0x1
功能:向当前读或写位置添加偏移量,适用函数 lseek,所属函数参数 whence。
注意:
未来版本即将废弃。
类型:Int32
const SEEK_END (deprecated)
public const SEEK_END: Int32 = 0x2
功能:将读写位置设置为文件末尾,并添加偏移量,适用函数 lseek,所属函数参数 whence。
注意:
未来版本即将废弃。
类型:Int32
const SEEK_SET (deprecated)
public const SEEK_SET: Int32 = 0x0
功能:偏移参数表示新的读写位置,适用函数 lseek,所属函数参数 whence。
注意:
未来版本即将废弃。
类型:Int32
const SIGABRT (deprecated)
public const SIGABRT: Int32 = 0x6
功能:异常终止,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGALRM (deprecated)
public const SIGALRM: Int32 = 0xE
功能:计时器到期,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGBUS (deprecated)
public const SIGBUS: Int32
功能:硬件故障,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0xA
- 其他情况:0x7
注意:
未来版本即将废弃。
类型:Int32
const SIGCHLD (deprecated)
public const SIGCHLD: Int32
功能:子进程状态更改,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0x14
- 其他情况:0x11
注意:
未来版本即将废弃。
类型:Int32
const SIGCONT (deprecated)
public const SIGCONT: Int32
功能:暂停过程的继续,默认操作继续或忽略,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0x13
- 其他情况:0x12
注意:
未来版本即将废弃。
类型:Int32
const SIGFPE (deprecated)
public const SIGFPE: Int32 = 0x8
功能:算术错误,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGHUP (deprecated)
public const SIGHUP: Int32 = 0x1
功能:连接已断开,默认操作已终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGILL (deprecated)
public const SIGILL: Int32 = 0x4
功能:硬件指令无效,默认动作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGINT (deprecated)
public const SIGINT: Int32 = 0x2
功能:终端中断字符,默认动作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGIO (deprecated)
public const SIGIO: Int32
功能:异步 IO,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0x17
- 其他情况:0x1D
注意:
未来版本即将废弃。
类型:Int32
const SIGIOT (deprecated)
public const SIGIOT: Int32 = 0x6
功能:硬件故障,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGKILL (deprecated)
public const SIGKILL: Int32 = 0x9
功能:终止,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGPIPE (deprecated)
public const SIGPIPE: Int32 = 0xD
功能:写入未读进程的管道,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGPROF (deprecated)
public const SIGPROF: Int32 = 0x1B
功能:摘要超时,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGPWR (deprecated)
public const SIGPWR: Int32 = 0x1E
功能:电源故障或重启,系统调用无效,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGQUIT (deprecated)
public const SIGQUIT: Int32 = 0x3
功能:终端退出字符,默认动作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGSEGV (deprecated)
public const SIGSEGV: Int32 = 0xB
功能:内存引用无效,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGSTKFLT (deprecated)
public const SIGSTKFLT: Int32 = 0x10
功能:协处理器堆栈故障,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGSTOP (deprecated)
public const SIGSTOP: Int32
功能:停止,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0x11
- 其他情况:0x13
注意:
未来版本即将废弃。
类型:Int32
const SIGSYS (deprecated)
public const SIGSYS: Int32
功能:终止,默认操作终止进程并生成核心转储文件(core dump),用于调试分析,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS:0xC
- 其他情况:0x1F
注意
未来版本即将废弃。
类型:Int32
const SIGTERM (deprecated)
public const SIGTERM: Int32 = 0xF
功能:终止,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGTRAP (deprecated)
public const SIGTRAP: Int32 = 0x5
功能:硬件故障,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGTSTP (deprecated)
public const SIGTSTP: Int32
功能:终端停止符号,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0x12
- 其他情况:0x14
注意:
未来版本即将废弃。
类型:Int32
const SIGTTIN (deprecated)
public const SIGTTIN: Int32 = 0x15
功能:后台读取控件 tty,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGTTOU (deprecated)
public const SIGTTOU: Int32 = 0x16
功能:后台写控制 tty,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGURG (deprecated)
public const SIGURG: Int32
功能:紧急情况(套接字),忽略默认操作,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0x10
- 其他情况:0x17
注意:
未来版本即将废弃。
类型:Int32
const SIGUSR1 (deprecated)
public const SIGUSR1: Int32
功能:用户定义的信号,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0x1E
- 其他情况:0xA
注意:
未来版本即将废弃。
类型:Int32
const SIGUSR2 (deprecated)
public const SIGUSR2: Int32
功能:用户定义的信号,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。不同系统下的值分别为:
- macOS: 0x1F
- 其他情况:0xC
注意:
未来版本即将废弃。
类型:Int32
const SIGVTALRM (deprecated)
public const SIGVTALRM: Int32 = 0x1A
功能:虚拟时间警报,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGWINCH (deprecated)
public const SIGWINCH: Int32 = 0x1C
功能:终端窗口大小更改,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGXCPU (deprecated)
public const SIGXCPU: Int32 = 0x18
功能:CPU 占用率超过上限,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const SIGXFSZ (deprecated)
public const SIGXFSZ: Int32 = 0x19
功能:文件长度超过上限,默认操作终止,适用函数 kill,killpg,所属函数参数 sig。
注意:
未来版本即将废弃。
类型:Int32
const S_IFBLK (deprecated)
public const S_IFBLK: UInt32 = 0x6000
功能:文件类型为块设备,适用函数 isType, 所属函数参数 mode。
注意:
未来版本即将废弃。
类型:UInt32
const S_IFCHR (deprecated)
public const S_IFCHR: UInt32 = 0x2000
功能:文件类型为字符设备,适用函数 isType, 所属函数参数 mode。
注意:
未来版本即将废弃。
类型:UInt32
const S_IFDIR (deprecated)
public const S_IFDIR: UInt32 = 0x4000
功能:文件类型为目录,适用函数 isType, 所属函数参数 mode。
注意:
未来版本即将废弃。
类型:UInt32
const S_IFIFO (deprecated)
public const S_IFIFO: UInt32 = 0x1000
功能:文件类型为 FIFO 文件,适用函数 isType, 所属函数参数 mode。
注意:
未来版本即将废弃。
类型:UInt32
const S_IFLNK (deprecated)
public const S_IFLNK: UInt32 = 0xA000
功能:文件类型为软连接,适用函数 isType, 所属函数参数 mode。
注意:
未来版本即将废弃。
类型:UInt32
const S_IFREG (deprecated)
public const S_IFREG: UInt32 = 0x8000
功能:文件类型为一般文件,适用函数 isType, 所属函数参数 mode。
注意:
未来版本即将废弃。
类型:UInt32
const S_IFSOCK (deprecated)
public const S_IFSOCK: UInt32 = 0xC000
功能:文件类型为套接字文件,适用函数 isType, 所属函数参数 mode。
注意:
未来版本即将废弃。
类型:UInt32
const S_IRGRP (deprecated)
public const S_IRGRP: UInt32 = 0x20
功能:表示文件用户组具有读权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IROTH (deprecated)
public const S_IROTH: UInt32 = 0x4
功能:表示其他用户对文件具有读权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IRUSR (deprecated)
public const S_IRUSR: UInt32 = 0x100
功能:表示文件所有者具有读权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IRWXG (deprecated)
public const S_IRWXG: UInt32 = 0x38
功能:表示文件用户组具有读、写、执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IRWXO (deprecated)
public const S_IRWXO: UInt32 = 0x7
功能:表示其他用户对文件具有读、写和执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IRWXU (deprecated)
public const S_IRWXU: UInt32 = 0x1C0
功能:表示文件所有者具有读、写和执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IWGRP (deprecated)
public const S_IWGRP: UInt32 = 0x10
功能:表示文件用户组具有写权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IWOTH (deprecated)
public const S_IWOTH: UInt32 = 0x2
功能:表示其他用户对文件具有写权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IWUSR (deprecated)
public const S_IWUSR: UInt32 = 0x80
功能:表示文件所有者具有写权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IXGRP (deprecated)
public const S_IXGRP: UInt32 = 0x8
功能:表示文件用户组具有执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IXOTH (deprecated)
public const S_IXOTH: UInt32 = 0x1
功能:表示其他用户对文件具有执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
类型:UInt32
const S_IXUSR (deprecated)
public const S_IXUSR: UInt32 = 0x40
功能:表示文件所有者具有执行权限,适用函数 open,open64,openat,openat64,chmod(mode),fchmod(mode),fchmodat(mode),creat, 所属函数参数 flag。
注意:
未来版本即将废弃。
const W_OK (deprecated)
public const W_OK: Int32 = 0x2
功能:测试文件写权限,适用函数 access,faccessat,所属函数参数 mode。
注意:
未来版本即将废弃。
类型:UInt32
const X_OK (deprecated)
public const X_OK: Int32 = 0x1
功能:测试文件执行权限,适用函数 access,faccessat,所属函数参数 mode。
注意:
未来版本即将废弃。
类型:Int32
函数
func open(String, Int32) (deprecated)
public func `open`(path: String, oflag: Int32): Int32
功能:打开文件并为其返回新的文件描述符,或在失败时返回 -1。
当文件打开方式参数 oflag 设置为 O_CREAT 时,可以通过参数设置文件权限。
O_RDONLY、O_RDWR、O_WRONLY 作为 oflag 取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 返回新的文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func open(String, Int32, UInt32) (deprecated)
public func `open`(path: String, oflag: Int32, flag: UInt32): Int32
功能:打开文件并为其返回新的文件描述符,或在失败时返回 -1。path 代表文件路径,oflag 代表文件打开的方式,其中 O_RDONLY、O_RDWR、O_WRONLY 作为 oflag 取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 操作。
当文件打开方式参数 oflag 设置为 O_CREAT 时,可以通过参数设置文件权限。
O_RDONLY、O_RDWR、O_WRONLY 作为 oflag 取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
- oflag: Int32 - 文件打开的方式。
- flag: UInt32 - 如果
oflag设置了 O_CREAT 并且需要创建新文件,则flag参数标识对新文件的权限,否则flag不改变文件权限。
返回值:
- Int32 - 返回新的文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func access(String, Int32) (deprecated)
public func access(path: String, mode: Int32): Int32
功能:判断某个文件是否具有某种权限,具有返回 0,否则返回 -1。
mode 为指定权限,传入类型 R_OK、W_OK、X_OK、F_OK。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 文件具有待检查的权限返回
0,否则返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func chdir(String) (deprecated)
public func chdir(path: String): Int32
功能:通过指定路径的方式,更改调用进程的当前工作目录。
注意:
未来版本即将废弃。
参数:
- path: String - 改变后的路径。
返回值:
- Int32 - 设置成功,返回
0,设置失败, 返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func chmod(String, UInt32) (deprecated)
public func chmod(path: String, mode: UInt32): Int32
功能:修改文件访问权限。
在 Windows 环境下:
- 所有文件和目录都是可读的,chmod() 不能更改文件的可读权限;
- 在
Windows环境下,文件的可执行权限通过文件扩展名设置,所有目录都是可执行的,chmod() 不能更改文件和目录的可执行权限。
注意:
未来版本即将废弃。
参数:
返回值:
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func chown(String, UInt32, UInt32) (deprecated)
public func chown(path: String, owner: UInt32, group: UInt32): Int32
功能:修改文件所有者和文件所有者所属组。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 操作成功时返回
0,失败时返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func close(Int32) (deprecated)
public func close(fd: Int32): Int32
功能:关闭文件,close 将会触发数据写回磁盘,并释放文件占用的资源。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
返回值:
- Int32 - 成功时返回
0,失败时返回-1。
func creat(String, UInt32) (deprecated)
public func creat(path: String, flag: UInt32): Int32
功能:创建文件并为其返回文件描述符,或在失败时返回 -1。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 返回文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func dup(Int32) (deprecated)
public func dup(fd: Int32): Int32
功能:用于复制旧 fd 参数指定的文件描述符并返回。此新文件描述符和旧的参数 fd 引用同一文件,共享文件各种状态。共享所有的锁定、读写位置和各项权限或标志等。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
返回值:
- Int32 - 返回最小且未使用的文件描述符,执行失败时返回
-1。
func dup2(Int32, Int32) (deprecated)
public func dup2(fd: Int32, fd2: Int32): Int32
功能:用于复制 oldfd 参数指定的文件描述符,并将其返回到 newfd 参数。如果参数 newfd 是打开的文件描述符,则 newfd 指定的文件将首先关闭。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 -
fd2文件描述符。
func faccessat(Int32, String, Int32, Int32) (deprecated)
public func faccessat(fd: Int32, path: String, mode: Int32, flag: Int32): Int32
功能:判断 fd 对应的文件是否具有某种权限,具有返回 0,否则返回 -1。
mode 为指定权限,传入类型 R_OK、W_OK、X_OK、F_OK。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
- path: String - 文件路径。
- mode: Int32 - 待检查的权限。
- flag: Int32 - 将以下一个或多个值按位或运算获取。
(512)使用有效的用户和组ID执行访问检查,默认情况下使用有效ID;(256)如果路径名是符号链接,不会取消引用而是返回有关链接本身信息。
返回值:
- Int32 - 文件具有待检查的权限返回
0,否则返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func fchdir(Int32) (deprecated)
public func fchdir(fd: Int32): Int32
功能:通过指定文件路径的描述符,更改调用进程的当前工作目录。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 改变后的文件路径的描述符。
返回值:
- Int32 - 设置成功,返回
0,设置失败, 返回-1。
func fchmod(Int32, UInt32) (deprecated)
public func fchmod(fd: Int32, mode: UInt32): Int32
功能:修改文件描述符对应的文件访问权限。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 操作成功时返回
0,失败时返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func fchmodat(Int32, String, UInt32, Int32) (deprecated)
public func fchmodat(fd: Int32, path: String, mode: UInt32, flag: Int32): Int32
功能:修改文件描述符对应的文件访问权限。
path为相对路径且fd为特殊值AT_FDCWD时,则路径将相对于调用进程的当前工作目录。path为相对路径且fd非AT_FDCWD时,则路径将相对于fd引用的文件所属目录。path为绝对路径时fd参数将被忽略。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
- path: String - 文件路径。
- mode: UInt32 - 要修改的权限。
- flag: Int32 - 取值可为
0,或(256)如果路径名是符号链接,不会取消引用它,而是返回有关链接本身的信息。
返回值:
- Int32 - 操作成功时返回
0,失败时返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func fchown(Int32, UInt32, UInt32) (deprecated)
public func fchown(fd: Int32, owner: UInt32, group: UInt32): Int32
功能:修改 fd 对应的文件所有者和文件所有者所属组。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 操作成功时返回
0,失败时返回-1。
func fchownat(Int32, String, UInt32, UInt32, Int32) (deprecated)
public func fchownat(fd: Int32, path: String, owner: UInt32, group: UInt32, flag: Int32): Int32
功能:修改文件描述符对应的文件所有者和文件所有者所属组。
path为相对路径且fd为特殊值AT_FDCWD时,则路径将相对于调用进程的当前工作目录。path为相对路径且fd非AT_FDCWD时,则路径将相对于fd引用的文件所属目录。path为绝对路径时fd参数将被忽略。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
- path: String - 文件路径。
- owner: UInt32 - 所有者
uid。 - group: UInt32 - 指定
gid参数。 - flag: Int32 - 取值可为
0,或(256)如果路径名是符号链接,不会取消引用它,而是返回有关链接本身的信息。
返回值:
- Int32 - 操作成功时返回
0,失败时返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func getcwd() (deprecated)
public func getcwd(): String
功能:获取当前执行进程工作目录的绝对路径。
注意:
未来版本即将废弃。
返回值:
- String - 操作成功,返回包含路径信息的字符串,操作失败则返回空字符串。
func getgid() (deprecated)
public func getgid(): UInt32
功能:获取用户组 ID。
注意:
未来版本即将废弃。
返回值:
- UInt32 - 当前用户组
ID。
func getgroups(Int32, CPointer<UInt32>) (deprecated)
public unsafe func getgroups(size: Int32, gidArray: CPointer<UInt32>): Int32
功能:获取当前用户所属组的代码。
如果 gidArray 参数大小的值为零,则函数仅返回表示用户所属的组数,不会向 gidArray 中放入 gid。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 执行成功,返回组代码,执行失败, 返回
-1。
func gethostname() (deprecated)
public func gethostname(): String
功能:获取主机名称,此名称通常是 TCP/IP 网络上主机的名称。
注意:
未来版本即将废弃。
返回值:
- String - 获取到的主机的名称字符串, 获取失败则返回空字符串。
func getlogin() (deprecated)
public func getlogin(): String
功能:获取当前登录名。
注意:
未来版本即将废弃。
返回值:
- String - 操作成功时返回登录名,失败时返回空字串。
func getos() (deprecated)
public func getos(): String
功能:从 /proc/version 文件中获取 Linux 系统的信息。例如: Linux version 4.15.0-142-generic (buildd@lgw01-amd64-036) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #146-Ubuntu SMP Tue Apr 13 01:11:19 UTC 2021。
注意:
未来版本即将废弃。
返回值:
- String - 获取到的 Linux 系统的信息字符串。
func getpgid(Int32) (deprecated)
public func getpgid(pid: Int32): Int32
功能:获取 pid 指定的进程的 PGID,如果 pid 为零,返回调用进程的进程 ID。
注意:
未来版本即将废弃。
参数:
- pid: Int32 - 目标进程
ID。
返回值:
- Int32 - 执行成功,返回进程组
ID,执行失败, 返回-1。
func getpgrp() (deprecated)
public func getpgrp(): Int32
功能:获取调用进程的父进程 ID。
注意:
未来版本即将废弃。
返回值:
- Int32 - 返回调用进程的父进程
ID。
func getpid() (deprecated)
public func getpid(): Int32
功能:获取调用进程的进程 ID(PID)。
注意:
未来版本即将废弃。
返回值:
- Int32 - 返回调用进程的进程
ID(PID)。
func getppid() (deprecated)
public func getppid(): Int32
功能:获取调用进程的父进程 ID。
注意:
未来版本即将废弃。
返回值:
- Int32 - 返回调用进程的父进程
ID。
func getuid() (deprecated)
public func getuid(): UInt32
功能:获取调用进程的真实用户 ID。
注意:
未来版本即将废弃。
返回值:
- UInt32 - 当前真实用户
ID。
func isBlk(String) (deprecated)
public func isBlk(path: String): Bool
功能:检查传入对象是否为块设备,并返回布尔类型。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Bool - 如果是,返回
true,否则返回false。
func isChr(String) (deprecated)
public func isChr(path: String): Bool
功能:检查传入对象是否为字符设备,返回布尔类型。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Bool - 如果是,返回
true,否则返回false。
func isDir(String) (deprecated)
public func isDir(path: String): Bool
功能:检查传入对象是否为文件夹,返回布尔类型。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Bool - 如果是,返回
true,否则返回false。
func isFIFO(String) (deprecated)
public func isFIFO(path: String): Bool
功能:检查传入对象是否为 FIFO 文件,返回布尔类型。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Bool - 如果是,返回
true,否则返回false。
func isLnk(String) (deprecated)
public func isLnk(path: String): Bool
功能:检查传入对象是否为软链路,返回布尔类型。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Bool - 如果是,返回
true,否则返回false。
func isReg(String) (deprecated)
public func isReg(path: String): Bool
功能:检查传入对象是否为普通文件,返回布尔类型。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Bool - 如果是,返回
true,否则返回false。
func isSock(String) (deprecated)
public func isSock(path: String): Bool
功能:检查传入对象是否为套接字文件,返回布尔类型。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Bool - 如果是,返回
true,否则返回false。
func isType(String, UInt32) (deprecated)
public func isType(path: String, mode: UInt32): Bool
功能:检查文件是否为指定模式的文件。如果是,返回 ture,否则返回 false。根据模式的不同值确定不同的类型。
注意:
未来版本即将废弃。
参数:
返回值:
- Bool - 如果是指定模式的文件,返回
true,否则返回false。
func isatty(Int32) (deprecated)
public func isatty(fd: Int32): Bool
功能:用于测试文件描述符是否引用终端,成功时返回 true,否则返回 false。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
返回值:
- Bool - 操作成功时返回
true,否则返回false。
func kill(Int32, Int32) (deprecated)
public func kill(pid: Int32, sig: Int32): Int32
功能:系统调用可用于向任何进程组或进程发送任何信号。
- 如果
pid大于0,则信号sig将发送到pid对应的进程。 - 如果
pid等于0,然后sig被发送到调用进程的进程组中的每个进程。 - 如果
pid等于-1,则sig被发送到调用进程有权发送信号的每个进程。 - 如果
pid小于-1,则将sig发送到ID为-pid的进程组中的每个进程。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 操作成功时返回
0,否则返回-1。
func killpg(Int32, Int32) (deprecated)
public func killpg(pgid: Int32, sig: Int32): Int32
功能:将信号 sig 发送到进程组 pgrp,如果 pgrp 为 0,则 killpg() 将信号发送到调用进程的进程组。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 操作成功时返回
0,否则返回-1。
func lchown(String, UInt32, UInt32) (deprecated)
public func lchown(path: String, owner: UInt32, group: UInt32): Int32
功能:修改文件链接本身所有者和所有者所属组。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 操作成功时返回
0,失败时返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func link(String, String) (deprecated)
public func link(path: String, newpath: String): Int32
功能:为存在的文件创建链接,一个文件可以有多个指向其 i-node 的目录条目。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
path或newPath包含空字符时,抛出异常。
func linkat(Int32, String, Int32, String, Int32) (deprecated)
public func linkat(fd: Int32, path: String, nfd: Int32, newPath: String, lflag: Int32): Int32
功能:创建相对于目录文件描述符的文件链接。
path为相对路径且fd为特殊值AT_FDCWD时,则路径将相对于调用进程的当前工作目录。path为相对路径且fd非AT_FDCWD时,则路径将相对于fd引用的文件所属目录。path为绝对路径时fd参数将被忽略。newPath的场景与path相同,只是当newPath为相对路径时是相对于nfd引用的文件所属目录。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
- path: String - 文件路径。
- nfd: Int32 - 其他文件描述符。
- newPath: String - 其他文件路径,如果
newpath存在,则不会覆盖。 - lflag: Int32 - AT_EMPTY_PATH 或
AT_SYMLINK_FOLLOW或0。
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
path或newPath包含空字符时,抛出异常。
func lseek(Int32, Int64, Int32) (deprecated)
public func lseek(fd: Int32, offset: Int64, whence: Int32): Int64
功能:当文件进行读或写时,读或写位置相应增加。本函数用于控制文件的读或写位置。调用成功时,返回当前读写位置,即从文件开头开始的字节数。如果发生错误,返回 -1。
注意:
未来版本即将废弃。
参数:
返回值:
- Int64 - 调用成功时,返回当前读写位置,即从文件开头开始的字节数。
func nice(Int32) (deprecated)
public func nice(inc: Int32): Int32
功能:更改当前线程的优先级。
成功时返回新值,失败时返回 -1。 inc 在值大于 19 时,返回最大值 19。
只有超级用户才能使用负的 inc 值,表示优先级高,进程执行得更快。 inc 代表当前进程的优先级,取值的范围是 +19(低优先级)到 -20。
注意:
未来版本即将废弃。
参数:
- inc: Int32 - 当前进程的优先级, 值的范围是
+19(低优先级)到-20。
返回值:
- Int32 - 返回新优先级值。
func open64(String, Int32) (deprecated)
public func open64(path: String, oflag: Int32): Int32
功能:打开文件并为其返回新的文件描述符,或在失败时返回 -1。
- 当文件打开方式参数
oflag设置为 O_CREAT 时,可以通过参数设置文件权限。 - O_RDONLY、O_RDWR、O_WRONLY 作为
oflag取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 返回新的文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func open64(String, Int32, UInt32) (deprecated)
public func open64(path: String, oflag: Int32, flag: UInt32): Int32
功能:打开文件并为其返回新的文件描述符,或在失败时返回 -1。
- 当文件打开方式参数
oflag设置为 O_CREAT 时,可以通过参数设置文件权限。 - O_RDONLY、O_RDWR、O_WRONLY 作为
oflag取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
- oflag: Int32 - 文件打开的方式。
- flag: UInt32 - 如果
oflag设置了 O_CREAT 并且需要创建新文件,则flag参数标识对新文件的权限,否则flag不改变文件权限。
返回值:
- Int32 - 返回新的文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func openat(Int32, String, Int32) (deprecated)
public func openat(fd: Int32, path: String, oflag: Int32): Int32
功能:打开文件并为其返回新的文件描述符,或在失败时返回 -1。
- 当文件打开方式参数
oflag设置为 O_CREAT 时,可以通过参数设置文件权限。 - O_RDONLY、O_RDWR、O_WRONLY 作为
oflag取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 返回新的文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func openat(Int32, String, Int32, UInt32) (deprecated)
public func openat(fd: Int32, path: String, oflag: Int32, flag: UInt32): Int32
功能:打开文件并为其返回新的文件描述符,或在失败时返回 -1。
- 当文件打开方式参数
oflag设置为 O_CREAT 时,可以通过参数设置文件权限。 - O_RDONLY、O_RDWR、O_WRONLY 作为
oflag取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 路径的文件描述符。
- path: String - 文件路径。
- oflag: Int32 - 文件打开的方式。
- flag: UInt32 - 如果
oflag设置了 O_CREAT 并且需要创建新文件,则flag参数标识对新文件的权限,否则flag不改变文件权限。
返回值:
- Int32 - 返回新的文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func openat64(Int32, String, Int32) (deprecated)
public func openat64(fd: Int32, path: String, oflag: Int32): Int32
功能:打开文件并为其返回新的文件描述符,或在失败时返回 -1。
- 当文件打开方式参数
oflag设置为 O_CREAT 时,可以通过参数设置文件权限。 - O_RDONLY、O_RDWR、O_WRONLY 作为
oflag取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 返回新的文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func openat64(Int32, String, Int32, UInt32) (deprecated)
public func openat64(fd: Int32, path: String, oflag: Int32, flag: UInt32): Int32
功能:打开文件并为其返回新的文件描述符,或在失败时返回 -1。
- 当文件打开方式参数
oflag设置为 O_CREAT 时,可以通过参数设置文件权限。 - O_RDONLY、O_RDWR、O_WRONLY 作为
oflag取值为互斥关系,但可以与其他操作标识一起使用,如 O_APPEND 。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 路径的文件描述符。
- path: String - 文件路径。
- oflag: Int32 - 文件打开的方式。
- flag: UInt32 - 如果
oflag设置了 O_CREAT 并且需要创建新文件,则flag参数标识对新文件的权限,否则flag不改变文件权限。
返回值:
- Int32 - 返回新的文件描述符,执行失败时返回
-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func pread(Int32, CPointer<UInt8>, UIntNative, Int32) (deprecated)
public unsafe func pread(fd: Int32, buffer: CPointer<UInt8>, nbyte: UIntNative, offset: Int32): IntNative
功能:将 fd 指向的文件的 nbyte 字节传输到 buffer 指向的内存中。如果 nbyte 为 0,则函数无效果,并返回 0。返回值是实际读取的字节数。返回值为 0 表示到达文件末尾或无法读取数据。此外,文件的读写位置随着读取字节的变化而变化。
建议 nbyte 的大小与 buffer 的大小相同,且 buffer 的大小小于或等于 150000 字节。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 待读取文件的文件描述符。
- buffer: CPointer<UInt8> - 缓冲区容器。
- nbyte: UIntNative - 读取字节数,建议采用
buffer.size。 - offset: Int32 - 读取位置的偏移量。
返回值:
- IntNative - 返回实际读取字节数,读取无效时返回
-1。
func pwrite(Int32, CPointer<UInt8>, UIntNative, Int32) (deprecated)
public unsafe func pwrite(fd: Int32, buffer: CPointer<UInt8>, nbyte: UIntNative, offset: Int32): IntNative
功能:将 buffer 指向的内存中 nbyte 字节从指定偏移位置开始写入到 fd 指向的文件。指定文件的读写位置会随之移动。
建议 nbyte 的大小与 buffer 的大小相同,且 buffer 的大小小于或等于 150000 字节。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 待读取文件的文件描述符。
- buffer: CPointer<UInt8> - 缓冲区容器。
- nbyte: UIntNative - 读取字节数,建议采用
buffer.size。 - offset: Int32 - 读取位置的偏移量。
返回值:
- IntNative - 返回实际写入数,执行失败时返回
-1。
func read(Int32, CPointer<UInt8>, UIntNative) (deprecated)
public unsafe func read(fd: Int32, buffer: CPointer<UInt8>, nbyte: UIntNative): IntNative
功能:将 fd 指向的文件的 nbyte 字节传输到 buffer 指向的内存中。如果 nbyte 为 0,则函数无效果,并返回 0。返回值是实际读取的字节数。返回值为 0 表示到达文件末尾或无法读取数据。此外,文件的读写位置随着读取字节的变化而变化。
建议 nbyte 的大小与 buffer 的大小相同,且 buffer 的大小小于或等于 150000 字节。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 待读取文件的文件描述符。
- buffer: CPointer<UInt8> - 缓冲区容器。
- nbyte: UIntNative - 读取字节数,建议采用
buffer.size。
返回值:
- IntNative - 返回实际读取字节数,读取无效时返回
-1。
func remove(String) (deprecated)
public func remove(path: String): Int32
功能:删除文件或目录。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func rename(String, String) (deprecated)
public func rename(oldName: String, newName: String): Int32
功能:重命名文件,如果需要将会移动文件所在目录。文件的任何其他硬链接不受影响。旧路径打开的文件描述符也不受影响。
各种限制将决定重命名操作是否成功,具体场景如下:
- 如果
newName已经存在,它将被原子替换,这样另一个尝试访问newName的进程就不会发现它丢失,但是可能会有一个窗口,其中旧路径和新路径都引用要重命名的文件。 - 如果旧路径和新路径是引用同一文件的现有硬链接,则重命名不做任何操作,并返回成功状态。
- 如果
newName存在,但操作因某种原因失败,则重命名保证保留newName的实例。 oldName可以指定目录。在这种情况下,newName必须不存在,或者它必须指定空目录。- 如果旧路径引用符号链接,则链接将重命名;如果新路径引用符号链接,则链接将被覆盖。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
oldName或newName包含空字符时,抛出异常。
func renameat(Int32, String, Int32, String) (deprecated)
public func renameat(oldfd: Int32, oldName: String, newfd: Int32, newName: String): Int32
功能:重命名文件,如果需要将会移动文件所在目录。
renameat() 与 rename() 处理相同,此处仅描述两者差异点:
oldName为相对路径且oldfd为特殊值AT_FDCWD时,则路径将相对于调用进程的当前工作目录。oldName为相对路径且oldfd非AT_FDCWD时,则路径将相对于oldfd引用的文件所属目录。oldName为绝对路径时oldfd参数将被忽略。newName的场景与oldName相同,只是当newName为相对路径时是相对于newfd引用的文件所属目录。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
oldName或newName包含空字符时,抛出异常。
func setgid(UInt32) (deprecated)
public func setgid(id: UInt32): Int32
功能:设置调用进程的有效组 ID,需要适当的权限。
注意:
未来版本即将废弃。
参数:
- id: UInt32 - 调用进程的有效组
ID号。
返回值:
- Int32 - 设置成功,返回
0,设置失败, 返回-1。
func sethostname(String) (deprecated)
public func sethostname(buf: String): Int32
功能:设置主机名,仅超级用户可以调用。
注意:
未来版本即将废弃。
参数:
- buf: String - 需要设置的主机名。
返回值:
- Int32 - 设置成功,返回
0,设置失败, 返回-1。
异常:
- IllegalArgumentException - 如果参数
buf包含空字符则抛出异常。
func setpgid(Int32, Int32) (deprecated)
public func setpgid(pid: Int32, pgrp: Int32): Int32
功能:此函数将参数 pid 指定的组 ID 设置为参数 pgrp 指定的组 ID。 如果 pid 为 0,则使用当前进程的组 ID。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 执行成功,返回组
ID,执行失败, 返回-1。
func setpgrp() (deprecated)
public func setpgrp(): Int32
功能:将当前进程所属的组 ID 设置为当前进程的进程 ID,此函数等同于调用 setpgid(0, 0)。
注意:
未来版本即将废弃。
返回值:
- Int32 - 执行成功,返回当前进程的组
ID,执行失败, 返回-1。
func setuid(UInt32) (deprecated)
public func setuid(id: UInt32): Int32
功能:设置调用进程的有效用户 ID,需要适当的权限。
注意:
未来版本即将废弃。
参数:
- id: UInt32 - 调用进程的有效用户
ID号。
返回值:
- Int32 - 设置成功,返回
0,设置失败, 返回-1。
func symlink(String, String) (deprecated)
public func symlink(path: String, symPath: String): Int32
功能:创建一个名为 symPath 链接到 path 所指定的文件。
- 符号链接在运行时被解释为链接的内容已被替换到要查找文件或目录的路径中。
- 符号链接可能包含..路径组件,这些组件(如果在链接的开头使用)引用链接所在目录的父目录。
- 符号链接(也称为软链接)可以指向现有文件或不存在的文件,后者被称为悬空链接。
- 符号链接的权限是不相关的,在跟踪链接时,所有权将被忽略,但当请求删除或重命名链接并且链接位于设置了粘滞位的目录中时,所有权将被检查。
- 如果 symPath 已存在,则不会被覆盖。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
path或symPath包含空字符时,抛出异常。
func symlinkat(String, Int32, String) (deprecated)
public func symlinkat(path: String, fd: Int32, symPath: String): Int32
功能:创建一个名为 symPath 链接到 path 与 fd 所指定的文件。
symPath为相对路径且fd为特殊值AT_FDCWD时,则路径将相对于调用进程的当前工作目录。symPath为相对路径且fd非AT_FDCWD时,则路径将相对于fd引用的文件所属目录。symPath为绝对路径时fd参数将被忽略。
注意:
未来版本即将废弃。
参数:
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
path或symPath包含空字符时,抛出异常。
func ttyname(Int32) (deprecated)
public func ttyname(fd: Int32): String
功能:返回终端名称。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
返回值:
- String - 操作成功时返回路径名,失败时,返回
NULL。
func umask(UInt32) (deprecated)
public func umask(cmask: UInt32): UInt32
功能:设置权限掩码。
注意:
未来版本即将废弃。
参数:
- cmask: UInt32 - 文件权限参数。
返回值:
- UInt32 - 返回文件上一个掩码的值。
func unlink(String) (deprecated)
public func unlink(path: String): Int32
功能:从文件系统中删除文件。
- 如果
path是指向文件的最后一个链接,并且没有进程打开该文件,则该文件将被删除,它使用的空间可供重复使用。 - 如果
path是指向文件的最后一个链接,但仍然有进程打开该文件,该文件将一直存在,直到引用它的最后一个文件描述符关闭。 - 如果
path引用了符号链接,则该链接将被删除。 - 如果
path引用了套接字、FIFO 或设备,则该文件将被删除,但打开对象的进程可能会继续使用它。
注意:
未来版本即将废弃。
参数:
- path: String - 文件路径。
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func unlinkat(Int32, String, Int32) (deprecated)
public func unlinkat(fd: Int32, path: String, ulflag: Int32): Int32
功能:从文件系统中删除文件。
该函数系统调用的操作方式与 unlink 函数完全相同,但此处描述的差异除外:
path为相对路径且fd为特殊值AT_FDCWD时,则路径将相对于调用进程的当前工作目录。path为相对路径且fd非AT_FDCWD时,则路径将相对于fd引用的文件所属目录。path为绝对路径时fd参数将被忽略。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 文件描述符。
- path: String - 文件路径。
- ulflag: Int32 - 可以指定为
0,或者可以设置为控制 unlinkat() 操作的标志值按位或运算。标志值当前取值仅支持 AT_REMOVEDIR。
返回值:
- Int32 - 成功返回
0,错误返回-1。
异常:
- IllegalArgumentException - 当函数参数
path包含空字符时,抛出异常。
func write(Int32, CPointer<UInt8>, UIntNative) (deprecated)
public unsafe func write(fd: Int32, buffer: CPointer<UInt8>, nbyte: UIntNative): IntNative
功能:将 buffer 指向的内存中 nbyte 字节写入到 fd 指向的文件。指定文件的读写位置会随之移动。
建议 nbyte 的大小与 buffer 的大小相同,且 buffer 的大小小于或等于 150000 字节。
注意:
未来版本即将废弃。
参数:
- fd: Int32 - 待写入文件的文件描述符。
- buffer: CPointer<UInt8> - 缓冲区容器。
- nbyte: UIntNative - 读取字节数,建议采用
buffer.size。
返回值:
- IntNative - 返回实际读取字节数,读取无效时返回
-1。
文件内容相关操作
下面是文件内容相关操作示例。
代码如下:
import std.posix.*
main(): Int64 {
var fd = `open`("textcase.txt", O_RDWR | O_APPEND | O_CREAT, S_IRWXU)
println("fd ==> ${fd}")
close(fd)
var fd2 = `open`("textcase.txt", O_RDWR)
var len = lseek(fd2, 0, SEEK_END)
println("len ==> ${len}")
close(fd2)
var str1 = unsafe{LibC.mallocCString(" ")}
var buf = str1.getChars()
var fd3 = `open`("textcase.txt", O_RDWR)
var readNum = unsafe { read(fd3, buf, 2) }
unsafe{ LibC.free(str1)}
println("readNum ==> ${readNum}")
close(fd3)
var str2 = unsafe{LibC.mallocCString("123456")}
var buf2 = str2.getChars()
var fd4 = `open`("textcase.txt", O_RDWR)
var fd5 = dup(fd4)
var writeNum = unsafe { write(fd5, buf2, UIntNative(str2.size())) }
unsafe { LibC.free(str2)}
println("writeNum ==> ${writeNum}")
close(fd4)
return 0
}
可能出现的运行结果:
fd ==> 3
len ==> 6
readNum ==> 2
writeNum ==> 6
文件信息相关操作
下面是文件信息相关操作示例,以下示例支持 Linux 平台,其他平台支持情况见本包概述。
代码如下:
import std.posix.*
main(): Int64 {
var result1: Bool = isType("/notdirs", S_IFDIR)
println("result ==> ${result1}")
var result2: Bool = isDir("/dev")
println("result ==> ${result2}")
var result3 = access("./oscfg.cfg", F_OK)
println("result ==> ${result3}")
var result4 = chmod("oscfg.cfg", UInt32(S_IXUSR))
println("result ==> ${result4}")
return 0
}
运行结果:
result ==> false
result ==> true
result ==> -1
result ==> -1
获取各类系统信息
下面是获取各类系统信息示例,以下示例支持 Linux 平台,其他平台支持情况见本包概述。
代码如下:
import std.posix.*
main(): Int64 {
/* 系统名称相关 */
var os_info = getos()
println("os info ==> ${os_info}")
var hostname = gethostname()
println("hostname ==> ${hostname}")
var logname: String = getlogin()
println("logname ==> ${logname}")
/* 程序运行路径相关函数 */
var changePath = "/"
var chdir_result = chdir(changePath)
println("chdir_result ==> ${chdir_result}")
var cwd_path: String = getcwd()
println("cwd_path ==> ${cwd_path}")
/* 系统 id 相关函数 getpgid */
var arr: CString = unsafe { LibC.mallocCString(" ") }
var a: CPointer<UInt8> = arr.getChars()
var cp: CPointer<UInt32> = CPointer<UInt32>(a)
var getg = unsafe{ getgroups(0, cp)}
var s: String = " "
for (_ in 0..getg) {
s = s + "\0"
}
println(getg)
var local: UInt32 = 0
for (temp in 0..getg) {
unsafe { local = cp.read(Int64(temp)) }
println("getgroups ==> ${local.toString()}")
}
unsafe { LibC.free(arr)}
return 0
}
运行结果如下(根据系统不同返回结果可能不同):
Linux version 4.15.0-159-generic (buildd@lgw01-amd64-055) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #167-Ubuntu SMP Tue Sep 21 08:55:05 UTC 2021
hostname ==> e124e6e0fe0f
logname ==> root
chdir_result ==> 0
cwd_path ==> /
1
getgroups ==> 1309868064
进程相关信息操作
下面是进程相关信息操作示例,以下示例支持 Linux 平台,其他平台支持情况见本包概述。
代码如下:
import std.posix.*
main(): Int64 {
var result = nice(200)
print("${result}")
var result1 = kill(0, SIGCHLD)
println(result1)
var result2 = killpg(0, SIGURG)
println("result ==> ${result2}")
if (isatty(0) && isatty(1) && isatty(2)) {
print("true01 ")
} else {
print("false01 ")
}
if (isatty(-23) || isatty(4) || isatty(455) || isatty(43332)) {
print("true02 ")
} else {
println("false02")
}
return 0
}
运行结果:
190
result ==> 0
true01 false02
std.process
功能介绍
process 包主要提供 Process 进程操作接口,主要包括进程创建,标准流获取,进程等待,进程信息查询等。
本包提供多平台统一操控能力,目前支持 Linux 平台,macOS 平台与 Windows 平台。
API 列表
函数
| 函数名 | 功能 |
|---|---|
| execute | 根据输入参数创建并运行一个子进程,等待该子进程运行完毕并返回子进程退出状态。 |
| executeWithOutput | 根据输入参数创建并运行一个子进程,等待该子进程运行完毕并返回子进程退出状态、标准输出和标准错误。 |
| findProcess | 根据输入进程 id 绑定一个进程实例。 |
| launch | 根据输入参数创建并运行一个子进程,并返回一个子进程实例。 |
类
| 类名 | 功能 |
|---|---|
| CurrentProcess (deprecated) | 此类为当前进程类,继承 Process 类,提供对当前进程操作相关功能。 |
| Process | 此类为进程类,提供进程操作相关功能。 |
| SubProcess | 此类为子进程类,继承 Process 类,提供对子进程操作相关功能。 |
枚举
| 枚举名 | 功能 |
|---|---|
| ProcessRedirect | 用于在创建进程时设置子进程标准流的重定向模式。 |
异常类
| 异常类名 | 功能 |
|---|---|
| ProcessException | process 包的异常类。 |
兼容性说明
class Process
| 成员 | 支持平台 |
|---|---|
| current (deprecated) | Linux Windows macOS |
| pid | Linux Windows macOS |
| name | Linux Windows macOS |
| command | Linux Windows macOS |
| arguments (deprecated) | Linux macOS |
| commandLine (deprecated) | Linux macOS |
| environment (deprecated) | Linux |
| workingDirectory (deprecated) | Linux macOS |
| of(Int64) (deprecated) | Linux Windows macOS |
| start(String, Array<String>, Path, Map<String, String>, ProcessRedirect, ProcessRedirect, ProcessRedirect) (deprecated) | Linux Windows macOS |
| run(String, Array<String>, Path, Map<String, String>, ProcessRedirect, ProcessRedirect, ProcessRedirect, Duration) (deprecated) | Linux Windows macOS |
| runOutput(String, Array<String>, Path, Map<String, String>, ProcessRedirect, ProcessRedirect, ProcessRedirect) (deprecated) | Linux Windows macOS |
| terminate(Bool) | Linux Windows macOS |
class CurrentProcss (deprecated)
注意:
未来版本即将废弃,可在 std.env 中找到代替功能。
| 成员 | 支持平台 |
|---|---|
| arguments | Linux Windows macOS |
| homeDirectory | Linux Windows macOS |
| tempDirectory | Linux Windows macOS |
| stdIn | Linux Windows macOS |
| stdOut | Linux Windows macOS |
| stdErr | Linux Windows macOS |
| atExit(() -> Unit) | Linux Windows macOS |
| exit(Int64) | Linux Windows macOS |
| getEnv(String) | Linux Windows macOS |
| removeEnv(String) | Linux Windows macOS |
| setEnv(String, String) | Linux Windows macOS |
class SubProcess
| 成员 | 支持平台 |
|---|---|
| stdIn (deprecated) | Linux Windows macOS |
| stdInPipe | Linux Windows macOS |
| stdOut (deprecated) | Linux Windows macOS |
| stdOutPipe | Linux Windows macOS |
| stdErr (deprecated) | Linux Windows macOS |
| stdErrPipe | Linux Windows macOS |
| wait(Duration) | Linux Windows macOS |
| waitOutput() | Linux Windows macOS |
函数
func execute(String, Array<String>, ?Path, ?Map<String, String>, ProcessRedirect, ProcessRedirect,ProcessRedirect, ?Duration)
public func execute(command: String,
arguments: Array<String>,
workingDirectory!: ?Path = None,
environment!: ?Map<String, String> = None,
stdIn!: ProcessRedirect = Inherit,
stdOut!: ProcessRedirect = Inherit,
stdErr!: ProcessRedirect = Inherit,
timeout!: ?Duration = None): Int64
功能:根据输入参数创建并运行一个子进程,等待该子进程运行完毕并返回子进程退出状态。
注意:
- 在
Windows平台上,在子进程执行完成后立即删除子进程的可执行文件可能删除失败并抛出异常,异常信息为Access is denied,如果遇到该问题,可以在一小段延迟后重新尝试删除该文件,详细实现可参考示例。
参数:
- command: String - 指定子进程命令,
command不允许包含空字符。 - arguments: Array<String> - 指定子进程参数,
arguments不允许数组中字符串中包含空字符。 - workingDirectory!: ?Path - 命名可选参数,指定子进程的工作路径,默认继承当前进程工作路径,路径必须为存在的目录且不允许为空路径或包含空字符。
- environment!: ?Map<String, String> - 命名可选参数,指定子进程环境变量,默认继承当前进程环境变量,
key不允许字符串中包含空字符或'=',value 不允许字符串中包含空字符。 - stdIn!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输入,默认继承当前进程标准输入。
- stdOut!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输出,默认继承当前进程标准输出。
- stdErr!: ProcessRedirect - 命名可选参数,指定子进程重定向标准错误,默认继承当前进程标准错误。
- timeout!: ?Duration - 命名可选参数,指定等待子进程超时时间,默认为不超时,
timeout指定为0或负值时表示不超时。
返回值:
- Int64 - 返回子进程退出状态,若子进程正常退出,返回子进程退出码,若子进程被信号杀死,返回导致子进程终止的信号编号。
异常:
-
- 当入参
command包含空字符 - 或者
arguments数组中字符串中包含空字符 - 或者
workingDirectory不是存在的目录或为空路径或包含空字符 - 或者
environment表中key字符串中包含空字符或'=' - 或者
value字符串中包含空字符 - 或者
stdIn、stdOut、stdErr输入为文件模式,输入的文件已被关闭或删除时,抛出异常。
- 当入参
-
ProcessException - 当内存分配失败或
command对应的命令不存在或等待超时,抛出异常。
func executeWithOutput(String, Array<String>, ?Path, ?Map<String, String>, ProcessRedirect, ProcessRedirect, ProcessRedirect)
public func executeWithOutput(command: String,
arguments: Array<String>,
workingDirectory!: ?Path = None,
environment!: ?Map<String, String> = None,
stdIn!: ProcessRedirect = Inherit,
stdOut!: ProcessRedirect = Pipe,
stdErr!: ProcessRedirect = Pipe): (Int64, Array<Byte>, Array<Byte>)
功能:根据输入参数创建并运行一个子进程,等待该子进程运行完毕并返回子进程退出状态、标准输出和标准错误。输出流、错误流中包含大量输出的场景不适用于本函数,建议通过 SubProcess 中提供的标准流属性结合 wait 函数自行处理。
参数:
- command: String - 指定子进程命令,
command不允许包含空字符。 - arguments: Array<String> - 指定子进程参数,
arguments不允许数组中字符串中包含空字符。 - workingDirectory!: ?Path - 命名可选参数,指定子进程的工作路径,默认继承当前进程工作路径,路径必须为存在的目录且不允许为空路径或包含空字符。
- environment!: ?Map<String, String> - 命名可选参数,指定子进程环境变量,默认继承当前进程环境变量,
key不允许字符串中包含空字符或'=',value 不允许字符串中包含空字符。 - stdIn!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输入,默认继承当前进程标准输入。
- stdOut!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输出,默认继承当前进程标准输出。
- stdErr!: ProcessRedirect - 命名可选参数,指定子进程重定向标准错误,默认继承当前进程标准错误。
返回值:
- (Int64, Array<Byte>, Array<Byte>) - 子进程执行返回结果,包含子进程退出状态(若子进程正常退出,返回子进程退出码,若子进程被信号杀死,返回导致子进程终止的信号编号),进程标准输出结果和进程错误结果。
异常:
- IllegalArgumentException
- 当入参
command包含空字符 - 或者
arguments数组中字符串中包含空字符 - 或者
workingDirectory不是存在的目录或为空路径或包含空字符 - 或者
environment表中key字符串中包含空字符或'=' - 或者
value字符串中包含空字符 - 或者
stdIn、stdOut、stdErr输入为文件模式,输入的文件已被关闭或删除时,抛出异常。
- 当入参
- ProcessException
- 当内存分配失败
- 或者
command对应的命令不存在 - 或者子进程不存在
- 或者标准流读取异常时,抛出异常。
func findProcess(Int64)
public func findProcess(pid: Int64): Process
功能:根据输入进程 id 绑定一个进程实例。
参数:
- pid: Int64 - 进程
id。
返回值:
- Process - 返回进程
id对应的进程实例。
异常:
- IllegalArgumentException - 当输入进程
id大于 Int32 最大值或小于0时,抛出异常。 - ProcessException - 当内存分配失败或
pid对应的进程不存在时,抛出异常。
func launch(String, Array<String>, ?Path, ?Map<String, String>, ProcessRedirect, ProcessRedirect, ProcessRedirect)
public func launch(command: String,
arguments: Array<String>,
workingDirectory!: ?Path = None,
environment!: ?Map<String, String> = None,
stdIn!: ProcessRedirect = Inherit,
stdOut!: ProcessRedirect = Inherit,
stdErr!: ProcessRedirect = Inherit): SubProcess
功能:根据输入参数创建并运行一个子进程,并返回一个子进程实例。调用该函数创建子进程后,需要调用 wait 或 waitOutput 函数,否则该子进程结束后成为的僵尸进程的资源不会被回收。
参数:
- command: String - 指定子进程命令,
command不允许包含空字符。 - arguments: Array<String> - 指定子进程参数,
arguments不允许数组中字符串中包含空字符。 - workingDirectory!: ?Path - 命名可选参数,指定子进程的工作路径,默认继承当前进程工作路径,路径必须为存在的目录且不允许为空路径或包含空字符。
- environment!: ?Map<String, String> - 命名可选参数,指定子进程环境变量,默认继承当前进程环境变量,
key不允许字符串中包含空字符或'=',value 不允许字符串中包含空字符。 - stdIn!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输入,默认继承当前进程标准输入。
- stdOut!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输出,默认继承当前进程标准输出。
- stdErr!: ProcessRedirect - 命名可选参数,指定子进程重定向标准错误,默认继承当前进程标准错误。
返回值:
- SubProcess - 返回一个子进程实例。
异常:
- IllegalArgumentException
- 当入参
command包含空字符 - 或者
arguments数组中字符串中包含空字符 - 或者
workingDirectory不是存在的目录或为空路径或包含空字符 - 或者
environment表中key字符串中包含空字符或'=' - 或者
value字符串中包含空字符 - 或者
stdIn、stdOut、stdErr输入为文件模式,输入的文件已被关闭或删除时,抛出异常。
- 当入参
- ProcessException - 当内存分配失败或
command对应的命令不存在时,抛出异常。
类
class CurrentProcess (deprecated)
public class CurrentProcess <: Process
功能:此类为当前进程类,继承 Process 类,提供对当前进程操作相关功能。
提供功能具体如下:
- 提供获取当前进程标准流(
stdIn、stdOut、stdErr)机制。 - 提供当前进程退出注册回调函数机制。
- 提供当前进程退出机制,允许设置退出状态码。
注意:
未来版本即将废弃。
父类型:
prop arguments
public prop arguments: Array<String>
功能:返回当前进程参数列表,例如当前进程命令行为 a.out ab cd ef,其中 a.out 是程序名,则返回的列表包含三个元素 ab cd ef。
说明:
- 使用 C 语言调用仓颉动态库方式时,通过 int SetCJCommandLineArgs(int argc, const char* argv[]) 设置的命令行参数,在使用当前进程的
arguments获取时,将会被舍弃掉第一个参数。
prop homeDirectory
public prop homeDirectory: Path
功能:获取 home 目录的路径。
类型:Path
prop stdErr
public prop stdErr: OutputStream
功能:获取当前进程标准错误流。
类型:OutputStream
prop stdIn
public prop stdIn: InputStream
功能:获取当前进程标准输入流。
类型:InputStream
prop stdOut
public prop stdOut: OutputStream
功能:获取当前进程标准输出流。
类型:OutputStream
prop tempDirectory
public prop tempDirectory: Path
功能:获取临时目录的路径。从环境变量中获取 TMPDIR、TMP、TEMP 和 TEMPDIR 环境变量。如果以上值在环境变量中均不存在,则默认返回 /tmp 目录。
类型:Path
func atExit(() -> Unit)
public func atExit(callback: () -> Unit): Unit
功能:注册回调函数,当前进程退出时执行注册函数。
注意:
请不要使用C语言 atexit 函数,避免出现不可期问题。
参数:
- callback: () ->Unit - 需要被注册回调的函数。
func exit(Int64)
public func exit(code: Int64): Nothing
功能:进程退出函数,执行到此函数直接结束当前进程,并且通过入参 code 设置返回状态码。
参数:
- code: Int64 - 当前进程退出状态码。
func getEnv(String)
public func getEnv(k: String): Option<String>
功能:获取指定名称的环境变量值。
参数:
- k: String - 环境变量名称。
返回值:
异常:
- IllegalArgumentException - 当函数参数
k包含空字符时,抛出异常。
func removeEnv(String)
public func removeEnv(k: String): Unit
功能:通过指定环境变量名称移除环境变量。
参数:
- k: String - 环境变量名称。
异常:
- IllegalArgumentException - 当函数参数
k包含空字符时,抛出异常。
func setEnv(String, String)
public func setEnv(k: String, v: String): Unit
功能:用于设置一对环境变量。如果设置了同名环境变量,原始环境变量值将被覆盖。
说明:
Windows 下如果传入的参数 v 是空字符串,那么会从环境中移除变量 k。
参数:
异常:
- IllegalArgumentException - 当函数参数
k或v中包含空字符时,抛出异常。
class Process
public open class Process
功能:此类为进程类,提供进程操作相关功能。
说明:
提供功能具体如下:
- 提供获取当前进程实例的功能。
- 提供根据进程
id绑定进程实例的功能。- 提供根据输入信息创建子进程的功能。
- 提供获取进程信息的功能。
- 提供关闭进程的功能,允许设置是否强制关闭进程。
static prop current (deprecated)
public static prop current: CurrentProcess
功能:获取当前进程实例。
注意:
未来版本即将废弃,使用 env 包的全局函数替代。
prop arguments (deprecated)
public open prop arguments: Array<String>
功能:获取进程参数。Windows 平台下无法在非特权 API 下获取到本属性,暂不支持获取。
注意:
未来版本即将废弃。
异常:
- ProcessException - 当进程不存在或对应进程为僵尸进程,或在
Windows平台下暂不支持场景,无法获取进程参数时,抛出异常。
prop command
public prop command: String
功能:获取进程命令。
类型:String
异常:
- ProcessException - 当进程不存在或对应进程为僵尸进程,无法获取进程命令时,抛出异常。
prop commandLine (deprecated)
public prop commandLine: Array<String>
功能:获取进程命令行。Windows 平台当前进程可获取,其他场景下无法在非特权 API 下获取到本属性,暂不支持获取。
注意:
未来版本即将废弃,使用 getcommandline() 替代。
异常:
- ProcessException - 当进程不存在或对应进程为僵尸进程,或在
Windows平台下暂不支持场景,无法获取进程命令行时,抛出异常。
prop environment (deprecated)
public prop environment: Map<String, String>
功能:获取进程环境变量。Windows 平台当前进程可获取,其他场景下无法在非特权 API 下获取到本属性,暂不支持获取。
注意:
未来版本即将废弃,使用 getVariables() 替代。
异常:
- ProcessException - 当进程不存在或对应进程为僵尸进程,或在
Windows平台下暂不支持场景,无法获取进程环境变量时,抛出异常。
prop name
public prop name: String
功能:获取进程名。
类型:String
异常:
- ProcessException - 当进程不存在或对应进程为僵尸进程,无法获取进程名时,抛出异常。
prop pid
public prop pid: Int64
功能:获取进程 id。
类型:Int64
prop startTime
public prop startTime: DateTime
功能:获取进程启动时间,获取失败时返回 DateTime.UnixEpoch。
类型:DateTime
prop systemTime
public prop systemTime: Duration
功能:获取进程启动时间,获取失败时返回 -1ms。
类型:Duration
prop userTime
public prop userTime: Duration
功能:获取进程启动时间,获取失败时返回 -1ms。
类型:Duration
prop workingDirectory (deprecated)
public prop workingDirectory: Path
功能:获取进程工作路径。Windows 平台当前进程可获取,其他场景下无法在非特权 API 下获取到本属性,暂不支持获取。
注意:
未来版本即将废弃,使用 getHomeDirectory() 替代。
类型:Path
异常:
- ProcessException - 当进程不存在或对应进程为僵尸进程,或在
Windows平台下暂不支持场景,无法获取进程工作路径时,抛出异常。
func isAlive()
public func isAlive(): Bool
功能:返回进程是否存活。
返回值:
- Bool - 进程存活则为
true,否则为false
static func of(Int64) (deprecated)
public static func of(pid: Int64): Process
功能:根据输入进程 id 绑定一个进程实例。
注意:
未来版本即将废弃,使用 findProcess 替代。
参数:
- pid: Int64 - 进程
id。
返回值:
- Process - 返回进程
id对应的进程实例。
异常:
- IllegalArgumentException - 当输入进程
id大于 Int32 最大值或小于0时,抛出异常。 - ProcessException - 当内存分配失败或
pid对应的进程不存在时,抛出异常。
static func run(String, Array<String>, ?Path, ?Map<String, String>, ProcessRedirect, ProcessRedirect,ProcessRedirect, ?Duration) (deprecated)
public static func run(command: String,
arguments: Array<String>,
workingDirectory!: ?Path = None,
environment!: ?Map<String, String> = None,
stdIn!: ProcessRedirect = Inherit,
stdOut!: ProcessRedirect = Inherit,
stdErr!: ProcessRedirect = Inherit,
timeout!: ?Duration = None): Int64
功能:根据输入参数创建并运行一个子进程,等待该子进程运行完毕并返回子进程退出状态。
注意:
- 未来版本即将废弃,使用 execute 替代。
- 在
Windows平台上,在子进程执行完成后立即删除子进程的可执行文件可能删除失败并抛出异常,异常信息为Access is denied,如果遇到该问题,可以在一小段延迟后重新尝试删除该文件,详细实现可参考示例。
参数:
- command: String - 指定子进程命令,
command不允许包含空字符。 - arguments: Array<String> - 指定子进程参数,
arguments不允许数组中字符串中包含空字符。 - workingDirectory!: ?Path - 命名可选参数,指定子进程的工作路径,默认继承当前进程工作路径,路径必须为存在的目录且不允许为空路径或包含空字符。
- environment!: ?Map<String, String> - 命名可选参数,指定子进程环境变量,默认继承当前进程环境变量,
key不允许字符串中包含空字符或'=',value 不允许字符串中包含空字符。 - stdIn!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输入,默认继承当前进程标准输入。
- stdOut!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输出,默认继承当前进程标准输出。
- stdErr!: ProcessRedirect - 命名可选参数,指定子进程重定向标准错误,默认继承当前进程标准错误。
- timeout!: ?Duration - 命名可选参数,指定等待子进程超时时间,默认为不超时,
timeout指定为0或负值时表示不超时。
返回值:
- Int64 - 返回子进程退出状态,若子进程正常退出,返回子进程退出码,若子进程被信号杀死,返回导致子进程终止的信号编号。
异常:
- IllegalArgumentException - 当入参
command包含空字符,或者arguments数组中字符串中包含空字符,或者workingDirectory不是存在的目录或为空路径或包含空字符,或者environment表中key字符串中包含空字符或'=',或value字符串中包含空字符,或者stdIn、stdOut、stdErr输入为文件模式,输入的文件已被关闭或删除时,抛出异常。 - ProcessException - 当内存分配失败或
command对应的命令不存在或等待超时,抛出异常。
static func runOutput(String, Array<String>, ?Path, ?Map<String, String>, ProcessRedirect, ProcessRedirect, ProcessRedirect) (deprecated)
public static func runOutput(command: String,
arguments: Array<String>,
workingDirectory!: ?Path = None,
environment!: ?Map<String, String> = None,
stdIn!: ProcessRedirect = Inherit,
stdOut!: ProcessRedirect = Pipe,
stdErr!: ProcessRedirect = Pipe): (Int64, Array<Byte>, Array<Byte>)
功能:根据输入参数创建并运行一个子进程,等待该子进程运行完毕并返回子进程退出状态、标准输出和标准错误。输出流、错误流中包含大量输出的场景不适用于本函数,建议通过 SubProcess 中提供的标准流属性结合 wait 函数自行处理。
注意:
未来版本即将废弃,使用 executeWithOutput 替代。
参数:
- command: String - 指定子进程命令,
command不允许包含空字符。 - arguments: Array<String> - 指定子进程参数,
arguments不允许数组中字符串中包含空字符。 - workingDirectory!: ?Path - 命名可选参数,指定子进程的工作路径,默认继承当前进程工作路径,路径必须为存在的目录且不允许为空路径或包含空字符。
- environment!: ?Map<String, String> - 命名可选参数,指定子进程环境变量,默认继承当前进程环境变量,
key不允许字符串中包含空字符或'=',value 不允许字符串中包含空字符。 - stdIn!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输入,默认继承当前进程标准输入。
- stdOut!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输出,默认继承当前进程标准输出。
- stdErr!: ProcessRedirect - 命名可选参数,指定子进程重定向标准错误,默认继承当前进程标准错误。
返回值:
- (Int64, Array<Byte>, Array<Byte>) - 子进程执行返回结果,包含子进程退出状态(若子进程正常退出,返回子进程退出码,若子进程被信号杀死,返回导致子进程终止的信号编号),进程标准输出结果和进程错误结果。
异常:
- IllegalArgumentException - 当入参
command包含空字符,或者arguments数组中字符串中包含空字符,或者workingDirectory不是存在的目录或为空路径或包含空字符,或者environment表中key字符串中包含空字符或'=',或value字符串中包含空字符,或者stdIn、stdOut、stdErr输入为文件模式,输入的文件已被关闭或删除时,抛出异常。 - ProcessException - 当内存分配失败,或者
command对应的命令不存在,或者子进程不存在,或者标准流读取异常时,抛出异常。
static func start(String, Array<String>, ?Path, ?Map<String, String>, ProcessRedirect, ProcessRedirect, ProcessRedirect) (deprecated)
public static func start(command: String,
arguments: Array<String>,
workingDirectory!: ?Path = None,
environment!: ?Map<String, String> = None,
stdIn!: ProcessRedirect = Inherit,
stdOut!: ProcessRedirect = Inherit,
stdErr!: ProcessRedirect = Inherit): SubProcess
功能:根据输入参数创建并运行一个子进程,并返回一个子进程实例。调用该函数创建子进程后,需要调用 wait 或 waitOutput 函数,否则该子进程结束后成为的僵尸进程的资源不会被回收。
注意:
未来版本即将废弃,使用 launch 替代。
参数:
- command: String - 指定子进程命令,
command不允许包含空字符。 - arguments: Array<String> - 指定子进程参数,
arguments不允许数组中字符串中包含空字符。 - workingDirectory!: ?Path - 命名可选参数,指定子进程的工作路径,默认继承当前进程工作路径,路径必须为存在的目录且不允许为空路径或包含空字符。
- environment!: ?Map<String, String> - 命名可选参数,指定子进程环境变量,默认继承当前进程环境变量,
key不允许字符串中包含空字符或'=',value 不允许字符串中包含空字符。 - stdIn!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输入,默认继承当前进程标准输入。
- stdOut!: ProcessRedirect - 命名可选参数,指定子进程重定向标准输出,默认继承当前进程标准输出。
- stdErr!: ProcessRedirect - 命名可选参数,指定子进程重定向标准错误,默认继承当前进程标准错误。
返回值:
- SubProcess - 返回一个子进程实例。
异常:
- IllegalArgumentException - 当入参
command包含空字符,或者arguments数组中字符串中包含空字符,或者workingDirectory不是存在的目录或为空路径或包含空字符,或者environment表中key字符串中包含空字符或'=',或value字符串中包含空字符,或者stdIn、stdOut、stdErr输入为文件模式,输入的文件已被关闭或删除时,抛出异常。 - ProcessException - 当内存分配失败或
command对应的命令不存在时,抛出异常。
func terminate(Bool)
public func terminate(force!: Bool = false): Unit
功能:终止进程,子进程执行返回结果,包含子进程退出状态(若子进程正常退出,返回子进程退出码,若子进程被信号杀死,返回导致子进程终止的信号编号),进程标准输出结果和进程错误结果。
参数:
- force!: Bool - 命名可选参数,指定是否强制关闭进程,默认为
false,若设置为false,对应进程可以在释放资源后结束;若设置为true,对应进程将被直接杀死。Windows平台实现为强制关闭进程。
异常:
- ProcessException - 如果进程不存在,不允许终止,则抛出异常。
func terminateAliveProcess(Int32, Bool)
protected open func terminateAliveProcess(pid: Int32, force: Bool): Unit
功能:终止指定进程,子进程执行返回结果,包含子进程退出状态(若子进程正常退出,返回子进程退出码,若子进程被信号杀死,返回导致子进程终止的信号编号),进程标准输出结果和进程错误结果。
参数:
-
pid: Int32 - 需要终止的进程
ID。 -
force!: Bool - 命名可选参数,指定是否强制关闭进程,默认为
false,若设置为false,对应进程可以在释放资源后结束;若设置为true,对应进程将被直接杀死。Windows平台实现为强制关闭进程。
异常:
- ProcessException - 如果进程不存在,不允许终止,则抛出异常。
class SubProcess
public class SubProcess <: Process
功能:此类为子进程类,继承 Process 类,提供对子进程操作相关功能。
说明:
提供功能具体如下:
- 提供获取子进程标准流(
stdIn、stdOut、stdErr)机制。- 提供等待子进程执行返回退出状态码机制,允许设置等待超时时长。
- 提供等待子进程执行返回输出结果(包含运行正常、异常结果)机制,允许设置等待超时时长。
父类型:
prop stdErr (deprecated)
public prop stdErr: InputStream
功能:获取输入流,连接到子进程标准错误流。
注意:
未来版本即将废弃,使用 stdErrPipe 替代。
类型:InputStream
prop stdErrPipe
public prop stdErrPipe: InputStream
功能:获取输入流,连接到子进程标准错误流。
类型:InputStream
prop stdIn (deprecated)
public prop stdIn: OutputStream
功能:获取输出流,连接到子进程标准输入流。
注意:
未来版本即将废弃,使用 stdInPipe 替代。
类型:OutputStream
prop stdInPipe
public prop stdInPipe: OutputStream
功能:获取输出流,连接到子进程标准输入流。
类型:OutputStream
prop stdOut (deprecated)
public prop stdOut: InputStream
功能:获取输入流,连接到子进程标准输出流。
注意:
未来版本即将废弃,使用 stdOutPipe 替代。
类型:InputStream
prop stdOutPipe
public prop stdOutPipe: InputStream
功能:获取输入流,连接到子进程标准输出流。
类型:InputStream
func wait(?Duration)
public func wait(timeout!: ?Duration = None): Int64
功能:阻塞当前进程等待子进程任务执行完成并返回子进程退出状态码,允许指定等待超时时间。对于需要操作标准流的场景(Pipe 模式),使用者需要优先处理标准流,避免子进程标准流缓冲区满后调用本函数产生死锁。
说明:
超时时间处理机制:
参数:
- timeout!: ?Duration - 命名可选参数,设置等待子进程超时时间,默认为
None。
返回值:
- Int64 - 返回子进程退出状态。若子进程正常退出,返回子进程退出码,若子进程被信号杀死,返回导致子进程终止的信号编号。
异常:
- TimeoutException - 当等待超时,子进程未退出时,抛出异常。
func waitOutput()
public func waitOutput(): (Int64, Array<Byte>, Array<Byte>)
功能:阻塞当前进程等待子进程任务执行完成,并返回子进程退出状态码、返回结果(包含输出流和错误流返回结果)。输出流、错误流中包含大量输出的场景不适用于本函数,建议通过 SubProcess 中提供的标准流属性结合 wait 函数自行处理。
返回值:
- (Int64, Array<Byte>, Array<Byte>) - 子进程执行返回结果,包含子进程退出状态(若子进程正常退出,返回子进程退出码,若子进程被信号杀死,返回导致子进程终止的信号编号),进程标准输出结果和进程错误结果。
异常:
- ProcessException - 当子进程不存在,或者标准流读取异常时,抛出异常。
枚举
enum ProcessRedirect
public enum ProcessRedirect {
| Inherit
| Pipe
| FromFile(File)
| Discard
}
功能:该枚举类型用于在创建进程时设置子进程标准流的重定向模式。
Discard
Discard
功能:构造一个标准流重定向枚举实例,表示子进程标准流将被丢弃。此模式下标准流属性不可读取或写入。
FromFile(File)
FromFile(File)
功能:构造一个标准流重定向枚举实例,表示子进程标准流将被重定向至指定的文件。重定向标准输入流将从指定文件读取,重定向标准输出流或标准错误流将写入至指定文件。重定向文件需保证存在且未关闭,否则不允许重定向。此模式下标准流属性不可读取或写入。参数 File 为指定存在且未关闭文件实例,创建子进程时,重定向标准流至该指定文件。
Inherit
Inherit
功能:构造一个标准流重定向枚举实例,表示子进程标准流将继承当前进程的标准流。此模式下标准流属性不可读取或写入。
Pipe
Pipe
功能:构造一个标准流重定向枚举实例,表示子进程标准流将被重定向至管道,并通过管道与当前进程连接。重定向标准输入流可通过管道向子进程写入数据,重定向标准输出流或标准错误流可通过管道读取子进程输出结果。此模式下可通过标准流属性读取或写入数据。
异常
class ProcessException
public class ProcessException <: IOException {
public init(message: String)
}
功能:process 包的异常类。
父类型:
init(String)
public init(message: String)
功能:创建 ProcessException 实例。
参数:
- message: String - 异常提示信息。
任意进程相关操作
下面是任意进程相关操作示例,以下示例不支持 Windows 平台。
代码如下:
import std.process.*
main(): Int64 {
let echoProcess: SubProcess = launch("sleep", "10s")
let ofProcess: Process = findProcess(echoProcess.pid)
println(ofProcess.pid)
println(ofProcess.name)
println(ofProcess.command)
ofProcess.terminate(force: true)
return 0
}
运行结果可能如下:
70753
sleep
sleep
子进程相关操作
下面是子进程相关操作示例,以下示例不支持 Windows 平台。
代码如下:
import std.process.*
import std.io.*
import std.fs.*
// 以Linux平台相关命令举例说明, 以下用例需要提前创建 “/root/code/Process/test” 目录
main(): Int64 {
let sleepProcess: SubProcess = launch("sleep", "10s", workingDirectory: Path("/root/code/Process/test"))
println(sleepProcess.pid)
println(sleepProcess.name)
println(sleepProcess.command)
sleepProcess.terminate(force: true)
let rtnCode = sleepProcess.wait()
println("sleepProcess rtnCode: ${rtnCode}")
let echoProcess: SubProcess = launch("echo", "hello cangjie!", stdOut: ProcessRedirect.Pipe)
let strReader: StringReader<InputStream> = StringReader(echoProcess.stdOutPipe)
println(strReader.readToEnd())
return 0
}
运行结果可能如下:
65953
sleep
sleep
sleepProcess rtnCode: 9
hello cangjie!
std.random
功能介绍
random 包提供生成伪随机数的能力。
API列表
类
| 类名 | 功能 |
|---|---|
| Random | 提供生成伪随机数的相关功能。 |
类
class Random
public class Random {
public init()
public init(seed: UInt64)
}
功能:提供生成伪随机数的相关功能。
示例:
import std.random.*
main() {
/* 创建 Random 对象并设置种子来获取随机对象 */
let m: Random = Random(3)
let b: Bool = m.nextBool()
let c: Int8 = m.nextInt8()
print("b=${b is Bool},")/* 对象也可以是 Bool 类型 */
println("c=${c is Int8}")
return 0
}
运行结果:
b=true,c=true
prop seed
public prop seed: UInt64
功能:获取随机数种子。
类型:UInt64
init()
public init()
功能:默认无参构造函数创建新的 Random 对象。
init(UInt64)
public init(seed: UInt64)
功能:使用随机数种子创建新的 Random 对象。
参数:
- seed: UInt64 - 随机数种子,如果设置相同随机种子,生成的伪随机数列表相同。
func next(UInt64) (deprecated)
public func next(bits: UInt64): UInt64
功能:生成一个用户指定位长的随机整数。
注意:
未来版本即将废弃,使用 nextBits 替代。
参数:
- bits: UInt64 - 要生成的伪随机数的位数,取值范围 (0, 64]。
返回值:
- UInt64 - 用户指定位长的伪随机数。
异常:
- IllegalArgumentException - 如果
bits等于 0 ,或大于 64,超过所能截取的 UInt64 长度,则抛出异常。
func nextBits(UInt64)
public func nextBits(bits: UInt64): UInt64
功能:生成一个指定位长的随机整数。
参数:
- bits: UInt64 - 要生成的伪随机数的位数,取值范围 (0, 64]。
返回值:
- UInt64 - 生成的用户指定位长的伪随机数。
异常:
- IllegalArgumentException - 如果
bits等于 0,或大于 64,超过所能截取的 UInt64 长度,则抛出异常。
func nextBool()
public func nextBool(): Bool
功能:获取一个布尔类型的伪随机值。
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Bool = m.nextBool()
println("n=${n is Bool}")
return 0
}
运行结果:
n=true
func nextFloat16()
public func nextFloat16(): Float16
功能:获取一个 Float16 类型的伪随机数,其范围为 [0.0, 1.0)。
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Float16 = m.nextFloat16()
if (n is Float16) {
println("n is Float16")
}
return 0
}
运行结果:
n is Float16
func nextFloat32()
public func nextFloat32(): Float32
功能:获取一个 Float32 类型的伪随机数,其范围为 [0.0, 1.0)。
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Float32 = m.nextFloat32()
if (n is Float32) {
println("n is Float32")
}
return 0
}
运行结果:
n is Float32
func nextFloat64()
public func nextFloat64(): Float64
功能:获取一个 Float64 类型的伪随机数,其范围为 [0.0, 1.0)。
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Float64 = m.nextFloat64()
if (n is Float64) {
println("n is Float64")
}
return 0
}
运行结果:
n is Float64
func nextGaussianFloat16(Float16, Float16)
public func nextGaussianFloat16(mean!: Float16 = 0.0, sigma!: Float16 = 1.0): Float16
功能:获取一个 Float16 类型的符合指定均值与标准差的高斯分布的随机数。
默认获取一个 Float16 类型且符合均值为 0.0 标准差为 1.0 的高斯分布的随机数。其中均值是期望值,可解释为位置参数,决定了分布的位置,标准差可解释为尺度参数,决定了分布的幅度。
参数:
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Float16 = m.nextGaussianFloat16(mean: 0.0, sigma: 1.0)
if (n is Float16) {
println("n is Float16")
}
return 0
}
运行结果:
n is Float16
func nextGaussianFloat32(Float32, Float32)
public func nextGaussianFloat32(mean!: Float32 = 0.0, sigma!: Float32 = 1.0): Float32
功能:获取一个 Float32 类型的符合指定均值与标准差的高斯分布的随机数。
默认获取一个 Float32 类型且符合均值为 0.0 标准差为 1.0 的高斯分布的随机数。其中均值是期望值,可解释为位置参数,决定了分布的位置,标准差可解释为尺度参数,决定了分布的幅度。
参数:
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Float32 = m.nextGaussianFloat32(mean: 0.0, sigma: 1.0)
if (n is Float32) {
println("n is Float32")
}
return 0
}
运行结果:
n is Float32
func nextGaussianFloat64(Float64, Float64)
public func nextGaussianFloat64(mean!: Float64 = 0.0, sigma!: Float64 = 1.0): Float64
功能:获取一个 Float64 类型的符合指定均值与标准差的高斯分布的随机数。
默认获取一个 Float64 类型且符合均值为 0.0 标准差为 1.0 的高斯分布的随机数。其中均值是期望值,可解释为位置参数,决定了分布的位置,标准差可解释为尺度参数,决定了分布的幅度。
参数:
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Float64 = m.nextGaussianFloat64(mean: 0.0, sigma: 1.0)
if (n is Float64) {
println("n is Float64")
}
return 0
}
运行结果:
n is Float64
func nextInt16()
public func nextInt16(): Int16
功能:获取一个 Int16 类型的伪随机数。
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Int16 = m.nextInt16()
if (n is Int16) {
println("n is Int16")
}
return 0
}
运行结果:
n is Int16
func nextInt16(Int16)
public func nextInt16(upper: Int16): Int16
功能:获取一个范围在 [0, upper) 的 Int16 类型的伪随机数。
参数:
返回值:
异常:
- IllegalArgumentException - 如果
upper小于等于 0,抛出异常。
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Int16 = m.nextInt16(5)
if (n is Int16) {
println("n is Int16")
}
try {
let p: Int16 = m.nextInt16(-1)
println(p)
} catch (e: IllegalArgumentException) {
println("参数异常:upper 小于等于 0")
}
return 0
}
运行结果:
n is Int16
参数异常:upper 小于等于 0
func nextInt32()
public func nextInt32(): Int32
功能:获取一个 Int32 类型的伪随机数。
返回值:
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Int32 = m.nextInt32()
if (n is Int32) {
println("n is Int32")
}
return 0
}
运行结果:
n is Int32
func nextInt32(Int32)
public func nextInt32(upper: Int32): Int32
功能:获取一个范围在 [0, upper) 的 Int32 类型的伪随机数。
参数:
返回值:
异常:
- IllegalArgumentException - 如果
upper小于等于 0,抛出异常。
示例:
import std.random.*
main() {
let m: Random = Random()
let n: Int32 = m.nextInt32(5)
if (n is Int32) {
println("n is Int32")
}
try {
let p: Int32 = m.nextInt32(-1)
println(p)
} catch (e: IllegalArgumentException) {
println("参数异常:upper 小于等于 0")
}
return 0
}
运行结果: