华为仓颉编程语言观感
这里写自定义目录标题
- 相似点(主要与Swift进行对比)
- 不同点
- 亮点
花了半天时间,对华为新出的仓颉编程语言做了简单的了解,整体观感如下:
- 仓颉语言看起来是一门大而全的语言,吸纳了现存的很多中编程语言的范式和语法。
- 语法非常像Swift,有些语法又有rust的影子;
- 静态类型语言,但编译为二进制可执行文件,无虚拟机。并发、垃圾回收与内存管理模块与java类似;
- 支持声明式UI语法,类似于现在ArkUI使用的ArkTS语法,估计以后HarmonyOS的开发语言会从ArkTS转化为仓颉。
相似点(主要与Swift进行对比)
-
类型扩展
-
添加函数 (swift包含)
仓颉: extend String { func printSize() {print(this.size)} }"123".printSize() // 3Swift: extension String {func printSize() {print(self.size)} }"123".printSize() // 3 -
添加属性 (swift不包含)
-
添加操作符重载 (swift包含)
仓颉: struct Point {let x: Intlet y: Intinit(x: Int, y: Int) {...}operator func +(rhs: Point): Point {return Point(this.x + rhs.x,this.y + rhs.y)} }let a: Point = ... let b: Point = ... let c = a + bSwift: struct Point {let x: Intlet y: Intinit(x: Int, y: Int) {self.x = xself.y = y}static func +(lhs:Point, rhs: Point) -> Point {return Point(x:lhs.x + rhs.x,y: lhs.y + rhs.y)} }let c: Point = Point(x: 1, y: 1) let d: Point = Point(x: 2, y: 2) let e = c + d -
实现接口 (swift包含)
仓颉: sealed interface Integer {}extend Int8 <: Integer {} extend Int16 <: Integer {} extend Int32 <: Integer {} extend Int64 <: Integer {}let a: Integer = 123 // okSwift: protocol Integer {}extension Int8 : Integer {}let a :Integer = Int8(123)
-
-
代数数据类型和模式匹配
仓颉中的枚举定义与使用:enum BinaryTree {| Node(value: Int, left: BinaryTree, right: BinaryTree)| Empty }func sumBinaryTree(bt: BinaryTree) {match (bt) { //match关键字实际是rust语言中的模式匹配关键字。case Node(v, l, r) => v + sumBinaryTree(l) + sumBinaryTree(r)case Empty => 0} }Swift中的枚举定义与使用:indirect enum BinaryTree {case Node(value: Int, left: BinaryTree, right: BinaryTree)case Empty }func sumBinaryTree(bt: BinaryTree) -> Int {switch bt {case .Node(let value, let left, let right):return value + sumBinaryTree(bt: left) + sumBinaryTree(bt: right)case .Empty:return 0} } -
泛型
泛型函数的声明方式几乎一样,尤其是针对泛型类型T的限制,两者都使用where关键字。仓颉: func lookup<T>(element: T, arr: Array<T>): Bool where T <: Equatable<T> {for (e in arr){if (element == e){return true}}return false }Swift: func lookup<T>(element: T, arr: Array<T>) -> Bool where T : Equatable {for e in arr {if (element == e){return true}}return false } -
命名参数&参数默认值
仓颉: func dateOf(year!: Int64, month!: Int64, dayOfMonth!: Int64, timeZone!: TimeZone = TimeZone.Local) {}dateOf(year: 2024, month: 6, dayOfMonth: 21) // ok dateOf(year: 2024, month: 6, dayOfMonth: 21, timeZone: TimeZone.UTC) // okSwift: func dateOf(year: Int64, month: Int64, dayOfMonth: Int64, timeZone: TimeZone = TimeZone.current) {}dateOf(year: 2024, month: 6, dayOfMonth: 21) // ok dateOf(year: 2024, month: 6, dayOfMonth: 21, timeZone: TimeZone.gmt) // ok -
尾随lambda(trailing lambda)
仓颉: func unless(condition: Bool, f: ()->Unit) {if(!condition) {f()} }int a = f(...) unless(a > 0) {print("no greater than 0") }Swift: func unless(condition: Bool, f: () -> Void) {if !condition {f()} }unless(condition: true) {print("no greater than 0") } -
属性
属性的get/set配置。仓颉: x和y是只读的,只有get实现,而color则是可变的,用mut prop修饰,同时具有get和set实现。 class Point {private let _x: Intprivate let _y: Intprivate var _color: Stringinit(x: Int, y: Int, color: String) {...}prop x: Int {get() {Logger.log(level: Debug, "access x")return _x}}prop y: Int {get() {Logger.log(level: Debug, "access y")return _y}}mut prop color: String {get() {Logger.log(level: Debug, "access color")return _color}set(c) {Logger.log(level: Debug, "reset color to ${c}")color = c}} }main() {let p = Point(0, 0, "red")let x = p.x // "access x"let y = p.y // "access y"p.color = "green" // "reset color to green" }Swift: x和y是只读的,只有get实现,而color则是可变的,同时具有get和set实现。 class Point2 {private let _x: Intprivate let _y: Intprivate var _color: Stringinit(_ x: Int, _ y: Int,_ color: String) {self._x = xself._y = yself._color = color}var x: Int {get {return _x}}var y: Int {get {return _y}}var color: String {get {return _color}set(c) {_color = c}} }let p = Point2(0, 0, "red")p.x = 100 //errorlet x = p.x // "access x"let y = p.y // "access y"p.color = "green" // "reset color to green" -
空引用安全
在仓颉中,对于任意类型T,都可以有对应的可选类型Option。具有Option类型的变量要么对应一个实际的具有T类型的值v,因此取值为Some(v),要么具有空值,取值为None。
可选类型(Option)是一种 enum 类型,是一个经典的代数数据类型,表示有值或空值两种状态。
在Swift,用来表示变量可空的关键字为Optional.仓颉: var a: ?Int = None a?.toString() // None a ?? 123 // 123 a = Some(321) a?.toString() // Some("321") a ?? 123 // 321Swift: var f: Int? = nil print(f) //nil print(f ?? 123) // 123 var g = Optional(321) print(g) //Optional(321) print(g ?? 123) // 321 -
值类型
仓颉和Swift都使用struct来实现用户自定义的值类型。仓颉: struct Point {var x: Intvar y: Intinit(x: Int, y: Int) { ... }... }var a = Point(0, 0) var b = a a.x = 1 print(b.x) // 0Swift: struct Point {var x: Intvar y: Intinit(x: Int, y: Int) { self.x = xself.y = y}}var a1 = Point3(x:0,y: 0) var b1 = a1 a1.x = 1 print(b1.x) // 0 -
宏
仓颉: 定义一个名为 DebugLog 的宏: public macro DebugLog(input: Tokens) {if (globalConfig.mode == Mode.development) {return quote( println( ${input} ) )}else {return quote()} } 使用 DebugLog 宏: @DebugLog( expensiveComputation() )Rust: use proc_macro;#[some_attribute] pub fn some_name(input: TokenStream) -> TokenStream { } -
Actor
使用更简洁的语法来实现异步编程、并发编程中的数据竞争问题。
仓颉: actor Account {instance var balance: Int64init (x: Int64) { this.balance = f1() }instance func performWithdraw(amount: Int64): Unit {balance -= amount}receiver func withdraw(amount: Int64): Bool {if (this.balance < amount) {return false} else {this.performWithdraw(amount);return true}} }Swift: 注意:这段代码是来自于Swift的官方文档。仓颉的文档示例与swift的文档示例代码基本是一致的,看来仓颉语言应该是参考了Swift语言不少的东西。 actor Account {var balance: Int = 20// current user balance is 20// ...func withdraw(amount: Int) {guard balance >= amount else {return}self.balance = balance - amount} } -
可变性修饰符
可变性修饰符:let 与 var,分别对应不可变和可变属性,
不同点
-
垃圾收集方案
仓颉使用追踪式垃圾回收,类似于java中的基于可达性分析的垃圾回收算法;Swift使用引用计数法。(Swift有weak关键字)
亮点
-
管道(Pipeline)操作符
func double(a: Int) {a * 2 }func increment(a: Int) {a + 1 }double(increment(double(double(5)))) // 425 |> double |> double |> increment |> double // 42 -
类型扩展可添加属性
-
try-with-resources
该特性应该借鉴自java.try (input = MyResource(),output = MyResource()) {while (input.hasNextLine()) {let lineString = input.readLine()output.writeLine(lineString)} } -
溢出检查
这个机制使得大多数时候,整数溢出都会及时被感知,避免造成业务隐患。@OverflowWrapping func test(x: Int8, y: Int8) { // if x equals to 127 and y equals to 3let z = x + y // z equals to -126 } -
并发编程
-
线程创建简单且占用内存量小。使用Spawn关键字来创建新线程。
func fetch_data(url: String) {let response = http_get(url)process(response) }main() {let urls = ["https://example.com/data1", "https://example.com/data2", ...]let futures = ArrayList<Future<Unit>>()for (url in urls) {let fut = spawn { fetch_data(url) } // 创建仓颉线程进行网络请求futures.append(fut)}for (fut in futures) { // 等待所有仓颉线程完成fut.get()} } -
无锁并发对象。
运行时库提供了一系列的原子操作对象,尽量让开发者少使用互斥量或者锁来实现线程安全。同时提供的这些原子操作对象,针对多线程操作做了优化,其效率比单纯使用互斥量要高得多。
-
相关文章:
华为仓颉编程语言观感
这里写自定义目录标题 相似点(主要与Swift进行对比)不同点亮点 花了半天时间,对华为新出的仓颉编程语言做了简单的了解,整体观感如下: 仓颉语言看起来是一门大而全的语言,吸纳了现存的很多中编程语言的范式…...
Elasticsearch:倒数排序融合 - Reciprocal rank fusion - 8.14
警告:此功能处于技术预览阶段,可能会在未来版本中更改或删除。语法可能会在正式发布之前发生变化。Elastic 将努力修复任何问题,但技术预览中的功能不受官方正式发布功能的支持 SLA 约束。 倒数排序融合 (reciprocal rank fusion - RRF) 是一…...
Day13—大语言模型
定义 大语言模型(Large Language Models)是一种基于深度学习的自然语言处理(NLP)模型,用于处理和生成人类语言文本。 一、认识NLP 什么是NLP NLP(Natural Language Processing)࿰…...
php基础语法_面向对象
PHP php代码标记 多种标记来区分php脚本 ASP标记:<% php代码 %> 短标记: 脚本标记: 标准标记(常用): 简写风格: ASP风格:<% php代码 %> 注意:简写风格和ASP风格…...
开源模型应用落地-LangChain高阶-LCEL-表达式语言(八)
一、前言 尽管现在的大语言模型已经非常强大,可以解决许多问题,但在处理复杂情况时,仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而,现在可以利用langchain来使得模型的应用变得更加直接和简单。 LCEL是什么? LCEL是一种非常灵活和强大的语言,可以帮助您更…...
c# 协议数据计算陀螺仪的角度,带符号
subStrL str.Substring((76 - 8), 2); subStrH str.Substring((78 - 8), 2); Data[7] (short)(Convert.ToInt16(subStrH, 16) * 256 Convert.ToInt16(subStrL, 16));//角度X subStrL str.Substring((80 - 8), 2); subStrH str.Subst…...
ArcGIS arcpy代码工具——批量要素裁剪栅格影像
系列文章目录 ArcGIS arcpy代码工具——批量对MXD文件的页面布局设置修改 ArcGIS arcpy代码工具——数据驱动工具批量导出MXD文档并同步导出图片 ArcGIS arcpy代码工具——将要素属性表字段及要素截图插入word模板 ArcGIS arcpy代码工具——定制属性表字段输出表格 ArcGIS arc…...
discuz插件之优雅草超级列表互动增强v1.2版本更新
https://doc.youyacao.com/9/2142 v1.2更新 discuz插件之优雅草超级列表互动增强v1.2版本更新 [title]20220617 v1.2发布[/title] 增加了对php8的支持 增加了 对discuz3.5的支持...
三、用户中心项目笔记----后端多环境实战+原始部署
后端多环境主要是修改: 依赖的环境地址 数据库地址 缓存地址 消息队列地址 项目端口号 服务器配置 后端怎么去区分不同的环境? 我们后端的SpringBoot项目,通过application.yml添加不同后缀来区分配置文件 application.yml就是公共的配置&a…...
SpringMVC的使用
SpringMVC详情 RequestMapping("/hello") 负责用户的请求路径与后台服务器之间的映射关系 如果请求路径不匹配,则用户报错404 ResponseBody 作用: 将服务器的返回值转化为JSON. 如果服务器返回的是String类型,则按照自身返回. 新增: post请求类型 PostMapping("…...
Vue73-命名路由
一、路由的name属性 二、小结...
TrustOne发布一周年成绩单,15000家数智化转型客户的选择!
新一代终端安全TrustOne 发布一周年 交出亮眼成绩单 目前已经为 15000家数智化转型客户 带来高效、全方位的解决方案 TrustOne 新一代终端安全 2023年6月 新一代终端安全TrustOne正式发布,极简新主义的创新理念为数字变革而来; 2023年12月 IDC&…...
Nginx实战:故障处理_后端服务正常,nginx偶发502(Bad Gateway)
一、故障场景 用户访问服务偶发报错【502 Bad Gateway】,但是服务后端正常运行。架构如下: #mermaid-svg-4dDszusKEuPgIPlt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4dDszusKEuPgIPlt .error-icon{fill:#5…...
mac系统清理软件哪个好用?CleanMyMac X清理工具轻松拿捏mac
还在为 mac 电脑里的垃圾文件、无用缓存和隐私痕迹而烦恼?想找一个软件直接全面清理优化电脑?维护苹果设备的清洁和高效运行是非常重要的,特别是在设备经过长时间使用后。有效的苹果清理软件不仅可以帮助您节省时间,还能延长设备的…...
拔掉独显提升性能,AMD新一代核显可以通杀主流游戏了
在今年台北电脑展上,AMD 除了带来了全新的 Ryzen 9000 系列。 与此同时也带来了全新的移动端处理器 Ryzen AI 9 HX 300 系列。 来源:AMD 也许是在 AI 领域稍晚一步,AMD 的全新移动端处理器命名直接把 AI 焊在脸上。 也就是咱们今天的主角 R…...
关于单片机那些事?
周期 时钟周期:也叫振荡周期,就是单片机外接晶振的倒数,如12Mhz,周期就是1/12us,最小的时间单位。频率越高,速度越快 指令周期:执行一条指令需要的时间,一般由若干个机器周期组成 …...
第5章 传输层
王道学习 考纲内容 (一)传输层提供的服务 传输层的功能:传输层寻址与端口;无连接服务和面向连接服务 (二)UDP UDP数据报;UDP检验 (三)TCP …...
典型传感器简介及驱动安装
双目视觉传感器 Indemind 传感器简介 INDEMIND M1 是专为开发者提供的一款硬件,采用“双目摄像头IMU”多传感器融合架构与 微秒级时间同步机制,为视觉 SLAM 研究提供精准稳定数据源,以满足 SLAM 研究、导航及 避障开发、视觉动作捕捉开发、…...
linux和Win——显卡驱动、Anaconda及pytorch安装(无需单独安装cuda、cudnn)
今天给新电脑的双系统(windows11和ubuntu22.04)安装了深度学习环境,在此记录一下。 一、Linux系统 (一)安装显卡驱动 (1)在安装Nvidia显卡驱动前,一定要点一下下面的“软件更新器…...
机器学习之多模态学习FLAVA(Foundational Language and Vision Alignment)
FLAVA(Foundational Language and Vision Alignment)是Meta AI提出的一种多模态学习模型,旨在处理自然语言和视觉任务。FLAVA通过联合学习文本和图像的特征表示,实现了在多模态任务上的优异性能。 FLAVA的基本概念 多模态学习: 多模态学习涉及同时处理多种类型的数据,例…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
