華為倉頡編程語言的表達式及其特點

華為倉頡編程語言的表達式及其特點

倉頡(Cangjie)語言的表達式有一個明顯的特點,范圍不再局限于傳統算術運算,而是擴展到條件表達式、循環表達式等多種類型,每種表達式均有確定的類型和值。

傳統基本表達式,由一個或多個操作數(operand)通過零個或多個操作符(operator)組合而成如 a + 10(假設a和b為已定義的數值變量)。字面量是直接表示值的表達式如?42、"Hello"。

表達式總是隱含著一個計算過程,因此每個表達式都會有一個計算結果。對于只有操作數而沒有操作符的表達式,其計算結果就是操作數自身。

本文不多介紹傳統基本表達式,下面重點介紹控制流表達式。

倉頡(Cangjie)作為一門融合了現代編程語言設計理念的語言,弱化了傳統 “語句” 與 “表達式” 的界限:

? 條件分支 → if-else 表達式

? 循環 → while、for 表達式

? 異常處理 → try 表達式

? 控制轉移 → break、continue 也是表達式,類型為 Nothing

這體現了該語言將傳統控制結構表達式化的設計理念。但需要特別注意在這方面的差異化處置:

【僅就目前( 2025 年 7 月推出首個長期支持版本(LTS 1.0.0)),華為倉頡編程語言,在傳統控制結構表達式化這方面的差異化處置的總結】

if-else 表達式的類型(返回值類型)由分支類型推斷(可能是任意類型,包括 Unit 或非 Unit——指的是它們通常用于返回一個有意義的值(如?StringInt?等)

while、do-while、for 表達式類型(返回值類型)都是 Unit,強調副作用而非返回值。和if-else 表達式不同,倉頡編程語言的while、do-while、for 表達式類型都是 Unit(表示 “無實際值” 的空類型),強調副作用而非返回值。

Unit:表示“有操作但無值”,類型安全且可顯式使用。

【唯一值:Unit 類型只有一個實例,即 ()(空元組)。它不攜帶任何數據,僅表示“操作已完成,但無有意義的結果”。

類型安全:與直接忽略返回值不同,倉頡強制要求顯式處理 Unit 類型,避免隱式丟棄值導致的潛在錯誤。】

異常處理 try 表達式?返回值可能為非 Unit 類型。

break 和 continue 表達式的類型(返回值類型)為 Nothing,表示它們不返回任何值且不會改變程序的控制流之外的狀態。

Nothing:表示“無可能返回”(如 break/continue/拋出異常),是所有類型的子類型,用于控制流轉移。

剛開始不太好懂,先總體了解之,看完下面展開介紹及例子,就會逐漸明了。

如何運行下面代碼,可參見

華為倉頡編程語言簡介與快速實驗上手圖解_倉頡1.0.0示例-CSDN博客

華為倉頡編程語言實踐體驗-CSDN博客

if-else 表達式

基本形式:

if (條件) {

? 分支 1

} else {

? 分支 2

}

也可寫為:

if (條件) { 分支1 } else { 分支2 }。

例如:

import std.convert.*main() {print("請輸入score的值: ")var str: String = readln()var score =  Int8.parse(str)// if-else 示例if (score >= 60) {println("及格")} else {println("不及格")}}

測試運行:

特別說明

if-else 表達式的類型由分支類型推斷(可能是任意類型,包括 Unit 或非 Unit)。求值規則:

計算“條件”表達式的值,若為 true,則執行“分支1”;若為 false 且存在 else 分支,則執行“分支2”。例如:

import std.convert.*main() {print("請輸入a的值: ")var str: String = readln()var a =  Int64.parse(str)print("請輸入b的值: ")var str2: String = readln()var b =  Int64.parse(str2)println("max = ${if (a >= b) { a } else { b }}")  //注意這一句,相當于下面兩句let max = if (a >= b) { a } else { b }  //注意這一句println("max = ${max}")}

測試運行

循環:while、do-while、for 表達式

while、do-while、for 表達式的類型都是 Unit,強調副作用而非返回值。后面以for 表達式為例特別說明。

while 表達式

基本形式

while (條件) {

? 循環體

}

例如:

main() {var i = 0  var sum = 0  while (i < 10) {  // 調整條件,確保累加1~10i += 1sum += i       }println("輸出: sum = ${sum}") //輸出: sum = 55return 0
}

do-while 表達式

基本形式:

do {

? 循環體

} while (條件)

例如:

main() {var i = 1do {println("Current value: ${i}") i += 1                     } while (i <= 3)               
}

輸出:

Current value: 1
Current value: 2
Current value: 3

for-in 表達式

基本形式:

for (迭代變量 in 序列) {

? 循環體

}

例如

main() {var sum = 0for (i in 1..=100) {sum += i}println("sum = ${sum}")  //sum = 5050
}

前面提到while、do-while、for 表達式類型都是 Unit,強調副作用而非返回值。什么意思?for 循環表達式為例說明,請看下面例子:

main() {var sum = 0println("sum = ${for (i in 1..=100) { sum += i }}")
}

你可能想,預期通過 for 循環表達式計算 1 + 2 + ... + 100 的和(5050),然后通過字符串模板 ${...} 輸出 sum = 5050。

但是實際輸出sum = (),而不是sum = 5050 ,問什么?

解釋

for循環作為表達式,其默認返回值類型是Unit(表示 “無實際值” 的空類型),無論循環體內做了什么操作。

代碼中for (i in 1..=100) { sum += i }的作用是修改外部變量sum(這是一種 “副作用”),但循環本身的返回值始終是Unit。

當你在字符串模板中使用${for (...) {}}時,實際插入的是Unit類型的默認表示形式(),因此輸出sum = ()。

你打印的是循環表達式的返回值(Unit),而不是sum變量的值。要打印sum變量的值,可參見前面的示例。

異常處理:try 表達式

基本形式:

try {

??? // 可能出現異常的代碼

} catch (e: ExceptionType) {

??? // 處理異常的代碼

} finally {

??? // 資源釋放的代碼(可選)

}

try 塊:執行可能拋出異常的代碼。

catch 塊:捕獲異常并返回一個備用值(確保表達式始終有返回值)。

finally 塊(可選):執行清理操作,但不影響 try 表達式的返回值。

、判斷用戶給出的整數的奇偶性,用try異常處理,防止用戶輸入非數字將出錯中斷運行,源碼如下:

import std.convert.*
import std.io.*main(){print("請輸入一個整數:")while (true) {var str: String = readln()if (str.isEmpty()) {print("輸入為空,請重新輸入一個整數:")continue}// 使用 try-catch 捕獲 parse 可能拋出的異常try {var n =  Int64.parse(str)if( n % 2 == 0) {println("${n} 是偶數")} else {println("${n} 是奇數")}break} catch(e:IllegalArgumentException){print("輸入非法,請輸入一個有效的整數:")}}}

特別提示

異常處理 try 表達式?返回值可能為非 Unit 類型

在華為倉頡編程語言中,try 表達式的返回值類型由 try 塊或 catch 塊中的最后一行表達式決定。若這些分支返回非 Unit 類型的值,則整個 try 表達式的類型會推斷為該具體類型。

例如:

main() {// 示例1:try和catch都返回Int類型let result1 = try {let x = 10let y = 2x / y  // 返回Int} catch (e: Exception) {println("發生錯誤: ${e.message}")0  // 返回Int}println("結果1: ${result1}")  // 輸出: 結果1: 5// 示例2:try返回String,catch返回Stringlet result2 = try {"成功執行"  // 返回String} catch (e: Exception) {"執行失敗"  // 返回String}println("結果2: ${result2}")  // 輸出: 結果2: 成功執行// 示例3:try拋出異常,catch返回非Unit類型let result3 = try {throw Exception("故意拋出異常")//println("不會執行到這里")} catch (e: Exception) {"捕獲到故意拋出異常"  // 返回String}println("結果3: ${result3}")  // 輸出: 結果3: 捕獲到異常
}

測試運行:

這個示例展示了try表達式在不同情況下的返回值類型推斷。當try或catch塊最后一行是非Unit類型表達式時,整個try表達式就會采用該類型。

控制轉移:break、continue 表達式

break 和 continue 表達式的類型為 Nothing,表示它們不返回任何值且不會改變程序的控制流之外的狀態。

【Nothing 是一種特殊的類型,它不包含任何值,并且 Nothing 類型是所有類型的子類型(這當中也包括 Unit 類型)

break、continue、return 和 throw 表達式的類型是 Nothing,程序執行到這些表達式時,它們之后的代碼將不會被執行。return 只能在函數體中使用,break、continue 只能在循環體中使用。】

例、以下程序使用 for-in 表達式和 break 表達式,在給定的整數數組中,找到第一個能被 5 整除的數字,源碼如下:

main() {let numbers = [12, 18, 25, 36, 49, 55]for (number in numbers) {if (number % 5 == 0) {println(number)break}}
}

、以下程序使用 for-in 表達式和 continue 表達式,將給定整數數組中的奇數打印出來,源碼如下:

main() {let numbers = [12, 18, 25, 36, 49, 55]for (number in numbers) {if (number % 2 == 0) {continue}println(number)}
}
輸出:

輸出:

25
49
55

賦值表達式

a= 2

b = a + 3

這些是是賦值表達式(包含賦值操作符的表達式),賦值表達式的類型是 Unit,值是 ()即空元組。例如:

main(){var a = 1var b = 2println("${a}, ${b}")/*a = (b = 0) // 編譯錯誤,賦值表達式的類型是 Unit,值是 ()if (a = 5) { // 編譯錯誤,賦值表達式的類型是 Unit,值是 ()}a = b = 0 // 語法錯誤,不支持鏈式使用賦值*/
}

其中,// 符號之后寫單行注釋;一對 /* 和 */ 符號之間寫多行注釋。注釋內容不影響程序的編譯和運行。

、官網介紹

https://cangjie-lang.cn/docs?url=%2F1.0.0%2Fuser_manual%2Fsource_zh_cn%2Fbasic_programming_concepts%2Fexpression.html

https://cangjie-lang.cn/docs?url=%2F0.53.18%2FSpec%2Fsource_zh_cn%2FChapter_12_Exceptions%28zh%29.html 中的“Try 表達式的類型”部分

https://cangjie-lang.cn/docs?url=%2F1.0.0%2Fuser_manual%2Fsource_zh_cn%2Fbasic_data_type%2Fbasic_operators.html 見開頭幾段有相關賦值表達式的介紹

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

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

相關文章

【linux】keepalived

一.高可用集群1.1 集群類型LB&#xff1a;Load Balance 負載均衡 LVS/HAProxy/nginx&#xff08;http/upstream, stream/upstream&#xff09; HA&#xff1a;High Availability 高可用集群 數據庫、Redis SPoF: Single Point of Failure&#xff0c;解決單點故障 HPC&#xff…

Webpack配置原理

一、Loader&#xff1a; 1、定義&#xff1a;將不同類型的文件轉換為 webpack 可識別的模塊2、分類&#xff1a; ① pre&#xff1a; 前置 loader &#xff08;1&#xff09;配置&#xff1a;在 webpack 配置文件中通過enforce進行指定 loader的優先級配置&#xff08;2&#x…

對比JS“上下文”與“作用域”

下面從定義、特性、示例&#xff0c;以及在代碼分析中何時側重“上下文”&#xff08;Execution Context/this&#xff09;和何時側重“作用域”&#xff08;Scope/變量查找&#xff09;&#xff0c;以及二者結合的場景來做對比和指導。一、概念對比 | 維度 | 上下文&#xff0…

如何做數據增強?

目錄 1、為什么要做數據增強&#xff1f; 2、圖像數據增強&#xff1f; 3、文本與音頻數據增強&#xff1f; 4、高級數據增強&#xff1f; 數據增強技術就像是一種“造數據”的魔法&#xff0c;通過對原始數據進行各種變換&#xff0c;生成新的樣本&#xff0c;從而提高模型…

Go by Example

網頁地址Go by Example 中文版 Github倉庫地址mmcgrana/gobyexample&#xff1a;按示例進行 HelloWorld package mainimport ("fmt" )func main() {fmt.Println("Hello World") } Hello World 值 package mainimport ("fmt" )func main() {…

ClickHouse高性能實時分析數據庫-消費實時數據流(消費kafka)

告別等待&#xff0c;秒級響應&#xff01;這不只是教程&#xff0c;這是你駕馭PB級數據的超能力&#xff01;我的ClickHouse視頻課&#xff0c;凝練十年實戰精華&#xff0c;從入門到精通&#xff0c;從單機到集群。點開它&#xff0c;讓數據處理速度快到飛起&#xff0c;讓你…

電子電氣架構 --- 車載軟件與樣件產品交付的方法

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

C++:STL中vector的使用和模擬實現

在上一篇中講到了string類&#xff0c;string并不屬于STL中因為string出現的比STL早&#xff0c;但是在使用方法上兩者有相似之處&#xff0c;學習完string后再來看vector會容易的多&#xff0c;接著往下閱讀&#xff0c;一定會有收獲滴&#xff01; 目錄 vector的介紹 vect…

倉庫管理的流程、績效和解決方案?

什么是倉庫管理&#xff1f; 倉庫管理涉及對所有倉庫運營的日常監督。一個全面、集成的倉庫管理解決方案采用行業最佳實踐&#xff0c;并涵蓋使高效運營得以實現的所有基本要素。這些要素包括分銷和庫存管理、倉庫勞動力管理以及業務支持服務。此外&#xff0c;由內部提供或與服…

TIM 實現定時中斷【STM32L4】【實操】

使用定時器實現定時中斷的功能&#xff1a;比如每1ms進入中斷處理函數使用STM32CubeMX配置TIM初始化先了解每個參數的含義&#xff0c;在進行配置Counter Settings: 計數器基本設置Prescaler(PSC): 預分頻器&#xff0c;設置預分頻器系數Counter Mode: 技術模式&#xff0c;…

Elasticsearch 的聚合(Aggregations)操作詳解

目錄 1. 概述 2. 聚合類型分類詳解 2.1 桶聚合&#xff08;Bucket Aggregations&#xff09; 2.1.1 基礎桶聚合 2.1.2 特殊桶聚合 2.1.3 高級桶聚合 2.2 指標聚合&#xff08;Metric Aggregations&#xff09; 2.2.1 單值指標聚合&#xff08;Single-value Metrics&am…

電子電氣架構 --- 高階智能駕駛對E/E架構的新要求

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

0.深度學習環境配置步驟

0.深度學習環境配置步驟 這里介紹深度學習環境配置詳細步驟&#xff0c;包括安裝軟件&#xff0c;每一步都有安裝時的截圖&#xff08;后續持續更新&#xff0c;敬請關注&#xff09; 目錄如下&#xff1a; 1.安裝anaconda 2.安裝CUDA 3.安裝CU_DNN 4.安裝pytorch

在 Azure 中配置 SMS 與 OTP

1. Azure Active Directory B2C (AAD B2C) 中的 SMS/OTP 身份驗證 1.1. 現狀與原理&#xff1a;電話注冊與登錄 Azure Active Directory B2C (AAD B2C) 提供了將電話號碼作為用戶身份標識進行注冊和登錄的功能&#xff0c;旨在為用戶提供一種便捷的替代傳統電子郵件或用戶名登錄…

簡單實現支付密碼的頁面及輸入效果

干我們這行&#xff0c;風吹日曬不到&#xff0c;就怕甲方突發奇想。 今天客戶要做一個安全密碼前置校驗&#xff0c;還要做成支付寶那種效果。ps:android端 心理吐槽了一萬遍以后&#xff0c;還是得面對現實。 先用通義問一遍&#xff0c;給了兩個方案&#xff0c;要么自己寫&…

proxmox 解決docker容器MongoDB創建報錯MongoDB 5.0+ requires a CPU with AVX support

目錄 最簡單直接的方式 測試MongoDB docker compose的安裝shell腳本 驗證訪問 最簡單直接的方式 讓虛擬機直接使用宿主機的物理 CPU 功能標志。 打開 Proxmox Web UI。 選擇你的 VM → 硬件 (Hardware) → CPU → 點擊 編輯 (Edit)。 將 CPU 類型改為 host。 確認并重啟…

向前滾動累加SQL 實現思路

一、業務背景在經營分析場景里&#xff0c;我們經常需要回答&#xff1a;“截至今天&#xff0c;過去 N 天/月/周累計發生了多少&#xff1f;”“把維度切到省、市、房型、項目經理、代理商等&#xff0c;結果又是什么&#xff1f;”本文用兩個真實需求做演示&#xff1a;以天為…

Spring AI(14)——文本分塊優化

RAG時&#xff0c;檢索效果的優劣&#xff0c;和文本的分塊的情況有很大關系。SpringAI中通過TokenTextSplitter對文本分塊。本文對SpringAI提供的TokenTextSplitter源碼進行了分析&#xff0c;并給出一些自己的想法&#xff0c;歡迎大家互相探討。查看了TokenTextSplitter的源…

Python----大模型(RAG 的智能評估-LangSmith)

一、LangSmith LangSmith是LangChain的一個子產品&#xff0c;是一個大模型應用開發平臺。它提供了從原 型到生產的全流程工具和服務&#xff0c;幫助開發者構建、測試、評估和監控基于LangChain 或其他 LLM 框架的應用程序。 安裝 LangSmith pip install langsmith0.1.137 官網…

磁懸浮軸承轉子不平衡質量控制策略設計:原理、分析與智能實現

磁懸浮軸承(Active Magnetic Bearing, AMB)以其無接觸、無摩擦、高轉速、無需潤滑等革命性優勢,在高端旋轉機械領域(如高速電機、離心壓縮機、飛輪儲能、航空航天動力系統)展現出巨大潛力。然而,轉子固有的質量不平衡是AMB系統面臨的核心挑戰之一,它誘發強同步振動,威脅…