华为仓颉编程语言观感

06-27 1768阅读

这里写自定义目录标题

  • 相似点(主要与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: Int
              let y: Int
              init(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
          
          Swift:
          struct Point {
              let x: Int
              let y: Int
              init(x: Int, y: Int) {
                  self.x = x
                  self.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 }
          extend Int16 }
          extend Int32 }
          extend Int64 }
          let a: Integer = 123 // ok
          }
          extension Int8 : Integer {}
          let a :Integer = Int8(123)
          
              | 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
              }
          }
          
              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
              }
          }
          
              for (e in arr){
                  if (element == e){
                      return true
                  }
              }
              return false
          }
          
              for e in arr {
                  if (element == e){
                      return true
                  }
              }
              return false
          }
          
              
          }
          dateOf(year: 2024, month: 6, dayOfMonth: 21) // ok
          dateOf(year: 2024, month: 6, dayOfMonth: 21, timeZone: TimeZone.UTC) // ok
          
              
          }
          dateOf(year: 2024, month: 6, dayOfMonth: 21) // ok
          dateOf(year: 2024, month: 6, dayOfMonth: 21, timeZone: TimeZone.gmt) // ok
          
          /lili p尾随lambda(trailing lambda)/p pre class="brush:python;toolbar:false"仓颉: 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")
          }
          
        5. 属性

          属性的get/set配置。

          仓颉:
          x和y是只读的,只有get实现,而color则是可变的,用mut prop修饰,同时具有get和set实现。
          class Point {
              private let _x: Int
              private let _y: Int
              private var _color: String
              init(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: Int
              private let _y: Int
              private var _color: String
              init(_ x: Int, _ y: Int,_ color: String) {
                  self._x = x
                  self._y = y
                  self._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 //error
              let x = p.x // "access x"
              let y = p.y // "access y"
              p.color = "green" // "reset color to green"
          
        6. 空引用安全

          在仓颉中,对于任意类型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
          
        7. 值类型

          仓颉和Swift都使用struct来实现用户自定义的值类型。

          仓颉:
          struct Point {
              var x: Int
              var y: Int
              init(x: Int, y: Int) { ... }
              ...
          }
          var a = Point(0, 0)
          var b = a
          a.x = 1
          print(b.x) // 0
          
          Swift:
          struct Point {
              var x: Int
              var y: Int
              init(x: Int, y: Int) { 
                  self.x  = x
                  self.y = y
              }
              
          }
          var a1 = Point3(x:0,y: 0)
          var b1 = a1
          a1.x = 1
          print(b1.x) // 0
          
        8. 仓颉:
          定义一个名为 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 {
          }
          
        9. Actor

          使用更简洁的语法来实现异步编程、并发编程中的数据竞争问题。

          仓颉:
          actor Account {
              instance var balance: Int64
              init (x: Int64) { this.balance = f1() }
              instance func performWithdraw(amount: Int64): Unit {
                  balance -= amount
              }
              receiver func withdraw(amount: Int64): Bool {
                  if (this.balance  
          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
          	}
          }
          
        10. 可变性修饰符

          可变性修饰符:let 与 var,分别对应不可变和可变属性,

          不同点

          • 垃圾收集方案

            仓颉使用追踪式垃圾回收,类似于java中的基于可达性分析的垃圾回收算法;Swift使用引用计数法。(Swift有weak关键字)

            亮点

            • 管道(Pipeline)操作符

              func double(a: Int) {
                  a * 2
              }
              func increment(a: Int) {
                  a + 1
              }
              double(increment(double(double(5)))) // 42
              5 |> 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 3
                  let 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()
                    for (url in urls) {
                        let fut = spawn { fetch_data(url) }  // 创建仓颉线程进行网络请求
                        futures.append(fut)
                    }
                    for (fut in futures) {  // 等待所有仓颉线程完成
                        fut.get()
                    }
                }
                
              2. 无锁并发对象。

                运行时库提供了一系列的原子操作对象,尽量让开发者少使用互斥量或者锁来实现线程安全。同时提供的这些原子操作对象,针对多线程操作做了优化,其效率比单纯使用互斥量要高得多。

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]