当前位置: 首页 > news >正文

仓颉语言三方库开发与使用指南(通用仓颉篇)

写在前面

本篇文章的作者是仓颉高级三方库开发者刘老师所作,本人发布该篇文章已经过刘老师允许,想让更多的粉丝朋友可以了解到更优秀的学习资源、更优秀的行业引导者
刘老师本人主页链接:https://blog.csdn.net/weixin_47308626?type=blog

导语

作为鸿蒙生态的核心新兴编程语言,仓颉凭借强大的跨语言互操作能力、高效的开发体验,正在快速成为应用开发的新选择。随着语言生态的逐步完善,三方库的开发与复用已成为提升开发效率、丰富应用功能的关键,也是开发者进阶路上的核心议题。

仓颉三方库的核心价值

  • 生态复用:通过标准化包封装与编译,实现代码跨项目、跨团队高效复用,减少重复开发。
  • 模块化开发:支持导出仓颉组件、类和方法,通过public修饰符精准控制访问权限,助力模块化架构设计。
  • 原生性能:CJNative 后端将库代码编译为原生二进制,直接运行于操作系统层面,兼顾高效执行与资源优化。
  • 安全保障:静态强类型检查杜绝类型错误,自动内存管理避免内存泄漏,双重保障运行时稳定性。

仓颉包管理核心机制

仓颉采用 “包 - 模块” 的层级设计组织代码,官方包管理工具 CJPM(Cangjie Package Manager)提供从初始化、构建到依赖管理的全流程支持,是三方库开发与使用的基础。

一、核心概念厘清

  • 包(Package):编译的最小单元,拥有独立命名空间,同一包内不允许同名顶层定义(函数重载除外)。
  • 模块(Module):若干相关包的集合,是第三方开发者发布、分享三方库的最小单元。
  • 源码包识别:直接包含至少一个.cj仓颉代码文件即为有效源码包;其父包(递归向上)需均为有效源码包,根包仅需满足首条规则。

二、CJPM 工具核心用法

CJPM 提供简洁的命令行接口,覆盖开发全流程,核心功能如下:

1. 常用命令
cjpm init        # 初始化新仓颉模块(生成项目结构与配置文件)
cjpm build       # 构建当前模块(输出库文件或可执行文件)
cjpm run         # 编译并运行可执行模块
cjpm test        # 执行本地包/模块的单元测试
cjpm install     # 安装指定版本的仓颉二进制包(本地或远程)
2. 核心配置文件
  • cjpm.toml:模块核心配置文件,定义包名、版本、输出类型、作者、依赖关系等元数据。
  • cjpm.lock:自动生成的依赖锁定文件,固定依赖版本,避免多环境版本不一致问题。
3. 依赖管理特性
  • 自动分析多版本依赖,智能合并并解决冲突。
  • 支持本地依赖(通过路径引用)和远程依赖(通过仓库地址引用)。

三、标准项目结构

遵循以下目录结构可确保兼容性,便于他人复用:

project/
├── src/                  # 源码目录
│   ├── main.cj           # 主入口文件(根包代码)
│   └── pkg1/             # 子包目录(与包名对应)
│       └── mod1.cj       # 子包模块代码
└── cjpm.toml             # 包配置文件(必需)
包声明规范

代码文件开头需明确声明所属包,包名需与目录层级一致:

package demo.pkg1  // 对应 src/pkg1 目录,父包为 demo

四、编译与构建流程

1. 编译器基础用法
cjc [option] file...  # 直接编译仓颉源码文件
2. 完整构建流程
  1. 前端编译:将仓颉源码转换为 LLVM IR 中间表示。
  2. 后端编译:基于 LLVM IR 生成目标平台的机器码。
  3. 链接:将机器码与依赖库整合,生成最终产物。
3. 关键构建选项
  • --output-type:指定输出类型(executable可执行文件 /static静态库 /dynamic动态库)。
  • --output-dir:指定产物输出目录(默认生成target文件夹)。
  • -p:指定包路径,用于多包项目的精准编译。

三方库开发实战

仓颉三方库的编译产物分为静态库(static)和动态库(dynamic)两类,需根据使用场景选择合适类型,核心实现步骤如下:

一、静态库与动态库核心差异

特性静态库(static)动态库(dynamic)
链接时机编译阶段直接嵌入可执行文件程序运行时动态加载
产物大小可执行文件较大(包含库代码)可执行文件较小(仅含引用入口)
内存占用多个进程独立加载,占用内存较多多进程共享实例,内存占用更优
更新方式需重新编译主程序才能更新直接替换动态库文件即可生效
部署依赖无外部依赖,可独立部署需随主程序分发对应的动态库文件

二、适用场景选择

静态库适用场景
  • 嵌入式设备、独立工具等需要 “零依赖部署” 的场景。
  • 对程序启动速度要求高,需避免运行时加载开销的场景。
  • 需规避动态库版本冲突的复杂项目。
动态库适用场景
  • 多进程共享功能模块(如系统级工具库),需优化内存占用。
  • 大型应用的插件系统,支持功能热更新(无需重启主程序)。
  • 频繁迭代的功能模块,需快速更新且不影响主程序。

三、基础配置示例

cjpm.toml中指定输出类型,即可快速配置库类型:

[package]
name = "math_utils"       # 库名称(需与包声明一致)
version = "1.0.0"         # 版本号(遵循语义化版本规范)
output-type = "dynamic"   # 输出动态库(改为"static"即为静态库)
authors = ["Your Name <your.email@example.com>"]
description = "轻量高效的仓颉数学工具库"[dependencies]
# 无依赖时留空,有依赖需声明版本与来源

四、简易数学工具库实现

以 “加减乘除幂运算” 工具库为例,完整演示开发流程:

1. 项目结构
math-utils/
├── src/
│   └── index.cj  # 库核心实现文件
└── cjpm.toml     # 配置文件
2. 核心代码实现

cangjie

// src/index.cj
package math_utils  # 包名需与 cjpm.toml 中的 name 一致// 加法(public修饰符表示可被外部导入使用)
public func add(a: Int64, b: Int64): Int64 {return a + b
}// 减法
public func subtract(a: Int64, b: Int64): Int64 {return a - b
}// 乘法
public func multiply(a: Int64, b: Int64): Int64 {return a * b
}// 除法(带除零检查,返回可选类型)
public func divide(a: Int64, b: Int64): ?Int64 {if (b == 0) {return None  // 除零返回空}return Some(a / b)
}// 幂运算(base为底数,exponent为非负指数)
public func power(base: Int64, exponent: UInt64): Int64 {if (exponent == 0) {return 1  // 任何数的0次幂为1}var result = basefor (_ in 1..exponent) {result *= base}return result
}
3. 构建库文件

进入math-utils目录,执行以下命令构建:

cjpm build

构建成功后,会在target目录下生成对应库文件(动态库为.so/.dll,静态库为.a/.lib)。

三方库使用教程

使用已开发的三方库仅需两步:配置依赖 + 导入使用,支持本地库和远程库两种引用方式。

一、本地库引用(开发调试场景)

假设已有两个项目,math-utils为开发好的库,math-example为使用库的应用,目录结构如下:

project-root/
├── math-utils/       # 已构建好的数学工具库
└── math-example/     # 待开发的应用项目
1. 配置应用依赖

编辑math-example/cjpm.toml,添加本地库依赖:

[package]
name = "math_example"
version = "1.0.0"
output-type = "executable"  # 应用为可执行类型[dependencies]
# 引用本地库:path指定库目录,version需与库的版本一致
math_utils = { path = "../math-utils", version = "1.0.0" }
2. 导入并使用库

编辑math-example/src/index.cj,通过import导入库功能:

package math_example  # 应用包名// 方式1:全量导入库(推荐,便捷高效)
import math_utils.*// 方式2:按需导入指定函数(减少冗余,按需使用)
// import math_utils.add
// import math_utils.multiplymain() {// 调用库函数let sum = add(5, 3)          // 结果:8let difference = subtract(10, 4)  // 结果:6let product = multiply(4, 6)   // 结果:24let quotient = divide(15, 3)   // 结果:Some(5)let powerResult = power(2, 3)  // 结果:8// 打印结果(需确保仓颉环境支持控制台输出)println("5+3 = {sum}")println("15÷3 = {quotient.unwrapOr(0)}")  // 处理可选类型
}
3. 运行应用

进入math-example目录,执行以下命令运行:

cjpm run

开发与使用注意事项

  • 包名一致性:库的package声明需与cjpm.toml中的name完全一致,否则会导致导入失败。
  • 访问权限:需对外暴露的函数、类必须添加public修饰符,默认无修饰符的内容仅包内可见。
  • 版本兼容性:遵循语义化版本规范(主版本号变更可能不兼容),避免依赖版本冲突。
  • 错误处理:调用库函数时需注意返回值类型(如示例中的可选类型?Int64),避免运行时异常。
http://www.dtcms.com/a/553583.html

相关文章:

  • 【互联网产品助理的成长之路(1)】需求设计的大致流程及思考
  • JAVASE速通复习(二)
  • 广州做网站好的公司胶州网站建设 网络推广
  • git提交 关键字介绍 约定式提交
  • vue2 vue3 修改elementUI和elementPlus主题颜色
  • 易班网站建设基础贵阳设计网站建设
  • 【Linux】Linux 权限
  • 食品电子商务网站建设规划书一般网站的宽度是多少
  • Python爬虫实战:美元-人民币汇率历史数据获取与趋势分析
  • android studio创建使用开发打包教程
  • 基于Springboot的影视评论网站的设计与实现58py6238(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
  • 57套思维导图PPT模板合集 培训/头脑风暴/工作规划 可编辑PPTX
  • 项目源码安全审查—密钥硬编码问题
  • 内蒙古城乡住房建设厅网站网站建设及发布的流程
  • Java 大视界 -- Java 大数据机器学习模型在遥感图像土地利用分类中的优化与应用
  • Hutool 全面实战指南:让 Java 开发更“甜”
  • LangChain进阶学习
  • 网站广告图怎么做网站开发的工作制度
  • 关于Delphi的一次吵架
  • 全连接层的第二层是怎么减少神经节点数
  • Rust开发之泛型约束与where子句的应用
  • 什么是CVE?如何通过SAST/静态分析工具Perforce QAC 和 Klocwork应对CVE?
  • 通过 Nix 管理 C 和 C++ 依赖项
  • Kimi Linear 论文阅读笔记:第一次“线性注意力”全面胜过全注意力
  • 金华网站开发开发网站需要什么硬件
  • 使用mysql客户端工具造数据方法入门
  • 光刻胶分类与特性——g/i线光刻胶及东京应化TP-3000系列胶典型配方(下)
  • Spring Boot项目快速稳健架构指南
  • 网站wordpress错误网站设计宽度尺寸
  • 图像分割技术总结