倉頡編程語言:從入門到精通

為啥要瞅瞅倉頡這玩意兒?

有一說一,現在的編程語言多得跟米一樣,對吧?那一門新語言想火,沒點絕活兒肯定不行。倉頡(Cangjie)這哥們兒,是華為搞出來的新玩意兒,靜態編譯的,主打的就是一個現代化、性能炸裂、安全感滿滿,而且天生就會搞并發。就憑這幾點,已經有不少大佬開始關注了。

這篇博客呢,就是你的“老司機”指南,帶你把倉頡這車開得明明白白。不管你是剛上路的小白,還是開慣了 Rust、Go、Java、Node.js 的老司機,都能在這兒找到感覺。咱就從最簡單的“Hello, World!”開整,一步步把它那些牛逼的特性,比如啥類型系統、并發模型都給扒個底朝天。走了您內!

一:剛認識,混個臉熟 —— 裝一下,跑個 Demo

萬事開頭難?不存在的,倉頡上手簡直不要太絲滑。

1. 安裝,搞定環境

整個安裝過程跟其他新潮語言差不多,用官方給的工具 cj 一條龍服務,輕松搞定。

  • 逛官網: 直接去倉頡官網下載頁。

  • 跑腳本: 看你電腦是啥系統(Windows, macOS, Linux),復制粘貼對應的命令就完事兒了。

# 比如你是 Linux/macOS
$ curl --proto '=https' --tlsv1.2 -sSf https://cangjie-lang.cn/install.sh | sh

裝完之后,把路徑配一下,就能在命令行里使喚 cj 了。

$ cj --version
cj version x.x.x

2. 你好啊,倉頡!

老規矩,咱得讓它跟世界打個招呼。

新建一個 main.cj 文件,把下面這幾行代碼粘進去:

// main.cj
// 意思是從 'std::io' 這個庫里,把 'println' 這函數拿來用
use std::io;// 這就是程序的入口,從這兒開始跑
public func main(): void {io::println("你好,倉頡!");
}

給你白話白話:

  • use std::io;: 就是告訴編譯器,“嘿,我要用標準庫(std)里管輸入輸出(io)的工具了”。跟 Rust 的 use 或者 Java 的 import 一個意思。

  • public func main(): void: 這就是程序的啟動點。

    • public: 公開的,誰都能調用。

    • func: 關鍵字,意思是“這是個函數”。

    • main: 函數名,main 函數就是老大,程序從它開始執行。

    • (): void: 括號里沒東西,說明沒參數;void 意思是這函數干完活兒不給回信兒(沒返回值)。

編譯跑起來:

打開你的黑框框(終端),用 cj 命令編譯運行一把。

# 編譯順便跑一下 main.cj
$ cj run main.cj
你好,倉頡!

圖解一下這過程:

+------------+     一頓操作     +-----------------+     跑一下     +----------------+
| main.cj    |  (cj build)  >   |  一個能跑的文件    |  (cj run)  >  |  屏幕上出現      |
| (你的代碼)   |                 |  (比如 main.exe) |             | "你好,倉頡!"   |
+------------+                 +-----------------+             +----------------+

二:核心玩法 —— 變量、類型和流程控制

基礎整明白了,咱再往里看看它的筋骨。

1. 變量和數據類型

記住,倉頡是門靜態強類型語言。說人話就是,你定義一個變量是啥類型,它這輩子就是啥類型,在跑之前就得定好。

public func main(): void {// 聲明個變量,存點東西// let 聲明的是個常量,不能改let message: string = "這是一個常量,鐵打的";// var 聲明的是個變量,想改就改var count: int = 0;count = count + 1; // 沒毛病// 它還挺聰明,能自己猜類型let implicit_message = "我不用說,它也知道我是字符串"; // 自動猜出是 stringvar implicit_count = 10; // 自動猜出是 int
}

跟別的語言比比看:

  • Rust: 不能說像,簡直是一毛一樣。Rust 用 letlet mut。倉頡的 letvar 就是這思路,主打一個“默認不讓你亂改”,安全第一。

  • Go: Go 用 varconstvar count int = 0 這樣。Go 那個 := 寫法(比如 count := 0)就跟倉頡的類型推斷差不多。

  • Java: Java 里變量隨便改,比如 int count = 0;。想不讓改得加個 final

  • Node.js (JavaScript): JS 那就隨性了,動態類型。const 是常量,let 是變量,但類型是跑起來才知道。

幾個常用的數據類型:

倉頡類型

大白話

例子

int

就是整數

42

float64

帶小數點的數

3.14159

bool

就倆值,對或錯

true, false

string

一串字兒

"你好"

char

單個字或符號

'A'

2. 流程控制

這玩意兒就是指揮程序往哪兒走的。倉頡給的還是老三樣 if-else, for, while

If-Else 表達式:

在倉頡里,if-else 不光能判斷,還能直接“吐”個值出來。

let number: int = 10;
let description: string = if number % 2 == 0 {"偶數"
} else {"奇數"
};
// 這下 description 就是 "偶數" 了,賊方便

這點跟 Rust 學的,代碼寫起來特別爽。不像 Java 和 Go,if-else 干完活就走了,還得你自己再整個變量去接。

循環:

// For 循環 (專門用來過一遍列表啥的)
let numbers: Array<int> = [1, 2, 3, 4, 5];
for num in numbers {// 對每個 num 做點啥
}// While 循環
var i: int = 0;
while i < 5 {// ...i = i + 1;
}

倉頡的 for 循環就干一件事:遍歷。簡單直接。這跟 Go 的 for ... range 和 Rust 的 for ... in 是一伙的,目的就是讓你少寫錯代碼,不像 C/Java 那種老式 for 循環,一不小心就寫出界了。

三:秀操作 —— 函數、結構體和并發

行,熱身結束,咱來看看倉頡那些更騷的操作。

1. 函數

函數嘛,就是把一堆代碼打包成一個塊,方便重復使用。

// 收倆整數,還一個它倆的和
func add(a: int, b: int): int {return a + b;
}// 用一下
let sum: int = add(5, 3); // sum 現在就是 8

2. 結構體 (Struct) 和方法 (Method)

想自己定義數據類型?用 struct 就對了。跟 Go 和 Rust 的 struct 差不多。

// 定義一個“點”
struct Point {x: float64,y: float64,
}// 給這個“點”加點技能
impl Point {// 'self' 就代表這個“點”自己public func distance_from_origin(self): float64 {return (self.x.pow(2) + self.y.pow(2)).sqrt();}
}// 走一個
let p = Point{x: 3.0, y: 4.0};
let dist = p.distance_from_origin(); // dist 就是 5.0

圖解一下:

+--------------------------+
|  struct Point { x, y }   |  <-- 這是“長啥樣”(數據)
+--------------------------+|| 配套技能V
+--------------------------+
|  impl Point {            |
|    func ...()            |  <-- 這是“能干啥”(方法)
|  }                       |
+--------------------------+

這種把“數據”和“行為”分開定義但又綁定的玩法,是現在很流行的模式(比如 Rust)。比 Java 那種啥都塞一個 class 里的要靈活,比 Go 那種“非侵入式”的接口用起來更直接。

3. 并發:協程 (Coroutine)

并發,這可是倉頡的王牌!它用的協程模型,超級輕量,跟 Go 語言的 Goroutine 簡直是親兄弟。

asyncawait 關鍵字,寫異步代碼就跟寫普通代碼一樣順溜。

// 模擬一個花時間的活兒,比如上網扒數據
async func fetch_data(url: string): string {// ... 假裝在請求網絡std::time::sleep(1.second); // 睡一秒return "從 " + url + " 搞來的數據";
}public async func main() {// 同時安排兩個活兒let task1 = async fetch_data("url1");let task2 = async fetch_data("url2");// 等它倆干完let data1 = await task1;let data2 = await task2;io::println(data1);io::println(data2);
}

跟其他語言的并發比劃比劃:

  • Go: 倉頡的協程和 Go 的 Goroutine 理念上賊像。Go 用 go 關鍵字開個小差,用 channel 通信。倉頡的 async/await 寫起來更像普通代碼,對從 JS/Python/C# 轉過來的兄弟們更友好。

  • Node.js: Node.js 是單線程跑異步。倉頡的 async/await 跟 Node.js 的語法和感覺一模一樣。但!底層完全不同:倉頡是真的能把活兒分給不同 CPU 核心去干,而 Node.js 默認就在一個線程里倒騰。

  • Java: Java 以前搞并發都靠線程(Thread),那玩意兒太重了。雖然現在 Java 也有了“虛擬線程”這種輕量級的玩意兒,但倉頡和 Go 這種天生就支持協程的,設計上更純粹、更簡單。

  • Rust: Rust 的 async/await 跟倉頡也像,但 Rust 讓你自己選配一個“異步發動機”(比如 Tokio)。倉頡很可能給你內置了一個牛逼的,省得你操心了。

圖解:倉頡/Go vs Java/傳統線程

倉頡/Go 模型:
+----------------------------------------+
| 電腦的CPU核心 1 | 核心 2 | ... | 核心 N |
+----------------------------------------+|               |           |
+-----+         +-----+     +-----+
|小任務A|         |小任務D|     |小任務G|
+-----+         +-----+     +-----+
|小任務B|         |小任務E|
+-----+         +-----+
|小任務C|         |小任務F|
+-----+         +-----+
// 一大堆輕量級的小任務,在幾個CPU核心上靈活切換,成本賊低傳統 Java 線程模型:
+----------------------------------------+
| CPU核心 A (Java線程A) | CPU核心 B (Java線程B) |
+----------------------------------------+
// 一個Java線程就占一個CPU核心,創建和切換都費勁

四:高手進階 —— 高級特性和圈子

1. 錯誤處理

倉頡處理錯誤的方式很直接,跟 Go 和 Rust 想法一樣,就是把“錯誤”當成正經事兒來處理,不讓你稀里糊涂地就過去了。

// 這函數可能會失敗,它會返回一個 Result
func might_fail(should_fail: bool): Result<string, Error> {if should_fail {return Err(Error{"出錯了兄弟"});} else {return Ok("搞定!");}
}// 處理這個 Result
let result = might_fail(true);
match result {case Ok(data) => io::println("拿到數據: " + data),case Err(e) => io::println("壞了,出錯了: " + e.message),
}

```Result<T, E>` 這玩意兒清楚地告訴你:這函數要么成功,給你個 `T` (`Ok(T)`);要么失敗,給你個 `E` (`Err(E)`)。然后用 `match` 強制你把兩種情況都考慮到,再也不會有漏網之魚了。

?2. 內存管理

倉頡又想快又想安全,那內存管理肯定得下功夫。它很可能學了 Rust 那套“所有權”和“借用”的玩法,或者用了啥牛逼的自動內存管理技術。反正目標就是,既不像 C/C++ 那樣讓你手動管內存搞得心累,也別像傳統 GC 那樣時不時卡一下。

3. 圈子和未來

一門語言火不火,得看圈子大不大。倉頡現在還算是個小萌新,但后臺硬啊。可以期待一下:

  • 標準庫: 自帶一堆好用的工具。
  • 包管理器: 像 `cargo` 或 `go mod` 那樣,管理第三方庫。
  • 工具鏈: 好用的編譯器、代碼提示、調試器啥的。
  • 兼容容性: 能跟老大哥 C/C++ 一起玩。

總結:倉頡這小子,到底想干啥?

倉頡不是瞎抄,它是把各家之長都學過來,然后自己攢了個大招。

特性倉頡 (Cangjie)RustGoJavaNode.js(JS)
類型靜態, 編譯, 強類型靜態, 編譯, 強類型靜態, 編譯, 強類型靜態, 編譯, 強類型動態, 解釋/JIT?
新能起飛** (目標)起飛很快還行易班
安全拉滿(目標)拉滿 (所有權)高(GC)高(GC)高(GC)
并發協程 (async/await)協程 (async/await)Goroutine線程/虛擬線程

事件循環

風格潮,像Rust/SwiftC++和函數式的混血C語言風, 極簡C++風, 啰嗦C語言風, 靈活
錯誤處理ResultResult多返回值異常回調/Promise/async
主場系統, 云原生, 嵌入式系統, WebAssembly云原生, 后端企業應用, 安卓Web后端, 工具?

2、語言畫像?

如果你從 Rust 來: 你會愛上倉頡對安全和性能的追求,還有那些熟悉的語法。而且它可能比 Rust 更“傻瓜化”,不用你操心運行時的事。


Gopher?: 你會對它的并發和編譯速度感到很親切。但倉頡更嚴格的類型和錯誤處理,可能會讓你覺得代碼更穩了。

如果你從 Java 來: 倉頡會讓你知道啥叫輕量級并發,啥叫不寫廢話。從重重的“對象”到更靈活的“數據”,得換換腦子。


如果你從 Node.js 來: `async/await` 你肯定玩得賊溜。但倉頡的靜態類型能在編譯時就幫你把好多 bug 揪出來。而且,你能真正用上電腦的所有核心,火力全開!

總結

倉頡這門語言,野心不小。它想在性能、安全、開發爽度這三個點上,找到一個完美的平衡。它吸收了過去這些年編程語言發展的精華,就是為了給未來的軟件開發(特別是系統和云原生這塊)打個好底子。

學倉頡,不光是學個新語言,更是了解一下現在軟件開發都在愁啥、有啥新招。現在上車,絕對是早期股東,一起見證它牛逼就完事兒了!
?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88393.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88393.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88393.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

線性探針是什么:是一種用于探測神經網絡中特定特征的工具

線性探針是什么 線性探針是一種在機器學習和相關領域廣泛應用的技術,用于評估預訓練模型特征、檢測數據中的特定序列等。在不同的應用場景下,線性探針有著不同的實現方式和作用: 評估預訓練模型特征:在機器學習中,線性探針是一種評估預訓練模型“特征遷移能力”的標準化方…

【論文閱讀】Few-Shot PPG Signal Generation via Guided Diffusion Models

從少量樣本數據選擇到后處理的整體框架。首先,擴散模型在N樣本數據集和指導下的訓練。接著,模型生成一個增強的數據集,并進一步優化以提高保真度。最后,這些合成數據與少量樣本訓練數據集結合,用于基準模型的訓練和評估。數據分布從最初的紅色變為保真度增強的藍色,這表明…

CentOS-7的“ifupdown“與Debian的“ifupdown“對比 筆記250706

CentOS-7的"ifupdown"與Debian的"ifupdown"對比 筆記250706 CentOS 7 和 Debian 的 ifupdown 工具名稱相同&#xff0c;但在實現機制、配置文件語法和系統集成上存在顯著差異。以下是核心對比分析&#xff1a; ?? 一、核心差異概覽 對比維度CentOS 7De…

架構如傳承:技術長河中的可持續樂章

代碼結構&#xff1a;協作基石 在軟件開發的世界里&#xff0c;代碼結構就如同建筑的框架&#xff0c;支撐著整個項目的運行。想象一下&#xff0c;你加入了一個新的開發團隊&#xff0c;接手一個已經有一定規模的項目。當你打開代碼庫&#xff0c;看到的是一團亂麻般的代碼&a…

Ubuntu22.04更新Openssh至9.9p2無法正常連接,報錯解決

Ubuntu22.04更新Openssh至9.9p2無法正常連接&#xff0c;報錯解決 1.報錯信息如下所示ExecStart/usr/sbin/sshd -D $SSHD_OPTS (codeexited, status255/EXCEPTION)2.這通常說明 SSH 配置文件存在語法錯誤、缺失關鍵文件&#xff0c;或者端口被占用等問題。 3.檢查配置文件是否有…

基于小程序的智能停車管理系統設計與開發

項目介紹 本課程演示的是一款基于小程序的智能停車管理系統設計與開發&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Java 學習者。 1.包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 2.帶你從零開始部署運行本套系統 3…

多模態大語言模型arxiv論文略讀(155)

Panther: Illuminate the Sight of Multimodal LLMs with Instruction-Guided Visual Prompts ?? 論文標題&#xff1a;Panther: Illuminate the Sight of Multimodal LLMs with Instruction-Guided Visual Prompts ?? 論文作者&#xff1a;Honglin Li, Yuting Gao, Chengl…

SAP ERP與Oracle EBS對比,兩個ERP系統有什么區別?

據統計&#xff0c;2024年中國ERP軟件市場規模預計突破210億元&#xff0c;其中SAP和Oracle占據第一梯隊&#xff0c;共占國內ERP市場45%以上的份額&#xff0c;在高端市場尤其顯著。SAP和Oracle作為ERP行業的兩大巨頭&#xff0c;具體有什么區別呢&#xff1f;SAP是什么&#…

網絡安全之RCE分析與利用詳情

Gogs背景介紹Gogs&#xff08;Go Git Service&#xff09;是一款用Go語言編寫的輕量級、開源的Git倉庫托管系統。它的設計目標是讓搭建和維護Git服務變得簡單、快速&#xff0c;同時提供類似GitHub的功能&#xff0c;但對資源消耗更少&#xff0c;適合個人或者小型團隊使用&…

OpenCV圖片操作100例:從入門到精通指南(2)

接上篇&#xff0c;本文將繼續分享OpenCV實用技巧&#xff0c;涵蓋圖像處理、目標檢測、3D視覺等進階領域&#xff01;六、圖像變換進階17. 圖像金字塔# 高斯金字塔下采樣 smaller cv2.pyrDown(img)# 高斯金字塔上采樣 larger cv2.pyrUp(img)用于多尺度圖像處理&#xff0c;構…

2、Connecting to Kafka

KafkaAdmin-請參閱配置主題ProducerFactory-請參閱發送消息ConsumerFactory-請參閱接收消息從2.5版本開始&#xff0c;每個版本都擴展了KafkaResourceFactory。這允許在運行時通過向引導服務器的配置中添加Supplier<String>來更改引導服務器&#xff1a;setBootstrapServ…

二進制部署CentOS8.5+Kubernetes1.33.2+Docker28.3.1高可用集群

Kubernetes 集群部署202507 本實驗主要軟件環境及資源如下&#xff1a; 二進制部署CentOS8.5Kubernetes1.33.2Docker28.3.1高可用集群 一、系統要求 ?Kubermetes 系統由一組可執行程序組成&#xff0c;用戶可以通過Kubernetes在GitHub 的項目網站下載編譯好的二進制文件或…

127. Java 泛型 - 泛型類與子類型

文章目錄127. Java 泛型 - 泛型類與子類型1. 泛型類和接口的子類型化示例&#xff1a;ArrayList 和 List2. 自定義泛型接口的子類型化示例&#xff1a;泛型接口的子類型解釋3. 泛型類和接口的類型參數4. 總結127. Java 泛型 - 泛型類與子類型 1. 泛型類和接口的子類型化 在 J…

內網服務器怎么設置公網遠程訪問? windows桌面連接和Linux自帶SSH外網異地跨網用完整步驟教程

沒有公網IP的本地主機跨網訪問是經常需要用到的網絡場景。要設置內網服務器在公網進行異地遠程訪問&#xff0c;需依次完成確保網絡連接正常、配置防火墻、啟用遠程訪問服務、和利用類似nat123內網映射外網打通等一系列步驟&#xff0c;以保障不同內網的遠程訪問的順利進行。一…

數據提取之bs4(BeautifuSoup4)模塊與Css選擇器

BeautifuSoup4from bs4 import BeautifulSoup創建對象 <class bs4.BeautifulSoup>soup BeautifulSoup(源碼, 解析器)bs4標簽種類&#xff08;1&#xff09;tag: 標簽print(soup.title, type(soup.title))&#xff08;2&#xff09;獲取標簽里面的文本內容, 可導航的字符…

CPP中的List

一.list的介紹&#xff1a;1.list是可以在常數范圍內在任意位置進行插入和刪除的序列式容器&#xff0c;并且該容器可以前后雙向迭代。2.list的底層是雙向鏈表結構&#xff0c;帶有哨兵位的頭結點 。3. list與forward_list非常相似&#xff1a;最主要的不同在于forward_list是單…

Ntfs!LfsUpdateLfcbFromRestart函數分析之Ntfs!LfsFindOldestClientLsn

第0部分&#xff1a;//// Find the oldest client Lsn. Use the last flushed Lsn as a starting point.//Lfcb->OldestLsn Lfcb->LastFlushedLsn;LfsFindOldestClientLsn( RestartArea,Add2Ptr( RestartArea, Lfcb->ClientArrayOffset, PLFS_CLIENT_RECORD ),&…

「日拱一碼」021 機器學習——特征工程

目錄 特征選擇 過濾法&#xff08;Filter Methods&#xff09; 方差選擇法 相關系數法 卡方檢驗 包裹法&#xff08;Wrapper Methods&#xff09; 遞歸特征消除&#xff08;RFE&#xff09; 嵌入法&#xff08;Embedded Methods&#xff09; L1正則化&#xff08;Lasso…

k8s:安裝 Helm 私有倉庫ChartMuseum、helm-push插件并上傳、安裝Zookeeper

ChartMuseum 是 Kubernetes 生態中用于存儲、管理和發布 Helm Charts 的開源系統&#xff0c;主要用于擴展 Helm 包管理器的功能 核心功能 ?集中存儲?&#xff1a;提供中央化倉庫存儲Charts&#xff0c;支持版本管理和權限控制。 ? ?跨集群部署?&#xff1a;支持多集群環境…

C++編程學習(第二天)

1、求a和b兩個數之和。#include <iostream> using namespace std;int main() {int a, b, sum; //定義變量a、b、sumcout << "請輸入第一個數字a: "; //打印需要顯示的字符串cin >> a; // >&…