华为仓颉编程语言观感

server/2024/10/18 14:06:59/

这里写自定义目录标题

  • 相似点(主要与Swift进行对比)
  • 不同点
  • 亮点

花了半天时间,对华为新出的仓颉编程语言做了简单的了解,整体观感如下:

  • 仓颉语言看起来是一门大而全的语言,吸纳了现存的很多中编程语言的范式和语法。
  • 语法非常像Swift,有些语法又有rust的影子;
  • 静态类型语言,但编译为二进制可执行文件,无虚拟机。并发、垃圾回收与内存管理模块与java类似;
  • 支持声明式UI语法,类似于现在ArkUI使用的ArkTS语法,估计以后HarmonyOS的开发语言会从ArkTS转化为仓颉

目前仓颉语言只开放了文档,未开放sdk让开发者测试开发。可以申请仓颉的开发者预览版Beta招募,链接Here

相似点(主要与Swift进行对比)

  • 类型扩展

    1. 添加函数 (swift包含)

      仓颉:
      extend String { func printSize() {print(this.size)}
      }"123".printSize() // 3
      Swift:
      extension String {func printSize() {print(self.size)}
      }"123".printSize() // 3
      
    2. 添加属性 (swift不包含)

    3. 添加操作符重载 (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 + b
      
      Swiftstruct 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
    4. 实现接口 (swift包含)

      仓颉:
      sealed interface Integer {}extend Int8 <: Integer {}
      extend Int16 <: Integer {}
      extend Int32 <: Integer {}
      extend Int64 <: Integer {}let a: Integer = 123 // ok
      
      Swift:
      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) // ok
    Swift:
    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修饰,同时具有getset实现。
    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则是可变的,同时具有getset实现。
    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 // 321
    
    Swift:
    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) // 0
    
    Swift:
    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
    }
    
  • 并发编程

    1. 线程创建简单且占用内存量小。使用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()}
      }
      
    2. 无锁并发对象。
      运行时库提供了一系列的原子操作对象,尽量让开发者少使用互斥量或者锁来实现线程安全。同时提供的这些原子操作对象,针对多线程操作做了优化,其效率比单纯使用互斥量要高得多。


http://www.ppmy.cn/server/53199.html

相关文章

《Unity3D高级编程之进阶主程》第一章 C#要点技术(六) 搜索算法

搜索算法 广度优先搜索和深度优先搜索是最常见的搜索算法&#xff0c;如果不进行些枝剪的话效率是比较差的&#xff0c;直接使用不加修饰的广度和深度算法&#xff0c;会消耗比较多的CPU以至于整体效率比较差。 好的搜索算法&#xff0c;大部分需要有数据结构的支撑&#xff0c…

鸿蒙期末项目(4)

day4 页面的设计与编写基本完成&#xff0c;接下来使用我们之前搭建好的服务器与相关的网络接口将鸿蒙中的逻辑真正实现一下。 在实现购物车页面展示功能时&#xff0c;使用了如下代码&#xff1a; getCartList(uid: number): Promise<CartItem[]> {return new Promise…

LeetCode //Bash - 192. Word Frequency

192. Word Frequency Write a bash script to calculate the frequency of each word in a text file words.txt. For simplicity sake, you may assume: words.txt contains only lowercase characters and space ’ ’ characters.Each word must consist of lowercase ch…

大数据面试题之Zookeeper面试题

目录 1、介绍下Zookeeper是什么? 2、Zookeeper有什么作用?优缺点?有什么应用场景? 3、Zookeeper的选举策略&#xff0c;leader和follower的区别? 4、介绍下Zookeeper选举算法 5、Zookeeper的节点类型有哪些?分别作用是什么? 6、Zookeeper的节点数怎么设置比较好? …

全国公共汽车、出租车拥有情况及客运量、货运量数据

基本信息. 数据名称: 全国公共汽车、出租车拥有情况及客运量、货运量数据 数据格式: Shp、Excel 数据时间: 2020-2022年 数据几何类型: 面 数据坐标系: WGS84 数据来源&#xff1a;中国城市统计年鉴 数据可视化. 2022年全年公共汽车客运总量数据示意图 2022年公路客…

Spark SQL 的总体工作流程

Spark SQL 是 Apache Spark 的一个模块,它提供了处理结构化和半结构化数据的能力。通过 Spark SQL,用户可以使用 SQL 语言或 DataFrame API 来执行数据查询和分析。这个模块允许开发者将 SQL 查询与 Spark 的数据处理能力结合起来,实现高效、优化的数据处理。下面是 Spark S…

udp协议 服务器

1 TCP和UDP基本概念 TCP:(Transmission Control Protocol)是一种面向连接、可靠的基于字节流的传输层通信协议。并且提供了全双工通信&#xff0c;允许两个应用之间建立可靠的链接以进行数据交换 udp:(User Datagram Protocol):是一种无链接、不可靠、基于数据报文传输层协议&…

Linux 常用命令

文章目录 Linux 常用命令开机、重启和用户登录注销用户管理帮助指令文件目录类时间日期类搜索查找类压缩和解压类组管理与文件管理网络管理进程管理服务管理防火墙管理定时任务 Linux 常用命令 开机、重启和用户登录注销 shutdown –h now&#xff1a;立即进行关机。shutdown…