文档编程语言【免费下载链接】cangjie_docs仓颉编程语言开发者文档。项目地址https://gitcode.com/Cangjie/cangjie_docs点击查看免费下载包的声明是仓颉Cangjie编程语言中每个源文件必须遵循的第一条规则它决定了源码如何被组织为包package、子包与模块module也是编译、导入与发布流程的起点。本文将围绕 包的声明 的完整规范系统讲解包声明的语法形式、标识符约束、源码目录对应关系与命名冲突规则并结合 cjc 编译选项 与 cjpm 项目管理工具 中的真实配置给出可直接落地的工程实践。读完本文你将能独立设计一个符合仓颉规范的多包模块结构并正确编写每个源文件的包声明。一、包声明的语法结构在仓颉编程语言中包声明以关键字package开头其后依次是可选的组织名organization name与组织名分隔符::从 root 包到当前包之间由.分隔路径上的所有包名。其形式可以概括为package [组织名::]root包名[.子包名]*组织名与包名都必须满足合法普通标识符的约束详见下文且不允许使用原始标识符即反引号包裹的标识符如if不能用作包名。三种典型声明如下package pkg1 // root 包 pkg1 package pkg1.sub1 // root 包 pkg1 的子包 sub1 package org1::pkg1.sub1 // 组织 org1 下的 root 包 pkg1 的子包 sub1第一个例子声明了一个名为pkg1的 root 包第二个例子声明了pkg1包下的子包sub1第三个例子则进一步引入了组织名org1它通过::与包名分隔。组织名通常用于标识代码的发布方当不同组织发布同名包时组织名可以起到命名空间隔离的作用。二、组织名与包名的标识符约束包名并非任意字符串它必须是一个合法的普通标识符。依据仓颉的标识符规范普通标识符取自以下两类字符序列由XID_Start字符包含中文、英文等字符开头后接任意长度的XID_Continue字符包含中文、英文和阿拉伯数字等由一个_开头后接至少一个XID_Continue字符。同时普通标识符不能与仓颉关键字相同。因此package while、package 3abc、package a-b之类的声明都是非法的。注意平台限制当前 Windows 平台版本中组织名、包名暂不支持使用 Unicode 字符必须是一个仅含 ASCII 字符的合法普通标识符。也就是说在 Windows 平台上package 工具库这类使用中文的包声明会报错请务必使用纯 ASCII 命名。三、包声明的放置位置与一致性要求包声明在源文件中的位置有严格的强制约束必须位于源文件的非空、非注释首行。文件开头的注释是允许的但注释之后的第一条有效语句必须是包声明。同一个包中的不同源文件其包声明必须保持一致。即同一目录包下的所有.cj文件必须声明相同的包名不能出现文件 A 声明package a、文件 B 声明package a.b的情况。下面的示例展示了合法与非法写法// 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...file 2在包声明之前放置了声明语句编译器会直接报错因为包声明必须是文件中的第一条非空、非注释语句。四、包名与源码目录的对应关系仓颉的包名不是随意起的名字它必须反映当前源文件相对于项目源码根目录src的路径并将路径中的分隔符替换为小数点。例如若包的源代码位于src/directory_0/directory_1目录下root 包名为pkg则其中源文件的包声明应为package pkg.directory_0.directory_1这里的对应关系遵循三条基础规则包所在的文件夹名必须与包名一致。directory_1目录中的文件必须声明以directory_1结尾的包名目录名与包名不能错位。源码根目录默认名为src。编译器以src作为计算包路径的基准点。源码根目录下的包可以省略包声明此时编译器会默认为其指定包名default。一个完整的目录示例假设源代码目录结构如下// The directory structure is as follows: src |-- directory_0 |-- directory_1 | |-- 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(): Int64 { return 0 }注意其中的关键点a.cj与b.cj位于同一目录src/directory_0/directory_1因此它们的包声明完全一致都是default.directory_0.directory_1c.cj位于src/directory_0其包声明为default.directory_0main.cj直接位于源码根目录src下按规则可以省略包声明编译器将其归入默认包default同时它还是模块的程序入口main函数的返回值类型为整数类型。这个示例也印证了包和模块管理中的描述包可以定义子包从而构成树形结构子包的目录是其父包目录的子目录没有父包的包称为 root 包root 包及其全部子包构成的整棵树称为模块。在上述结构中default是 root 包directory_0、directory_0.directory_1依次是其子包。五、命名冲突规则包声明不能引起命名冲突子包不能和当前包的顶层声明同名。以下是一组典型的错误示例。当包a中存在名为B的顶层类同时包a下又存在子包a.B时// 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 {}编译b.cj时会因为a.B与顶层类B同名而报错。进一步地如果在main.cj中写import a.B// main.cj import a.B // ambiguous use of a.B main() { a.B.f() }由于a.B既可能指子包也可能指类B编译器会判定为歧义使用ambiguous use而报错。因此在设计包结构时应避免子包名与父包中的顶层类型、函数等声明重名。六、包声明与编译、工程管理的配合包声明不仅是语法约束它还与仓颉编译工具链和工程管理工具紧密联动。使用cjc -p编译整包cjc是仓颉的编译命令其--package短选项-p选项用于编译一个包使用时需要指定一个目录作为输入且该目录中的源码文件必须属于同一个包。例如 cjc 编译选项 中给出的log包示例// log/printer.cj package log public func printLog(message: String) { println([Log]: ${message}) }$ cjc -p log --output-typestaticlib该命令将log包编译为静态库在当前目录下生成liblog.a文件。随后可以链接该库编译入口文件$ cjc main.cj liblog.a这里的package log声明与目录名log、-p log参数三者必须保持一致任何一处错位都会导致编译失败。此外--output-type支持exe、staticlib、dylib、chir、obj等输出类型其中cjc默认输出可执行文件exe。使用cjpm初始化模块骨架仓颉官方项目管理工具cjpm init会自动生成标准模块骨架在当前文件夹创建cjpm.toml配置文件、新建src源码文件夹并在src下生成默认的main.cj。其 配置文件 中[package]段的name字段即同时规定了模块名及模块 root 包名[package] cjc-version 1.0.0 # 所需 cjc 的最低版本要求必需 name demo # 模块名及模块 root 包名必需 version 1.0.0 # 模块版本信息必需 output-type executable # 编译输出产物类型必需 src-dir # 指定源码存放路径非必需使用cjpm build -V可以观察实际编译过程cjpm会调用cjc分别编译包与模块例如cjc --import-path target -p src/package1 --output-typestaticlib -o target/release/module1/libmodule1.package1.a。从中可以看到包名与src下的目录结构是编译命令的直接输入。使用--import-path指定导入搜索路径当模块跨包导入时编译器通过包名查找对应的 AST 产物文件.cjo。--import-path value选项用于指定导入模块的 AST 文件搜索路径它提供与CANGJIE_PATH环境变量相同的功能但优先级更高。例如目录结构. ├── libs | └── myModule | ├── myModule.log.cjo | └── libmyModule.log.a └── main.cj配合cjc main.cj --import-path ./libs编译器会使用./libs/myModule/myModule.log.cjo文件对main.cj进行语义检查与编译。这说明包名的层级结构myModule.log会直接映射为文件系统中的目录与文件路径包声明、目录、产物文件三者构成了一个闭环的定位体系。七、与包相关的语言特性要点包声明是包体系的第一环它与下列语言特性共同构成仓颉的模块化机制包是编译的最小单元每个包可以单独输出 AST 文件、静态库文件、动态库文件等产物每个包有自己的名字空间同一个包内不允许有同名的顶层定义或声明函数重载除外。模块是若干包的集合是第三方开发者发布的最小单元见包的概述。程序入口模块的程序入口只能位于其根目录下且顶层最多只能有一个main该main没有参数或参数类型为ArrayString返回类型为整数类型或Unit类型详见程序入口。上文目录示例中的main.cj正是这种形态。访问修饰符package声明本身支持internal、protected、public三种访问修饰符默认是public这与顶层声明的可见性规则一致可用于控制包对模块内外的可见范围。导入机制其他文件可以通过import 完整包名.顶层声明或import 包名.*的方式导入包中的声明导入语句必须位于包声明之后、其他声明之前编译器还会自动为源码隐式导入core包中所有public修饰的声明详见包的导入。条件编译的边界仓颉内置编译标记When仅允许修饰 import 节点和除 package 声明外的其他声明类节点即When不能用于包声明见条件编译。结语包声明虽是一条简单的语法规则却是仓颉源码组织、编译产物定位与模块发布的基础。掌握包名 相对src的路径 点号替换分隔符 可选组织名这一核心映射关系并严格遵守首行位置、同包一致、目录名与包名对齐、避免子包与顶层声明同名等约束就能构建出规范、可维护、可独立编译与发布的多包模块。将本文的规则与cjc -p、cjpm、--import-path等工具配合使用即可打通从一个包的声明到整模块编译发布的完整链路。赞分享文档编程语言【免费下载链接】cangjie_docs仓颉编程语言开发者文档。项目地址https://gitcode.com/Cangjie/cangjie_docs点击查看免费下载相关推荐仓颉语言包声明package 声明完全指南语法、目录映射与命名约束仓颉语言包声明package 声明完全指南语法、目录映射与命名约束 在仓颉编程语言中 包package是编译的最小单元 每个包拥有独立的名字空间文档编程语言仓颉语言顶层声明可见性详解public/protected/internal/private 四种访问修饰符的语义、默认规则与编译约束仓颉语言顶层声明可见性详解public/protected/internal/private 四种访问修饰符的语义、默认规则与编译约束 仓颉Cangjie文档编程语言仓颉编程语言宏包定义与导入macro package 语法、可见性规则与跨包依赖管理实战仓颉编程语言宏包定义与导入 macro package 语法、可见性规则与跨包依赖管理实战 本篇技术指南聚焦仓颉Cangjie编程语言宏机制的关键前置环节文档编程语言创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考