重学仓颉-1从零开始学习现代编程语言

引言

仓颉编程语言(Cangjie Programming Language)是一种面向全场景应用开发的通用编程语言,它融合了多种编程范式的优点,旨在提供高效、安全、易用的开发体验。本文将带你深入了解仓颉语言的核心特性、安装配置以及第一个程序的编写。

一、仓颉语言概述

1.1 语言特点

仓颉编程语言具有以下核心特点:

1.1.1 多后端支持

仓颉语言支持两种后端:

  • CJNative 后端:将代码编译为原生二进制代码,直接在操作系统层面运行
  • CJVM 后端:将代码编译为字节码,基于虚拟机运行
cangjie 复制代码
// 示例:编译为原生二进制(CJNative后端)
// 使用命令:cjc hello.cj -o hello
main(): Unit {
    println("Hello, Cangjie Native!")
}

1.1.2 语法简明高效

仓颉语言提供了多种简化语法:

cangjie 复制代码
// 1. 插值字符串
let name = "World"
let message = "Hello, ${name}!"  // 字符串插值

// 2. 主构造函数
class Point {
    public Point(let x: Int64, let y: Int64) {}
}

// 3. if 表达式
let result = if (x > 0) {
    "positive"
} else {
    "negative"
}

// 4. match 表达式
let status = match (code) {
    case 200 => "OK"
    case 404 => "Not Found"
    case _ => "Unknown"
}

1.1.3 多范式编程支持

cangjie 复制代码
// 函数式编程特性
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers |> map {x => x * 2}  // 高阶函数
let evens = numbers |> filter {x => x % 2 == 0}  // 过滤

// 面向对象编程特性
interface Drawable {
    func draw(): Unit
}

class Circle <: Drawable {
    let radius: Float64
    
    public init(radius: Float64) {
        this.radius = radius
    }
    
    public func draw(): Unit {
        println("Drawing circle with radius ${radius}")
    }
}

// 命令式编程特性
func factorial(n: Int64): Int64 {
    var result = 1
    var i = 1
    while (i <= n) {
        result *= i
        i += 1
    }
    return result
}

1.1.4 类型安全

cangjie 复制代码
// 静态强类型,编译时类型检查
let x: Int64 = 42  // 明确类型声明
let y = 3.14  // 类型推断为 Float64
let z = "hello"  // 类型推断为 String

// 类型不匹配会在编译时报错
// let error = x + z  // 编译错误:Int64 和 String 不能相加

1.1.5 内存安全

cangjie 复制代码
// 自动内存管理
class SafeBuffer {
    private let data: Array<Int64>
    
    public init(size: Int64) {
        this.data = Array<Int64>(size, {i => 0})
    }
    
    // 自动进行边界检查
    public func get(index: Int64): Int64 {
        if (index >= 0 && index < this.data.size) {
            return this.data[index]
        } else {
            return 0  // 安全返回默认值
        }
    }
}

1.1.6 高效并发

cangjie 复制代码
// 用户态轻量化线程(原生协程)

func worker(id: Int64) {
    for (i in 0..5) {
        println("Worker ${id}: ${i}")
        sleep(Duration.millisecond * 100) // 休眠100毫秒
    }
}

main() {
    // 创建多个并发线程
    let future1 = spawn {
     worker(1)   
    }
    let future2 = spawn {
        worker(2)
    }

    let v1 = future1.get()
    let v2 = future2.get()
}

1.1.7 兼容语言生态

cangjie 复制代码
// C语言互操作示例

// 声明C函数
foreign func printf(fmt: CString, ...): Int32

main() {
    unsafe {
        var fmt = LibC.mallocCString("Hello, No.%d\n")
        printf(fmt, 1)
        LibC.free(fmt)
    }
}

1.1.8 领域易扩展

cangjie 复制代码
// define/define.cj
macro package cj_demo.define
import std.ast.*
// 宏编程示例
public macro dprint(input: Tokens): Tokens {
    // 将输入的程序片段转化为字符串
    let inputStr = input.toString()
    // quote 表达式是用于构造 Tokens 的一种表达式,它将括号内的程序片段转换为 Tokens
    let result = quote({=>
        print($(inputStr) + " = ")
        println($(input))
        $(input)
    }()
    )
    return result
}

// main.cj
import cj_demo.define.*

main():Unit {
    @dprint(1 + 2)
}

1.1.9 助力UI开发

cangjie 复制代码
// 声明式UI框架示例(概念性)
class Button {
    let text: String
    let onClick: () -> Unit

    public init(text: String, onClick: () -> Unit) {
        this.text = text
        this.onClick = onClick
    }
}

main() {
    // 使用尾随lambda语法
    let button = Button("Click me", {
        => println("Button clicked!")
    })
}

1.1.10 内置库功能丰富

cangjie 复制代码
import std.convert.*
import std.crypto.digest.*
import stdx.encoding.hex.*
import stdx.crypto.keys.*
import std.io.*
import std.fs.*
import stdx.crypto.x509.*
import std.time.*

二、安装仓颉工具链

2.1 系统要求

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 额外依赖:

bash 复制代码
sudo apt-get install binutils libc-dev libc++-dev libgcc-7-dev

macOS 系统要求

  • macOS 12.0 及以上版本
  • 安装依赖:
bash 复制代码
brew install libffi

Windows 系统要求

  • Windows 10 及以上版本
  • 支持 x64 架构

2.2 安装步骤

Linux/macOS 安装

  1. 下载安装包
bash 复制代码
# 根据你的系统架构选择对应的安装包
# x86_64 Linux: cangjie-sdk-linux-x64-x.y.z.tar.gz
# aarch64 Linux: cangjie-sdk-linux-aarch64-x.y.z.tar.gz
# x86_64 macOS: cangjie-sdk-mac-x64-x.y.z.tar.gz
# aarch64 macOS: cangjie-sdk-mac-aarch64-x.y.z.tar.gz
  1. 解压安装包
bash 复制代码
tar xvf cangjie-sdk-linux-x64-x.y.z.tar.gz
  1. 配置环境
bash 复制代码
source cangjie/envsetup.sh
  1. 验证安装
bash 复制代码
cjc -v
  1. 永久配置(可选)
bash 复制代码
# 编辑 ~/.bashrc 或 ~/.zshrc
echo 'source /path/to/cangjie/envsetup.sh' >> ~/.bashrc

Windows 安装

  1. exe 安装包

    • 直接运行 cangjie-sdk-windows-x64-x.y.z.exe
    • 跟随安装向导完成安装
  2. zip 安装包

cmd 复制代码
# CMD 环境
path\to\cangjie\envsetup.bat

# PowerShell 环境
. path\to\cangjie\envsetup.ps1

# MSYS/bash 环境
source path/to/cangjie/envsetup.sh
  1. 验证安装
cmd 复制代码
cjc -v

2.3 环境变量配置

Windows 永久配置

  1. 设置 CANGJIE_HOME 环境变量
  2. Path 中添加以下路径:
    • %CANGJIE_HOME%\bin
    • %CANGJIE_HOME%\tools\bin
    • %CANGJIE_HOME%\tools\lib
    • %CANGJIE_HOME%\runtime\lib\windows_x86_64_llvm
    • %USERPROFILE%\.cjpm\bin

2.4 卸载和更新

卸载

bash 复制代码
# Linux/macOS
rm -rf /path/to/cangjie

# Windows (exe安装)
# 运行 unins000.exe

# Windows (zip安装)
# 删除安装目录并移除环境变量

更新

  1. 卸载当前版本
  2. 下载并安装新版本

三、第一个仓颉程序

3.1 Hello World 程序

创建文件 hello.cj

cangjie 复制代码
// hello.cj - 第一个仓颉程序
// 这是单行注释

/*
 * 这是多行注释
 * 可以跨越多行
 */

main() {
    println("你好,仓颉!")
    println("Hello, Cangjie!")
}

3.2 编译和运行

Linux/macOS

bash 复制代码
# 编译
cjc hello.cj -o hello

# 运行
./hello

Windows

cmd 复制代码
# 编译
cjc hello.cj -o hello.exe

# 运行
hello.exe

3.3 程序结构解析

cangjie 复制代码
// 1. 注释语法
// 单行注释以 // 开始
/* 多行注释
   可以跨越多行 */

// 2. 主函数
main() {
    // 程序入口点
    // 每个可执行程序必须有 main 函数
}

// 3. 输出函数
println("文本")  // 输出并换行
print("文本")    // 输出不换行

3.4 扩展示例

cangjie 复制代码
// 更复杂的 Hello World 示例
import std.time.DateTime

func getGreeting(): String {
    let hour = DateTime.now().hour
    if (hour < 12) {
        return "早上好"
    } else if (hour < 18) {
        return "下午好"
    } else {
        return "晚上好"
    }
}

func printInfo() {
    println("=== 仓颉编程语言示例 ===")
    println("当前时间: ${DateTime.now()}")
    println("问候语: ${getGreeting()}")
    println("========================")
}

main() {
    printInfo()
    // 变量声明和使用
    let name = "开发者"
    let version = "1.0.0"

    println("欢迎 ${name} 使用仓颉语言 ${version}")

    // 简单计算
    let a = 10
    let b = 20
    let sum = a + b
    println("${a} + ${b} = ${sum}")
}

四、开发工具和最佳实践

4.1 开发工具链

仓颉语言提供了完整的开发工具链:

bash 复制代码
# 编译器
cjc source.cj -o output

# 包管理器
cjpm install package_name
cjpm init
cjpm build

# 调试器
cjdb program

# 格式化工具
cjfmt source.cj

# 静态检查
# 集成在编译器中

4.2 项目结构示例

tree 复制代码
my_project/
├── src/
│   ├── main.cj
│   ├── utils.cj
│   └── models/
│       └── user.cj
├── tests/
│   └── test_main.cj
├── docs/
│   └── README.md
├── cjpm.toml
└── .gitignore

4.3 代码组织最佳实践

cangjie 复制代码
// 1. 模块化设计
// utils/format.cj
package cj_demo.utils

import std.collection.{map, collectArray}

public func formatString(prefix: String, args: Array<String>): String {
    let s: Array<String> = args |> map {s: String => prefix + s} |> collectArray
    return s.toString()
}

// 2. 主程序
// main.cj
import cj_demo.utils.formatString

main() {
    // 常规传参
    let result = formatString("Hello", ["world", "word2"])
    // 最后一个参数为Array时,可以可变传参
    let result2 = formatString("Hello", "world", "word2")
}

五、常见问题和解决方案

5.1 编译错误

cangjie 复制代码
// 错误:未定义变量
main() {
    println(undefined_variable)  // 编译错误
}

// 正确:先声明变量
main() {
    let message = "Hello"
    println(message)  // 正确
}

5.2 运行时错误

cangjie 复制代码
// 错误:数组越界
main() {
    let arr = [1, 2, 3]
    println(arr[10])  // 运行时错误
}

// 正确:检查边界
main() {
    let arr = [1, 2, 3]
    if (arr.size > 10) {
        println(arr[10])
    } else {
        println("索引越界")
    }
}

5.3 环境配置问题

bash 复制代码
# 问题:找不到 cjc 命令
# 解决方案:检查环境变量
echo $PATH
which cjc

# 重新配置环境
source /path/to/cangjie/envsetup.sh

六、进阶学习路径

6.1 学习顺序建议

  1. 基础语法:变量、函数、控制流
  2. 数据类型:基本类型、集合类型
  3. 面向对象:类、接口、继承
  4. 函数式编程:高阶函数、闭包
  5. 并发编程:线程、同步
  6. 系统编程:FFI、网络、文件IO
  7. 元编程:宏、反射

6.2 实践项目建议

cangjie 复制代码
// 1. 计算器项目
class Calculator {
    func add(a: Float64, b: Float64): Float64 {
        a + b
    }
    func subtract(a: Float64, b: Float64): Float64 {
        a - b
    }
    func multiply(a: Float64, b: Float64): Float64 {
        a * b
    }
    func divide(a: Float64, b: Float64): Float64 {
        if (Int64(b) == 0) {
            return 0.0f64
        } // 避免除零错误
        a / b
    }
}

// 2. 文件处理工具
import std.fs.*

func processFile(filePath: String) {
    if (exists(filePath)) {
        let file = File(filePath, OpenMode.Read)
        let content = file.read()
        println("文件内容: ${content}")
    } else {
        println("文件不存在: ${filePath}")
    }
}

七、总结

仓颉编程语言作为一门现代编程语言,具有以下优势:

  1. 多范式支持:同时支持函数式、面向对象和命令式编程
  2. 类型安全:静态强类型系统,编译时错误检查
  3. 内存安全:自动内存管理,运行时安全检查
  4. 高效并发:原生协程支持,简化并发编程
  5. 生态兼容:支持C语言互操作,易于集成现有库
  6. 开发效率:丰富的内置库,现代化的语法特性

参考资料

相关推荐
奶糖不太甜2 小时前
鸿蒙UI布局不兼容解决方案笔记
harmonyos
小小小小小星3 小时前
鸿蒙开发调试技巧整理
harmonyos
HarderCoder3 小时前
重学仓颉-2基础编程概念详解
harmonyos
RAY_01046 小时前
2024鸿蒙样题需要掌握的知识点
华为·harmonyos
御承扬6 小时前
HarmonyOS NEXT系列之元服务框架ASCF
华为·harmonyos
li理10 小时前
鸿蒙应用开发深度解析:从基础列表到瀑布流,全面掌握界面布局艺术
前端·前端框架·harmonyos
万少1 天前
可可图片编辑 HarmonyOS(2) 选择图片和保存到图库
harmonyos
小小小小小星1 天前
鸿蒙开发性能优化实战指南:从工具到代码全解析
性能优化·harmonyos
奶糖不太甜1 天前
鸿蒙元应用与服务卡片技术文档及案例
harmonyos