仓颉语言标准库概要指南与示例
仓颉语言标准库概要指南与示例
核心概念:包(Package)与模块(Module)
- 包(Package):编译的最小单元,可包含函数、类、结构体等声明,支持嵌套(子包),例如std.collection.concurrent是std.collection的子包。
- 模块(Module):由 “根包(root package)+ 所有子包” 构成的树形结构,模块名与根包一致(如std模块包含std.core、std.collection等所有子包),是发布的最小单元。
常用标准库(注意,这是按我自己了解和认识选择,有一定随机因素。官方 仓颉编程语言标准库 API 可见 https://cangjie-lang.cn/docs?url=%2F1.0.0%2Flibs%2Fstd%2Fstd_module_overview.html ))
包名 | 主要功能 |
core | 提供最基础的 API,如“控制台输出” 和 “控制台输入”。该包无需显式导入即可使用。 |
env | 提供访问环境变量、命令行参数、供标准输入、标准输出等功能。 |
convert | 提供格式化能力,主要为将仓颉类型实例转换为格式化字符串。 |
collection | 包含常见数据结构(如ArrayList动态数组、HashMap键值对)的高效实现。 |
time | 提供与时间日期相关的类型和计算功能。 |
math | 包含常见的数学运算和常数。 |
random | 提供生成伪随机数的能力。 |
fs | file system提供对文件、文件夹和路径的操作。 |
包导入语法
导入场景 | 语法格式 | 示例 |
导入单个顶层声明 | import fullPackageName.itemName | import std.collection.ArrayList |
导入同一包的多个声明 | import fullPackageName.{item1, item2...} | import std.collection.{ArrayList, HashMap} |
导入包内所有 public 声明 | import fullPackageName.* | import std.math.* |
仓颉标准库示例
下面通过几个具体例子来看看这些包如何工作。你可以将代码保存为 .cj 文件进行编译和测试。实验环境搭建 参见 https://blog.csdn.net/cnds123/article/details/150844497
【 特别说明 :csdn目前的网页“代码”格式不支持 仓颉(CangJie),因此博文中的示例“代码”格式选为 Rust 】
示例 1:控制台交互(core 包,无需显式导入即可使用)
// 主逻辑:读取用户名并输出欢迎语
main() {// 1. 打印提示信息到标准输出(stdout)print("请输入你的名字:")// 2. 读取用户从标准输入(stdin)输入的字符串(自动忽略换行符)let username = readln()// 3. 拼接字符串并打印结果print("欢迎你," + username + "!使用仓颉语言开发真高效~")
}
编译运行截图:
core 包、env包、convert包 介绍及示例,可见https://blog.csdn.net/cnds123/article/details/150953751
在此就不多写了。
示例 2:集合操作(collection 包)
std.collection提供常用数据结构(如ArrayList动态数组、HashMap键值对),该示例演示两种集合的创建、添加元素、遍历操作。
// 导入collection包的ArrayList(动态数组)和HashMap(键值对)
import std.collection.{ArrayList, HashMap}main() {// --------------------------// 1. ArrayList(动态数组)示例:存储整数列表// --------------------------// 创建一个存储Int类型的ArrayList实例let numList = ArrayList<Int64>()// 向数组添加元素numList.add(10)numList.add(20)numList.add(30)// 遍历ArrayList(通过索引访问)println("ArrayList中的元素:")for (i in 0..numList.size) {//println("索引" + i.toString() + ":" + numList.get(i).toString())println("索引${i.toString()}:${numList.get(i).getOrThrow()}")}// --------------------------// 2. HashMap(键值对)示例:存储用户信息(姓名→年龄)// --------------------------// 创建一个Key为String、Value为Int的HashMap实例let userMap = HashMap<String, Int64>()// 向HashMap添加键值对userMap.add("张三", 25)userMap.add("李四", 30)userMap.add("王五", 28)// 遍历HashMap(通过键值对迭代)println("\nHashMap中的用户信息:")for ((name, age) in userMap) {println("姓名:" + name + ",年龄:" + age.toString())}// 查找指定键的值(存在则返回值,不存在返回null)let zhangSanAge = userMap.get("张三")println("\n张三的年龄:${zhangSanAge.getOrThrow()}")
}
编译运行输出:
ArrayList中的元素:
索引0:10
索引1:20
索引2:30
HashMap中的用户信息:
姓名:张三,年龄:25
姓名:李四,年龄:30
姓名:王五,年龄:28
张三的年龄:25
关于ArrayList 可参见https://blog.csdn.net/cnds123/article/details/151579259 相关部分
示例 3:时间处理(time 包)
// 导入time包的核心类型和函数
import std.time.*main() {// 1. 获取当前系统时间(包含日期和时区)let currentTime = DateTime.now()println("当前时间(原始格式):" + currentTime.toString())// 2. 格式化时间为“年-月-日 时:分:秒”(支持自定义格式)let formattedTime = currentTime.format("yyyy-MM-dd HH:mm:ss")println("格式化时间:" + formattedTime)}
示例中格式化符号,yyyy 4 位年,MM 2 位月,dd 2位日,HH 24小时制,mm 2位分,ss 2 位秒。
示例 4:数学计算(math 包)
// 导入math包
import std.math.*// 当前版本缺π(圆周率),先手动定义
let PI = 3.14159265358979323846// 角度 → 弧度
func degToRad(d: Float64): Float64 {return d * (PI / 180.0)
}// 弧度 → 角度
func radToDeg(r: Float64): Float64 {return r * (180.0 / PI)
}main() {print("π(圆周率):" + PI.toString())// 基础运算:平方根、幂运算、绝对值let sqrtVal = sqrt(16.0) // 平方根let powVal = pow(2.0, 5.0) // 2的5次方let absVal = abs(-10.5) // 绝对值print("\n16的平方根:" + sqrtVal.toString())print("2^5 = " + powVal.toString())print("-10.5的绝对值:" + absVal.toString())// 三角函数(需传入弧度值,这里将30度转为弧度)let rad30 = degToRad(30.0) // 角度转弧度let sin30 = sin(rad30) // sin(30°)print("\nsin(30°) = " + sin30.toString()) // 结果约为0.500000
}
示例 5:伪随机数(random 包),生成 10 个 [0,1) 的 Float64 随机小数
import std.random.*main(): Unit {let rng = Random() // 默认时间种子for (i in 0..10) {let v = rng.nextFloat64()println("random ${i} = ${v}")}
}
std.fs示例
可见https://blog.csdn.net/cnds123/article/details/151956561
在此就不多写了。
最后,给出几个综合示例
综合示例1:生成随机数组与随机选择
import std.random.*
import std.collection.ArrayList/* ---------- 两个小工具 ---------- */
// 返回 [min, max] 闭区间随机整数
func randInt(rng: Random, min: Int64, max: Int64): Int64 {let span = max - min + 1return min + Int64(rng.nextFloat64() * Float64(span))
}// 从数组随机选 1 个元素
func randSelect<T>(rng: Random, arr: Array<T>): T {let idx = Int64(rng.nextFloat64() * Float64(arr.size))return arr[idx]
}/* ---------- 主程序 ---------- */
main(): Unit {let rng = Random() // 默认时间种子// 1. 10 个 [0,99] 随机整数let randomArray = ArrayList<Int64>()for (i in 0..9) {randomArray.add(randInt(rng, 0, 99))}println("随机数组:${randomArray}")// 2. 随机水果let fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]let randomFruit = randSelect(rng, fruits)println("随机选择的水果:${randomFruit}")
}
综合示例2:给出1到100之间的整数猜数游戏
有两种代码
法一源码:
import std.convert.*
import std.random.*main() {// 输出游戏欢迎信息println("欢迎来到猜数字游戏!")println("我已经想好了一个1到100之间的整数。")println("请你猜一猜这个数字是多少?")// 先拿到 Int8 范围内的随机数let n: Int8 = Random().nextInt8()// 映射到 1~100let target: Int8 = (n % 100 + 100) % 100 + 1 // 两次 %100 保证非负// 注释掉调试输出,正式游戏不显示答案// println(target)var guess: Int8 = 0 // 声明猜测变量,扩大作用域while (true) {// 提示用户输入猜测的数字,合并重复提示print("请输入你的猜测(1-100):")var str: String = readln()if (str.isEmpty()) {println("输入为空,请重新输入一个整数:")continue}// 使用 try-catch 捕获 parse 可能抛出的异常try {guess = Int8.parse(str)// 检查范围if (guess >= 1 && guess <= 100) {break // 输入有效,退出输入循环} else {println("请输入1到100之间的数字:")}} catch(e:IllegalArgumentException){println("输入非法,请输入一个有效的整数:")}}// 主游戏循环,每次猜测后重新获取输入while (true) {if (guess < target) {println("猜小了!再试试更大的数字。")} else if (guess > target) {println("猜大了!再试试更小的数字。")} else {println("恭喜你猜对了!")break}// 重新获取用户输入print("请再次输入你的猜测(1-100):")var str: String = readln()try {guess = Int8.parse(str)} catch(e:IllegalArgumentException) {println("输入非法,已自动使用上一次猜测值,请输入有效整数:")}} println("游戏结束,谢谢参与!")
}
法二源码:
import std.random.*
import std.env.*
import std.convert.*/* 读整数(尾递归版,避开 while true 类型问题) */
func readInt(prompt: String): Int64 {print(prompt)let line = readln()try {return Int64.parse(line)} catch (_: Exception) {println("请输入合法整数!")return readInt(prompt) // 尾递归重试}
}/* 闭区间随机整数 */
func randInt(rng: Random, min: Int64, max: Int64): Int64 {let span = max - min + 1return min + Int64(rng.nextFloat64() * Float64(span))
}/* ---------- 主游戏 ---------- */
main(): Unit {let rng = Random()let target = randInt(rng, 1, 100)let maxTry = 7println("=== 仓颉猜数游戏 ===")println("我已经想好了一个 1~100 的整数,你有 ${maxTry} 次机会!")for (i in 1..maxTry) {let guess = readInt("第 ${i} 次猜测:")if (guess == target) {println("猜对了!答案就是 ${target}")return} else if (guess > target) {println("太大了,再小一点~")} else {println("太小了,再大一点~")}}println("次数用完,正确答案是 ${target},欢迎再来!")
}
附录:仓颉编程语言青少年基础教程系列汇总https://blog.csdn.net/cnds123/article/details/152025242
OK !