(仓颉) 仓颉语言入门

2024-09-07 16:44
文章标签 语言 入门 仓颉

本文主要是介绍(仓颉) 仓颉语言入门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • ⭐前言
  • 🔠1 基本概念
    • 🔤Hello World
    • 🔤标识符
    • 🔤内置类型
    • 🔤if表达式
    • 🔤for表达式
    • 🔤while表达式
    • 🔤demo 手动计算Π
  • 🔠2 函数
    • 🔤普通函数
    • 🔤lambda
    • 🔤demo 递归遍历目录
  • 🔠3 枚举
    • 🔤enum
    • 🔤match表达式
    • 🔤option 解析数字
    • 🔤demo 计算表达式
  • 🔠4 struct
    • 🔤值类型
    • 🔤二叉树
  • 🔠5 calss
    • 🔤引用类型
    • 🔤继承
    • 🔤prop 属性
  • 🔠6 接口与扩展
    • 🔤interface
    • 🔤extend
    • 🔤泛型
  • 🔠7 异常处理
    • 🔤try catch finally
  • 🔠8 并发编程
    • 🔤Future
  • 🔠9 跨语言互操作
  • 🔠10 宏
    • 🔤macro
  • ⭐END
    • 🌟交流方式

⭐前言

仓颉-鸿蒙原生应用编程语言-华为开发者联盟 (huawei.com)

初识仓颉语言-仓颉编程语言开发指南-学习仓颉语言 - 华为HarmonyOS开发者 (huawei.com)

【原创】仓颉编程语言入门教程

楼主作为主语言C++,副语言python。仅做基础的入门了解。

本文不做任何格外的语法说明,仅在代码中用简短的注释辅助。

下文均为教学视频中的实例demo(上方的视频也出现在官网的视频一栏中)。

本文所有代码均在下方的在线编译器中进行尝试。

除了最后两章,9,10无法进行单文件操作其余均有验证。

仓颉 Playground (zxilly.dev)

https://github.com/Zxilly/playground-cj

仓颉版本 0.54.3

package cangjie// 编写你的第一个仓颉程序
main(): Int64 {println("你好,仓颉!")return 0
}

🔠1 基本概念

🔤Hello World

// main 可以没有返回值
main() {println("你好,仓颉!")
}

🔤标识符

main() {// 普通变量let num = 10let ___x = "___Str"println(num)println(___x)// 原始表示符// 用于将关键字作为标识符let `for` = "这是一个将for关键字用作原始标识符"println(`for`)
}

🔤内置类型

main() {/*** 字面量后缀* 整形* Int8  -> i8* Uint8 -> u8* 浮点型* Float16 -> f16*/let a: Int64 = 2024let b = 67u8let c: Float64 = 6.21let d: Bool = true || falseprintln(d)// 字符类型,表示一个 unicode 字符// 运行下来双引号也可以运行let e: Rune = '仓'let f: Rune = '\u{9889}'println("${e} ${f}")// 单行字符串let g: String = "Cang" + "jie"let h: String = """第1行,这是多行字符串第2行
"""// 插值字符串// 要求表达式类型实现了 ToString 接口let i: String = "Cangjie${a}"println("${h}${i}")// 引用类型数组let j: Array<UInt8> = [1u8, 2u8]// 值类型数组// 没有 ToString// let k: VArray<Rune, $2> = ['C', 'J']let k: VArray<Rune, $2> = [e, f]println("引用类型数组${j}")// 元组类型let l: (Int64, Float64) = (2024, 9.6)// expected 'Struct-String', found 'Tuple<Int64, Float64>'// println(l)// 区间类型// 主要用于for in表达式中let m: Range<Int64> = 2019..2024// expected 'Struct-String', found 'Struct-Range<Int64>'// println(m)
}

🔤if表达式

import std.random.*main() {let speed = Random().nextFloat64() + 20.0println("${speed} km/s")// if 表达式// 类似于 gcc 中的大括号表达式let level = if (speed > 16.7) {"第3宇宙速度"} else if (speed > 11.2) {"第2宇宙速度"} else if (speed > 7.9) {"第1宇宙速度"} else {"第0宇宙速度"}println(level)
}

🔤for表达式

main() {// 1. forvar sum = 0// range(1, 100, 2)for (i in 1..99 : 2) {sum += i}println(sum)// 2. forlet arr = [(1, 2), (3, 4)]// 元组可以解构for ((x, y) in arr) {println("x=${x} y=${y}")}// 3. forvar num = 2// 用 _ 作为占用,避免编译器警告for (_ in 0..5) {num *= num}// 4. for// 当 where 为 true 才执行循环体for (i in 0..10 where i % 2 == 1) {println(i)}
}

🔤while表达式

main() {var result = 0.0var lower = 1.0var upper = 2.0while (upper - lower > 1.0E-10) {result = (lower + upper) / 2.0if (result ** 2 - 2.0 > 0.0) {upper = result} else {lower = result}}println("√2 ≈ ${result}")
}

🔤demo 手动计算Π

// 在在线仓颉Playground 中运行失败
// from std import random.*
// from std import math.*
import std.random.*
import std.math.*main() {/*** 手动计算圆周率* 在一个正方形中随机投点*/const N = 10000var n: UInt32 = 0let random = Random()for (_ in 0..N) {let x = random.nextFloat64()let y = random.nextFloat64()if ((x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25) {n++}}let pi = Float64(n) / Float64(N) * 4.0println("Π = ${pi}")println("deviation: ${abs(Float64.PI - pi)}")
}

🔠2 函数

🔤普通函数

func void() {// pass
}// 将函数作为参数
func node(value: Int32, left!: () -> Unit = void, right!: () -> Unit = void) {// 二叉树的中序遍历func show() {left()print(value)right()}return show
}main() {let tree = node(0,left: node(1, left: node(2, right: node(3))),right: node(4, left: node(5), right: node(6)))tree()
}

🔤lambda

func iter(n: Int64, x0: Float64, f: (Float64) -> Float64) {var x = x0for (_ in 0..n) {print("${x}, ")x = f(x)}println("${x}")
}main() {// lambda 表达式// { 参数列表 => 函数体 }// { params => block }// 周期3iter(5, 0.8, {x: Float64 => 1.0 / (1.0 - x)})// 没有周期,产生未随机数iter(10, 0.8, {x: Float64 => 4.0 * x * (1.0 - x)})
}

🔤demo 递归遍历目录

import std.fs.*func forEachFileDo(root: Path, handler: (Path) -> Unit): Unit {let current = Directory(root)for (file in current.files()) {handler(file.path)}for (directory in current.directories()) {forEachFileDo(directory.path, handler)}
}main() {forEachFileDo(Path("."), {path: Path => println(path)})
}

🔠3 枚举

🔤enum

enum Tree {// 枚举项Empty | Leaf(Int64) | Node(Int64, Tree, Tree)// 成员函数public func traverse(): Unit {match (this) {case Empty => ()case Leaf(value) => print(value)case Node(value, left, right) =>left.traverse()print(value)right.traverse()}}public static func generate(depth: UInt8): Tree {if (depth == 1) {return Leaf(1)}return Node(Int64(depth),generate(depth - 1),generate(depth - 1))}
}main() {let tree = Node(1,Node(2, Node(3, Empty, Leaf(4)), Empty),Node(5, Leaf(6), Leaf(7)))tree.traverse()println()let fullTree = Tree.generate(5)fullTree.traverse()
}

🔤match表达式

func fib(n: Int64): Int64 {// math 表达式match (n) {case 0 | 1 => ncase other where other > 0 => fib(other - 1) + fib(other - 2)case _ => 0}
}main() {println(fib(-1))for (i in 1..=10) {print("${fib(i)} ")}
}

🔤option 解析数字

func parseInt(text: String): Option<Int64> {if (text.isEmpty() || text == ".") {return None}var sign = if (text[0] == 45u8) {1} else {0}var sum = 0for (i in sign..text.size) {if (text[i] > 57u8 || text[i] < 48u8) {return None}let digit = Int64(text[i] - 48u8)sum = 10 * sum + digit}// 自动包装为 optionreturn if (sign == 1) {-sum} else {sum}
}main() {let number = parseInt("-123456")// getOrThrow 从 Option 取值println(number.getOrThrow())let result = parseInt("123-456")if (result.isNone()) {println("parse failed")}
}

🔤demo 计算表达式

enum Expr {Num(Float64)| Add(Expr, Expr)| Sub(Expr, Expr)| Mul(Expr, Expr)| Div(Expr, Expr)public func calc(): Float64 {match (this) {case Num(number) => numbercase Add(a, b) => a.calc() + b.calc()case Sub(a, b) => a.calc() - b.calc()case Mul(a, b) => a.calc() * b.calc()case Div(a, b) => a.calc() / b.calc()}}public operator func +(that: Expr): Expr {return Add(this, that)}public operator func -(that: Expr): Expr {return Sub(this, that)}public operator func *(that: Expr): Expr {return Mul(this, that)}public operator func /(that: Expr): Expr {return Div(this, that)}
}main() {let x = Num(1.2) + Num(3.4) + Num(2.0) - Num(1.0) / Num(2.0)println(x.calc())
}

🔠4 struct

🔤值类型

struct Point {static let name = "Point"// 主构造函数// 自动成为成员变量Point(private var x: Float64, private var y: Float64) {println("Create a point: (${x}, ${y})")}public func copy() {return this}// 用 mut 修饰可以使用 this 引用当前实例public mut func set(x: Float64, y: Float64) {this.x = xthis.y = y}public func show() {println("Visit the point: (${x}, ${y})")}
}main() {println(Point.name)let p1 = Point(3.0, 4.0)var p2 = p1.copy()p2.set(1.0, 2.0)p1.show()p2.show()
}

🔤二叉树

struct Node {public Node(var value: Int32, let left!: ?Node = None, let right!: ?Node = None) {}public func traverse(): Unit {// Option 类型的语法糖left?.traverse()print(value)right?.traverse()}static let name: String// 静态构造函数static init() {name = "Binary Tree"}public static func intro() {println(name)}
}main() {Node.intro()let root = Node(1,left: Node(2, left: Node(3, right: Node(4))),right: Node(5, left: Node(6), right: Node(7)))root.traverse()
}

🔠5 calss

🔤引用类型

class Point {static let name = "Point"public Point(private var x: Float64, private var y: Float64) {println("Create a point: {${x}, ${y}}")}// this 是当前的引用public func ref() {return this}public func set(x: Float64, y: Float64) {this.x = xthis.y = y}public func show() {println("Visit the point: (${x}, ${y})")}
}main() {println(Point.name)let p1 = Point(3.0, 4.0)var p2 = p1.ref()p2.set(1.0, 2.0)p1.show()p2.show()
}

🔤继承

// 使用了 open 关键字的才能被继承
open class NodeA {public NodeA(protected var value: String,protected let left!: ?NodeA = None,protected let right!: ?NodeA = None) {}// 中序遍历public open func traverse(): Unit {left?.traverse()print(value)right?.traverse()}
}class NodeB <: NodeA {public init(value: String,left!: ?NodeA = None,right!: ?NodeA = None) {super(value, left: left, right: right)}// 前序遍历public func traverse(): Unit {print(value)left?.traverse()right?.traverse()}
}main() {let root = NodeA('a',left: NodeA('b', left: NodeA('c', right: NodeA('d'))),right: NodeB('e', left: NodeB('f'), right: NodeB('g')))root.traverse()
}

🔤prop 属性

class Node {private var value: Int64 = 0public Node(private var name: String,private let left!: ?Node = None,private let right!: ?Node = None) {}// 是 class 不是 struct// 属性,mut 中才能定义set// 此处属性名:param// 这里的目的是和成员变量 value 进行关联public mut prop param: Int64 {get() {value}set(number) {value = numberupdate()left?.param = number / 2right?.param = number / 2}}private func update() {println("${name} has been updated to ${value}")}
}main() {var root = Node('a',left: Node('b', left: Node('c', right: Node('d'))),right: Node('e', left: Node('f'), right: Node('g')))println(root.param)root.param = 128
}

🔠6 接口与扩展

🔤interface

import std.math.*interface Slot {func compute(t: Float64): Float64operator func <<(that: Slot): Slot {return this}operator func >>(that: Slot): Slot {that << thisreturn this}
}extend Float64 <: Slot {public func compute(t: Float64): Float64 {return this}
}class Wave <: Slot {public Wave(let freq: Float64, let phi: Float64) {}public func compute(t: Float64): Float64 {return sin(2.0 * Float64.PI * freq * t + phi)}
}class Mut <: Slot {public Mut(let a: Slot, let b: Slot) {}public func compute(t: Float64): Float64 {a.compute(t) * b.compute(t)}
}class Integrator <: Slot {var input: ?Slot = Nonevar sum = 0.0public Integrator(let dt: Float64) {}public func compute(t: Float64): Float64 {sum += dt * input.getOrThrow().compute(t)return sum}public operator func <<(that: Slot): Slot {input = Some(that)this}
}main() {const DT = 0.001let left = 1.0 >> Integrator(DT)let right = Wave(0.5 / Float64.PI, 0.0)let flow = Mut(left, right) >> Integrator(DT)for (t in 0..1000) {println(flow.compute(Float64(t) * DT))}
}

🔤extend

// 默认情况下,扩展仅在当前包中有效
extend String {operator func >>(n: Int64): String {if (n <= 0) {return this.clone()}let size = this.sizelet offset = size - n % sizethis[offset..size] + this[0..offset]}
}main() {let text = "Cangjie2024"println(text >> 2 >> 2)
}

🔤泛型

class Node<T> where T <: ToString {public Node(protected var value: T,protected let left!: ?Node<T> = None,protected let right!: ?Node<T> = None) {}// 中序遍历public func traverse(): Unit {left?.traverse()print(value)right?.traverse()}
}main() {let tree1 = Node('a',left: Node('b', left: Node('c', right: Node('d'))),right: Node('e', left: Node('f'), right: Node('g')))tree1.traverse()println()let tree2 = Node(1,left: Node(2, left: Node(3, right: Node(4))),right: Node(5, left: Node(6), right: Node(7)))tree2.traverse()
}

🔠7 异常处理

🔤try catch finally

class ParseException <: Exception {public init() {super("Parse Failed")}
}func parseInt(text: String): Int64 {if (text.isEmpty() || text == ".") {throw ParseException()}var sign = if (text[0] == 45u8) {1} else {0}var sum = 0for (i in sign..text.size) {if (text[i] > 57u8 || text[i] < 48u8) {throw ParseException()}let digit = Int64(text[i] - 48u8)sum = 10 * sum + digit}// 自动包装为 optionreturn if (sign == 1) {-sum} else {sum}
}main() {println(parseInt("-123456"))let number = try {parseInt("123-456")} catch (e: ParseException) {println("not an integer")0}println(number)try {parseInt("123x456")println(parseInt("-123456"))} catch (e: ParseException) {println(e.message)} finally {println("clean up")}// parseInt("x123456")println("end")
}

🔠8 并发编程

🔤Future

import std.collection.*
import std.random.*
import std.math.*const M = 200000
const N = 16func task(): Int64 {var n: Int64 = 0let random = Random()for (_ in 0..M) {let x = random.nextFloat64()let y = random.nextFloat64()if ((x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25) {n++}}return n
}main() {let futures = ArrayList<Future<Int64>>()for (_ in 0..N) {let future = spawn {task()}futures.append(future)}var n = 0for (future in futures) {n += future.get()}let pi = Float64(n) / Float64(M * N) * 4.0println("Π = ${pi}")println("deviation: ${abs(Float64.PI - pi)}")
}

🔠9 跨语言互操作

🔠10 宏

🔤macro

// macro.cj
// 宏需要定义在宏包
macro package meta
import std.ast.*public macro transform(tokens: Tokens): Tokens {for (token in tokens) {println("${token.value}\t\t${token.kind}")}println("--------------")return tokens
}// main.cj
import meta.*@transform
func add(x: Int64, y: Int64) {return x + y
}main() {@transform(add(1, 2))
}



⭐END

🌟交流方式

⭐交流方式⭐ |C/C++|算法|设计模式|软件架构-CSDN社区

关注我,学习更多C/C++,python,算法,软件工程,计算机知识

B站:

👨‍💻主页:天赐细莲 bilibili

这篇关于(仓颉) 仓颉语言入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1145589

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

MySQL-CRUD入门1

文章目录 认识配置文件client节点mysql节点mysqld节点 数据的添加(Create)添加一行数据添加多行数据两种添加数据的效率对比 数据的查询(Retrieve)全列查询指定列查询查询中带有表达式关于字面量关于as重命名 临时表引入distinct去重order by 排序关于NULL 认识配置文件 在我们的MySQL服务安装好了之后, 会有一个配置文件, 也就

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX