重学仓颉-11包系统完全指南

概述

在仓颉编程语言中,包(Package)是编译的最小单元,也是代码组织和模块化的核心概念。随着项目规模的不断扩大,仅在一个超大文件中管理源代码会变得十分困难。包系统允许我们将源代码根据功能进行分组,并将不同功能的代码分开管理,每组独立管理的代码会生成一个输出文件。

核心概念

包 vs 模块

  • 包(Package):编译的最小单元,每个包可以单独输出 AST 文件、静态库文件、动态库文件等产物
  • 模块(Module):若干包的集合,是第三方开发者发布的最小单元

包的特性

  • 每个包有自己的名字空间
  • 在同一个包内不允许有同名的顶层定义或声明(函数重载除外)
  • 一个包中可以包含多个源文件
  • 模块的程序入口只能在其根目录下

包声明(Package Declaration)

基本语法

包声明以关键字 package 开头,后接 root 包至当前包由 . 分隔路径上所有包的包名:

cangjie 复制代码
package pkg1      // root 包 pkg1
package pkg1.sub1 // root 包 pkg1 的子包 sub1

重要规则

  1. 包声明位置:必须在源文件的非空非注释的首行
  2. 包名一致性:同一个包中的不同源文件的包声明必须保持一致
  3. 包名限制:当前 Windows 平台版本,包名暂不支持使用 Unicode 字符,必须仅含 ASCII 字符

包名与目录结构的关系

包名需反映当前源文件相对于项目源码根目录 src 的路径,并将其中的路径分隔符替换为小数点。

示例目录结构:

cangjie 复制代码
src
`-- directory_0
    |-- directory_1
    |    |-- a.cj
    |    `-- b.cj
    `-- c.cj
`-- main.cj

对应的包声明:

cangjie 复制代码
// a.cj - 位于 src/directory_0/directory_1/
package default.directory_0.directory_1

// 定义一些函数
public func calculate(a: Int32, b: Int32): Int32 {
    return a + b
}

public func multiply(a: Int32, b: Int32): Int32 {
    return a * b
}
cangjie 复制代码
// b.cj - 位于 src/directory_0/directory_1/
package default.directory_0.directory_1
import std.math.sqrt
// 定义一些类型
public struct Point {
    public let x: Float64
    public let y: Float64

    public init(x: Float64, y: Float64) {
        this.x = x
        this.y = y
    }

    public func distance(other: Point): Float64 {
        let dx = this.x - other.x
        let dy = this.y - other.y
        return sqrt(dx * dx + dy * dy)
    }
}
cangjie 复制代码
// c.cj - 位于 src/directory_0/
package default.directory_0

import std.convert.Formattable
// 定义一些常量
public let PI: Float64 = 3.14159265359
public let E: Float64 = 2.71828182846

public func formatNumber(num: Float64): String {
    return "${num.format(".2")}"
}

main() {
    println(formatNumber(2.23424))
}
cangjie 复制代码
// main.cj - 位于 src/ 根目录,可以省略包声明
import default.directory_0.directory_1.calculate
import default.directory_0.directory_1.multiply
import default.directory_0.directory_1.Point
import default.directory_0.PI
import default.directory_0.formatNumber

main(): Int32 {
    // 使用导入的函数
    let result1 = calculate(10, 20)
    let result2 = multiply(5, 6)
    
    // 使用导入的类型
    let p1 = Point(x: 0.0, y: 0.0)
    let p2 = Point(x: 3.0, y: 4.0)
    let distance = p1.distance(to: p2)
    
    // 使用导入的常量
    let area = PI * 5.0 * 5.0
    
    // 使用导入的函数
    let formatted = formatNumber(area)
    
    println("计算结果:")
    println("10 + 20 = \(result1)")
    println("5 * 6 = \(result2)")
    println("两点距离:\(distance)")
    println("圆的面积:\(formatted)")
    
    return 0
}

包名冲突避免

子包不能和当前包的顶层声明同名,避免命名冲突:

cangjie 复制代码
// ❌ 错误示例 - 包名冲突
package cangjie_blog.math

public class Vector { // Error: 'Vector' 与子包 'math.Vector' 冲突
    public static func create(): Vector {
        return Vector()
    }
}
cangjie 复制代码
// ✅ 正确示例 - 避免包名冲突
package cangjie_blog.math.Vector
public class MathVector { // 使用不同的名称避免冲突
    public static func create(): MathVector {
        return MathVector()
    }
}

程序入口(Program Entry)

main 函数规则

仓颉程序入口为 main,源文件根目录下的包的顶层最多只能有一个 main

main 函数签名

  1. 无参数的 main
cangjie 复制代码
// main.cj
main(): Int64 {
    println("Hello, Cangjie!")
    return 0
}
  1. 带命令行参数的 main
cangjie 复制代码
// main.cj
package cangjie_blog

import std.collection.enumerate

main(args: Array<String>): Unit {
    println("程序启动,参数数量:${args.size}")

    for ((i, arg) in enumerate(args)) {
        println("参数 ${i}: ${arg}")
    }

    // 处理命令行参数
    if (args.size > 0) {
        let firstArg = args[0]
        if (firstArg == "--help") {
            println("使用方法:./main [选项]")
            println("选项:")
            println("  --help    显示帮助信息")
            println("  --version 显示版本信息")
        } else if (firstArg == "--version") {
            println("仓颉语言程序 v1.0.0")
        }
    }
}

main 函数限制

  • 不可被访问修饰符修饰
  • 返回值类型必须为 Unit 或整数类型
  • 参数类型必须为 Array<String> 或无参数
  • 当包被导入时,包中定义的 main 不会被导入

错误示例

cangjie 复制代码
// ❌ 错误:返回值类型不正确
main(): String {
    return "Hello" // Error: return type of 'main' is not 'Integer' or 'Unit'
}

// ❌ 错误:参数类型不正确
main(args: Array<Int32>): Int64 {
    return 0 // Error: 'main' cannot be defined with parameter whose type is not Array<String>
}

// ❌ 错误:多个 main 函数
main(args: Array<String>): Int32 {
    return 0
}

main(): Int8 { // Error: multiple 'main's are found in source files
    return 0
}

包的导入(Package Import)

基本导入语法

1. 导入单个项目

cangjie 复制代码
package cangjie_blog
import std.math.sqrt
const PI: Float64 = 3.14159
main(): Int32 {
    let result = sqrt(16.0)
    let area = PI * 5.0 * 5.0
    
    println("√16 = ${result}")
    println("圆的面积:${area}")
    
    return 0
}

2. 导入多个项目

cangjie 复制代码
package cangjie_blog

import std.math.{sqrt, abs}
import std.collection.max

main(): Int32 {
    let numbers = [3.14, -2.5, 10.0, -7.8]

    for (num in numbers) {
        let absValue = abs(num)
        println("|${num}| = ${absValue}")
    }

    let maxValue = max(numbers)
    println("最大值:${maxValue}")

    return 0
}

3. 导入整个包

cangjie 复制代码
package cangjie_blog

import std.math.*

const PI = 3.1415926

main(): Int32 {
    // 可以直接使用 math 包中的所有公共函数和常量
    let result = sqrt(25.0)
    let sinValue = sin(PI / 2.0f64)
    let cosValue = cos(0.0)

    println("√25 = ${result}")
    println("sin(π/2) = ${sinValue}")
    println("cos(0) = ${cosValue}")

    return 0
}

导入规则和限制

1. 导入位置

导入语句必须在包声明之后,其他声明或定义之前:

cangjie 复制代码
package cangjie_blog

// ✅ 正确:导入语句在包声明之后
import std.math.*

// 其他代码...
public func processData(): Unit {
    // 函数实现
}

2. 循环依赖禁止

包之间不能存在循环依赖:

cangjie 复制代码
// ❌ 错误:循环依赖
package cangjie_blog.pkga

import cangjie_blog.pkgb.* // Error: packages pkga pkgb are in circular dependencies

public class ClassA {
    public func method(): Unit {}
}

package cangjie_blog.pkgb

import cangjie_blog.pkga.* // Error: packages pkga pkgb are in circular dependencies

public class ClassB {
    public func method(): Unit {}
}

3. 不能导入当前包

cangjie 复制代码
// ❌ 错误:不能导入当前包
package cangjie_blog

import cangjie_blog.someFunction // Error: packages cangjie_blog are in circular dependencies

public func someFunction(): Unit {}
main() {
    
}

导入冲突解决

1. 使用 import as 重命名

cangjie 复制代码

2. 使用包名作为命名空间

cangjie 复制代码
// 解决不同包中同名类型的冲突
package cangjie_blog

// 从不同包导入同名的类,这里还有一个问题,包名不规范,包名最好都是小写
import cangjie_blog.geometry.Vector as GeoVector
import cangjie_blog.math.Vector as MathVector

main(): Int32 {
    // 使用重命名后的类型
    let geoVec = GeoVector()
    let mathVec = MathVector()
    return 0
}

隐式导入

编译器会自动为源码隐式导入 core 包中所有的 public 修饰的声明,这就是为什么 StringRange 等类型能直接使用的原因。

重导出(Re-export)

访问修饰符修饰的 import

import 可以被访问修饰符修饰,实现重导出功能:

cangjie 复制代码
// 包 a 重导出包 b 中的函数
package cangjie_blog.a
public import cangjie_blog.a.b.{calculate, multiply}

public let x = 0
cangjie 复制代码
// 包 a.b 中定义函数
internal package a.b

public func calculate(a: Int32, b: Int32): Int32 {
    return a + b
}

public func multiply(a: Int32, b: Int32): Int32 {
    return a * b
}
cangjie 复制代码
// 其他包可以直接导入 a 中的函数,无需从 a.b 导入
package cangjie_blog.imp

import cangjie_blog.a.{calculate, multiply}

main(): Int32 {
    let result1 = calculate(10, 20)
    let result2 = multiply(5, 6)

    println("10 + 20 = ${result1}")
    println("5 * 6 = ${result2}")

    return 0
}

访问修饰符级别

修饰符 含义 默认值
private 仅当前文件内可访问 import 的默认值
internal 当前包及其子包可访问 其他声明的默认值
protected 当前模块内可访问 -
public 模块内外均可访问 package 的默认值

重导出限制

包不可以被重导出:

cangjie 复制代码
// ❌ 错误:不能重导出包
// imported package name 'cangjie_blog.a.b' cannot be modified by 'public'
public import cangjie_blog.a.b

顶层声明的可见性(Top-level Access Control)

访问修饰符详解

1. private - 文件级可见性

cangjie 复制代码
package cangjie_blog.visibility

// private 修饰的函数仅在当前文件内可见
private func internalHelper(): String {
    return "这是内部辅助函数"
}

// 其他函数可以调用 private 函数
public func publicFunction(): String {
    return "公共函数调用:" + internalHelper()
}

// 但是其他文件无法访问 internalHelper

2. internal - 包级可见性

cangjie 复制代码
package cangjie_blog.visibility

// internal 修饰的函数在当前包及子包内可见
internal func packageHelper(): String {
    return "这是包级辅助函数"
}

// 同一包内的其他函数可以调用
public func anotherFunction(): String {
    return "另一个函数:" + packageHelper()
}
cangjie 复制代码
// 子包中可以导入并使用
package cangjie_blog.visibility.sub
import cangjie_blog.visibility.packageHelper

public func subPackageFunction(): String {
    return "子包函数:" + packageHelper() // ✅ 可以访问
}

3. protected - 模块级可见性

cangjie 复制代码
package cangjie_blog.visibility

// protected 修饰的函数在当前模块内可见
protected func moduleHelper(): String {
    return "这是模块级辅助函数"
}

// 同一模块内的其他包可以导入使用
cangjie 复制代码
// 同一模块内的其他包
package cangjie_blog.visibilitytest

import cangjie_blog.visibility.moduleHelper
// 'packageHelper' is not accessible in package 'cangjie_blog.visibility'
// import cangjie_blog.visibility.packageHelper
// 'internalHelper' is not accessible in package 'cangjie_blog.visibility'
// import cangjie_blog.visibility.internalHelper

public func otherFunction(): String {
    return "其他包函数:" + moduleHelper() // ✅ 可以访问
}

4. public - 全局可见性

cangjie 复制代码
package cangjie_blog.visibility
// public 修饰的函数在所有地方都可见
public func globalFunction(): String {
    return "这是全局可见的函数"
}

// 可以被任何包导入使用
cangjie 复制代码
// 任何其他包都可以导入
package cangjie_blog.visibilitytest

// import cangjie_blog.visibility.moduleHelper
// 'packageHelper' is not accessible in package 'cangjie_blog.visibility'
// import cangjie_blog.visibility.packageHelper
// 'internalHelper' is not accessible in package 'cangjie_blog.visibility'
// import cangjie_blog.visibility.internalHelper
import cangjie_blog.visibility.globalFunction

// public func otherFunction(): String {
//     return "其他包函数:" + moduleHelper() // ✅ 可以访问
// }

public func externalFunction(): String {
    return "外部包函数:" + globalFunction() // ✅ 可以访问
}

访问级别规则

1. 访问级别排序

public > protected > internal > private

2. 声明访问级别限制

一个声明的访问修饰符不得高于该声明中用到的类型的访问修饰符的级别:

cangjie 复制代码
package cangjie_blog.access

// internal 类
class InternalClass {
    public func method(): Unit {}
}

// ❌ 错误:public 函数不能使用 internal 类型
// 'public' declaration uses lower access level types
// public func publicFunction(param: InternalClass): InternalClass {
//     return param // Error: public declaration cannot use internal type
// }

// ✅ 正确:internal 函数可以使用 internal 类型
internal func internalFunction(param: InternalClass): InternalClass {
    return param
}

// ✅ 正确:public 函数可以使用 public 类型
public func anotherPublicFunction(param: String): String {
    return param
}

3. 泛型类型约束

cangjie 复制代码
package cangjie_blog.access

// internal 接口
interface InternalInterface {
    func method(): Unit 
}

// ❌ 错误:public 泛型类不能使用 internal 接口作为约束
// 'public' declaration uses 'internal' types
// public class PublicGeneric<T> where T <: InternalInterface {
//     // Error: public declaration cannot use internal type
// }

// ✅ 正确:internal 泛型类可以使用 internal 接口
internal class InternalGeneric<T> where T <: InternalInterface {
    // 实现...
}

特殊情况

1. public 声明的内部实现

public 修饰的声明在其初始化表达式或者函数体里面可以使用本包可见的任意类型:

cangjie 复制代码
package access

// internal 类
class InternalClass {
    public func method(): String {
        return "internal method"
    }
}

// internal 函数
internal func internalFunction(): String {
    return "internal function"
}

// ✅ public 函数内部可以使用 internal 类型
public func publicFunction(): String {
    let obj = InternalClass()        // ✅ 可以创建 internal 类型实例
    let result = internalFunction()  // ✅ 可以调用 internal 函数
    return obj.method() + " + " + result
}

// ✅ public 变量可以使用 internal 类型
public let publicVariable: String = internalFunction() // ✅ 可以调用 internal 函数

// ✅ public 类内部可以使用 internal 类型
public class PublicClass {
    private let internalObj = InternalClass() // ✅ 可以创建 internal 类型实例
    
    public func method(): String {
        return internalObj.method() // ✅ 可以调用 internal 方法
    }
}

2. 内置类型默认访问级别

内置类型诸如 RuneInt64 等默认的修饰符是 public

cangjie 复制代码
package cangjie_blog.access

// ✅ 正确:public 变量可以使用内置类型
public let publicNumber: Int64 = 42
public let publicString: String = "Hello"
public let publicRune: Rune = 'A'

// ✅ 正确:public 函数可以使用内置类型
public func publicFunction2(): Int64 {
    let localNumber: Int32 = 100
    return Int64(localNumber)
}

实际项目示例

让我创建一个完整的项目示例来展示包系统的使用:

项目结构

css 复制代码
src/
├── main.cj
├── math/
│   ├── arithmetic.cj
│   ├── geometry.cj
│   └── constants.cj
├── utils/
│   ├── formatter.cj
│   └── validator.cj
└── models/
    ├── point.cj
    └── rectangle.cj

具体实现

1. 数学包 - 算术运算

cangjie 复制代码
// src/math/arithmetic.cj
package cangjie_blog.math

public func add(a: Int32, b: Int32): Int32 {
    return a + b
}

public func subtract(a: Int32, b: Int32): Int32 {
    return a - b
}

public func multiply(a: Int32, b: Int32): Int32 {
    return a * b
}

public func divide(a: Int32, b: Int32): Float64 {
    if (b == 0) {
        throw Exception("除数不能为零")
    }
    return Float64(a) / Float64(b)
}

public func power(base: Int32, exponent: Int32): Int64 {
    if (exponent < 0) {
        throw Exception("指数不能为负数")
    }

    var result: Int64 = 1
    var base64 = Int64(base)
    var exp = exponent

    while (exp > 0) {
        if (exp % 2 == 1) {
            result = result * base64
        }
        base64 = base64 * base64
        exp = exp / 2
    }

    return result
}

2. 数学包 - 几何运算

cangjie 复制代码
// src/math/geometry.cj
package cangjie_blog.math

public func circleArea(radius: Float64): Float64 {
    return PI * radius * radius
}

public func circleCircumference(radius: Float64): Float64 {
    return 2.0 * PI * radius
}

public func rectangleArea(width: Float64, height: Float64): Float64 {
    return width * height
}

public func rectanglePerimeter(width: Float64, height: Float64): Float64 {
    return 2.0 * (width + height)
}

public func triangleArea(base: Float64, height: Float64): Float64 {
    return 0.5 * base * height
}

public func trianglePerimeter(a: Float64, b: Float64, c: Float64): Float64 {
    return a + b + c
}

3. 数学包 - 常量

cangjie 复制代码
// src/math/constants.cj
package cangjie_blog.math

public let PI: Float64 = 3.14159265359
public let E: Float64 = 2.71828182846
public let GOLDEN_RATIO: Float64 = 1.61803398875
public let SQRT2: Float64 = 1.41421356237
public let SQRT3: Float64 = 1.73205080757

4. 工具包 - 格式化

cangjie 复制代码
// src/utils/formatter.cj
package cangjie_blog.utils

import cangjie_blog.math.PI
import std.math.{round, pow}

public func formatFloat(value: Float64, precision: Int32): String {
    let factor = pow(10.0f64, Float64(precision))
    let rounded = round((value * factor)) / factor
    return "${rounded}"
}

public func formatPercentage(value: Float64): String {
    return "${value * Float64(100)}%"
}

public func formatCurrency(amount: Float64, currency: String): String {
    return "${currency}\\${formatFloat(amount, 2)}"
}

5. 工具包 - 验证器

cangjie 复制代码
// src/utils/validator.cj
package cangjie_blog.utils

public func isValidEmail(email: String): Bool {
    // 简单的邮箱验证
    return email.contains("@") && email.contains(".")
}

public func isValidPhone(phone: String): Bool {
    // 简单的手机号验证(假设11位数字)
    if (phone.size != 11) {
        return false
    }
    
    for (char in phone.toRuneArray()) {
        if (char < r'0' || char > r'9') {
            return false
        }
    }
    
    return true
}

public func isValidAge(age: Int64): Bool {
    return age >= 0 && age <= 150
}

public func isValidPassword(password: String): Bool {
    // 密码至少8位,包含字母和数字
    if (password.size < 8) {
        return false
    }
    
    var hasLetter = false
    var hasDigit = false
    
    for (char in password.toRuneArray()) {
        if ((char >= r'a' && char <= r'z') || (char >= r'A' && char <= r'Z')) {
            hasLetter = true
        } else if (char >= r'0' && char <= r'9') {
            hasDigit = true
        }
    }
    
    return hasLetter && hasDigit
}

6. 模型包 - 点

cangjie 复制代码
// src/models/point.cj
package cangjie_blog.models
import std.math.sqrt
public struct Point <: ToString {
    public let x: Float64
    public let y: Float64
    
    public init(x!: Float64, y!: Float64) {
        this.x = x
        this.y = y
    }
    
    public func distance(to!: Point): Float64 {
        let dx = this.x - to.x
        let dy = this.y - to.y
        return sqrt(dx * dx + dy * dy)
    }
    
    public func add(other: Point): Point {
        return Point(x: this.x + other.x, y: this.y + other.y)
    }
    
    public func subtract(other: Point): Point {
        return Point(x: this.x - other.x, y: this.y - other.y)
    }
    
    public func multiply(scalar: Float64): Point {
        return Point(x: this.x * scalar, y: this.y * scalar)
    }
    
    public func toString(): String {
        return "(${x}, ${y})"
    }
}

7. 模型包 - 矩形

cangjie 复制代码
// src/models/rectangle.cj
package cangjie_blog.models
import cangjie_blog.math.{rectangleArea, rectanglePerimeter}

public struct Rectangle <: ToString {
    public let topLeft: Point
    public let bottomRight: Point

    public init(topLeft: Point, bottomRight: Point) {
        this.topLeft = topLeft
        this.bottomRight = bottomRight
    }

    public init(x1!: Float64, y1!: Float64, x2!: Float64, y2!: Float64) {
        this.topLeft = Point(x: x1, y: y1)
        this.bottomRight = Point(x: x2, y: y2)
    }

    public func width(): Float64 {
        return bottomRight.x - topLeft.x
    }

    public func height(): Float64 {
        return bottomRight.y - topLeft.y
    }

    public func area(): Float64 {
        return rectangleArea(width(), height())
    }

    public func perimeter(): Float64 {
        return rectanglePerimeter(width(), height())
    }

    public func contains(point: Point): Bool {
        return point.x >= topLeft.x && point.x <= bottomRight.x && point.y <= topLeft.y && point.y >= bottomRight.y
    }

    public func toString(): String {
        return "Rectangle(${topLeft} to ${bottomRight})"
    }
}

8. 主程序

cangjie 复制代码
package cangjie_blog
// cjlint-ignore -start !G.OTH.03 !G.OTH.02
// 主程序,可以省略包声明
import cangjie_blog.math.*
import cangjie_blog.utils.*
import cangjie_blog.models.*

main(): Int32 {
    println("=== 仓颉语言包系统演示 ===\n")

    // 测试算术运算
    println("1. 算术运算测试:")
    let sum = add(15, 25)
    let product = multiply(6, 7)
    let quotient = divide(100, 3)

    println("   15 + 25 = ${sum}")
    println("   6 × 7 = ${product}")
    println("   100 ÷ 3 = ${formatFloat(quotient, 2)}")
    println("   2^8 = ${power(2, 8)}\n")

    // 测试几何运算
    println("2. 几何运算测试:")
    let radius = 5.0
    let circleArea = circleArea(radius)
    let circleCirc = circleCircumference(radius)

    println("   半径为 ${radius} 的圆:")
    println("   面积:${formatFloat(circleArea, 2)}")
    println("   周长:${formatFloat(circleCirc, 2)}\n")

    // 测试模型
    println("3. 模型测试:")
    let p1 = Point(x: 0.0, y: 0.0)
    let p2 = Point(x: 3.0, y: 4.0)
    let distance = p1.distance(to: p2)

    println("   点 ${p1} 到点 ${p2} 的距离:${formatFloat(distance, 2)}")

    let rect = Rectangle(x1: 0.0, y1: 0.0, x2: 5.0, y2: 3.0)
    println("   矩形:${rect}")
    println("   面积:${formatFloat(rect.area(), 2)}")
    println("   周长:${formatFloat(rect.perimeter(), 2)}\n")

    // 测试工具函数
    println("4. 工具函数测试:")
    let email = "test@example.com"
    let phone = "13800138000"
    let age = 25
    let password = "SecurePass123"

    println("   邮箱 ${email} 是否有效:${isValidEmail(email)}")
    println("   手机号 ${phone} 是否有效:${isValidPhone(phone)}")
    println("   年龄 ${age} 是否有效:${isValidAge(age)}")
    println("   密码是否有效:${isValidPassword(password)}\n")

    // 测试格式化
    println("5. 格式化测试:")
    let percentage = 0.856
    let currency = 1234.56

    println("   百分比:${formatPercentage(percentage)}")
    println("   货币:${formatCurrency(currency, "¥")}")
    println("   精确到3位小数:${formatFloat(PI, 3)}\n")

    println("=== 演示完成 ===")
    return 0
}
// cjlint-ignore -end

最佳实践

1. 包命名规范

  • 使用小写字母和下划线
  • 包名要反映功能模块
  • 避免与标准库冲突

2. 导入组织

  • 按标准库、第三方库、本地包的顺序组织导入
  • 使用具体的导入而不是通配符导入(除非必要)
  • 及时清理未使用的导入

3. 访问控制

  • 默认使用 internal 访问级别
  • 只在必要时使用 public
  • 合理使用 private 隐藏内部实现

4. 包结构设计

  • 按功能模块组织包
  • 避免过深的包层次
  • 保持包的职责单一

总结

仓颉语言的包系统提供了强大的代码组织和模块化能力。通过合理使用包声明、导入、访问控制和重导出,我们可以:

  1. 提高代码可维护性:将相关功能组织在一起
  2. 增强代码复用性:通过导入和重导出共享功能
  3. 控制代码可见性:使用访问修饰符保护内部实现
  4. 避免命名冲突:通过包名空间隔离不同模块

参考资料

相关推荐
Georgewu11 小时前
【 HarmonyOS 】错误描述:The certificate has expired! 鸿蒙证书过期如何解决?
harmonyos
Georgewu11 小时前
【HarmonyOS】一步解决弹框集成-快速弹框QuickDialog使用详解
harmonyos
爱笑的眼睛1111 小时前
HarmonyOS 应用开发:基于API 12+的现代化开发实践
华为·harmonyos
冯志浩14 小时前
Harmony Next - 手势的使用(一)
harmonyos·掘金·金石计划
奶糖不太甜15 小时前
鸿蒙ArkUI开发常见问题解决方案:从布局到事件响应全解析
harmonyos·arkui
鸿蒙先行者15 小时前
鸿蒙调试工具连接失败解决方案与案例分析
harmonyos
鸿蒙小灰16 小时前
ArkWeb优化方法及案例
harmonyos·arkweb
HarmonyOS小助手16 小时前
货拉拉开源两款三方库,为鸿蒙应用高效开发贡献力量
harmonyos·鸿蒙·鸿蒙生态
HarderCoder19 小时前
重学仓颉-10集合类型完全指南:从基础到高级应用
harmonyos